/src/serenity/Userland/Libraries/LibSQL/AST/Update.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2022, Tim Flynn <trflynn89@serenityos.org> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #include <LibSQL/AST/AST.h> |
8 | | #include <LibSQL/Database.h> |
9 | | #include <LibSQL/Meta.h> |
10 | | #include <LibSQL/Row.h> |
11 | | |
12 | | namespace SQL::AST { |
13 | | |
14 | | ResultOr<ResultSet> Update::execute(ExecutionContext& context) const |
15 | 0 | { |
16 | 0 | auto const& schema_name = m_qualified_table_name->schema_name(); |
17 | 0 | auto const& table_name = m_qualified_table_name->table_name(); |
18 | 0 | auto table_def = TRY(context.database->get_table(schema_name, table_name)); |
19 | | |
20 | 0 | Vector<Row> matched_rows; |
21 | |
|
22 | 0 | for (auto& table_row : TRY(context.database->select_all(*table_def))) { |
23 | 0 | context.current_row = &table_row; |
24 | |
|
25 | 0 | if (auto const& where_clause = this->where_clause()) { |
26 | 0 | auto where_result = TRY(where_clause->evaluate(context)).to_bool(); |
27 | 0 | if (!where_result.has_value() || !where_result.value()) |
28 | 0 | continue; |
29 | 0 | } |
30 | | |
31 | 0 | TRY(matched_rows.try_append(move(table_row))); |
32 | 0 | } |
33 | | |
34 | 0 | ResultSet result { SQLCommand::Update }; |
35 | |
|
36 | 0 | for (auto& update_column : m_update_columns) { |
37 | 0 | auto row_value = TRY(update_column.expression->evaluate(context)); |
38 | | |
39 | 0 | for (auto& table_row : matched_rows) { |
40 | 0 | auto& row_descriptor = *table_row.descriptor(); |
41 | |
|
42 | 0 | for (auto const& column_name : update_column.column_names) { |
43 | 0 | if (!table_row.has(column_name)) |
44 | 0 | return Result { SQLCommand::Update, SQLErrorCode::ColumnDoesNotExist, column_name }; |
45 | | |
46 | 0 | auto column_index = row_descriptor.find_if([&](auto element) { return element.name == column_name; }).index(); |
47 | 0 | auto column_type = row_descriptor[column_index].type; |
48 | |
|
49 | 0 | if (!row_value.is_type_compatible_with(column_type)) |
50 | 0 | return Result { SQLCommand::Update, SQLErrorCode::InvalidValueType, column_name }; |
51 | | |
52 | 0 | table_row[column_index] = row_value; |
53 | 0 | } |
54 | | |
55 | 0 | TRY(context.database->update(table_row)); |
56 | 0 | result.insert_row(table_row, {}); |
57 | 0 | } |
58 | 0 | } |
59 | | |
60 | 0 | return result; |
61 | 0 | } |
62 | | |
63 | | } |