mirror of
https://github.com/RGBCube/serenity
synced 2025-05-30 21:58:10 +00:00
LibSQL: Partially implement the UPDATE command
This implements enough to update rows filtered by a WHERE clause.
This commit is contained in:
parent
1574f2c3f6
commit
53f8d62ea4
7 changed files with 203 additions and 12 deletions
63
Userland/Libraries/LibSQL/AST/Update.cpp
Normal file
63
Userland/Libraries/LibSQL/AST/Update.cpp
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Tim Flynn <trflynn89@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibSQL/AST/AST.h>
|
||||
#include <LibSQL/Database.h>
|
||||
#include <LibSQL/Meta.h>
|
||||
#include <LibSQL/Row.h>
|
||||
|
||||
namespace SQL::AST {
|
||||
|
||||
ResultOr<ResultSet> Update::execute(ExecutionContext& context) const
|
||||
{
|
||||
auto const& schema_name = m_qualified_table_name->schema_name();
|
||||
auto const& table_name = m_qualified_table_name->table_name();
|
||||
auto table_def = TRY(context.database->get_table(schema_name, table_name));
|
||||
|
||||
Vector<Row> matched_rows;
|
||||
|
||||
for (auto& table_row : TRY(context.database->select_all(*table_def))) {
|
||||
context.current_row = &table_row;
|
||||
|
||||
if (auto const& where_clause = this->where_clause()) {
|
||||
auto where_result = TRY(where_clause->evaluate(context)).to_bool();
|
||||
if (!where_result.has_value() || !where_result.value())
|
||||
continue;
|
||||
}
|
||||
|
||||
TRY(matched_rows.try_append(move(table_row)));
|
||||
}
|
||||
|
||||
ResultSet result { SQLCommand::Update };
|
||||
|
||||
for (auto& update_column : m_update_columns) {
|
||||
auto row_value = TRY(update_column.expression->evaluate(context));
|
||||
|
||||
for (auto& table_row : matched_rows) {
|
||||
auto& row_descriptor = *table_row.descriptor();
|
||||
|
||||
for (auto const& column_name : update_column.column_names) {
|
||||
if (!table_row.has(column_name))
|
||||
return Result { SQLCommand::Update, SQLErrorCode::ColumnDoesNotExist, column_name };
|
||||
|
||||
auto column_index = row_descriptor.find_if([&](auto element) { return element.name == column_name; }).index();
|
||||
auto column_type = row_descriptor[column_index].type;
|
||||
|
||||
if (!row_value.is_type_compatible_with(column_type))
|
||||
return Result { SQLCommand::Update, SQLErrorCode::InvalidValueType, column_name };
|
||||
|
||||
table_row[column_index] = row_value;
|
||||
}
|
||||
|
||||
TRY(context.database->update(table_row));
|
||||
result.insert_row(table_row, {});
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue