Serenity Operating System
at master 1067 lines 42 kB view raw
1/* 2 * Copyright (c) 2021, Jan de Visser <jan@de-visser.net> 3 * Copyright (c) 2021, Mahmoud Mandour <ma.mandourr@gmail.com> 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8#include <unistd.h> 9 10#include <AK/QuickSort.h> 11#include <AK/ScopeGuard.h> 12#include <LibSQL/AST/Parser.h> 13#include <LibSQL/Database.h> 14#include <LibSQL/Result.h> 15#include <LibSQL/ResultSet.h> 16#include <LibSQL/Row.h> 17#include <LibSQL/Value.h> 18#include <LibTest/TestCase.h> 19 20namespace { 21 22constexpr char const* db_name = "/tmp/test.db"; 23 24SQL::ResultOr<SQL::ResultSet> try_execute(NonnullRefPtr<SQL::Database> database, DeprecatedString const& sql, Vector<SQL::Value> placeholder_values = {}) 25{ 26 auto parser = SQL::AST::Parser(SQL::AST::Lexer(sql)); 27 auto statement = parser.next_statement(); 28 EXPECT(!parser.has_errors()); 29 if (parser.has_errors()) 30 outln("{}", parser.errors()[0].to_deprecated_string()); 31 return statement->execute(move(database), placeholder_values); 32} 33 34SQL::ResultSet execute(NonnullRefPtr<SQL::Database> database, DeprecatedString const& sql, Vector<SQL::Value> placeholder_values = {}) 35{ 36 auto result = try_execute(move(database), sql, move(placeholder_values)); 37 if (result.is_error()) { 38 outln("{}", result.release_error().error_string()); 39 VERIFY_NOT_REACHED(); 40 } 41 return result.release_value(); 42} 43 44template<typename... Args> 45Vector<SQL::Value> placeholders(Args&&... args) 46{ 47 return { SQL::Value(forward<Args>(args))... }; 48} 49 50void create_schema(NonnullRefPtr<SQL::Database> database) 51{ 52 auto result = execute(database, "CREATE SCHEMA TestSchema;"); 53 EXPECT_EQ(result.command(), SQL::SQLCommand::Create); 54} 55 56void create_table(NonnullRefPtr<SQL::Database> database) 57{ 58 create_schema(database); 59 auto result = execute(database, "CREATE TABLE TestSchema.TestTable ( TextColumn text, IntColumn integer );"); 60 EXPECT_EQ(result.command(), SQL::SQLCommand::Create); 61} 62 63void create_two_tables(NonnullRefPtr<SQL::Database> database) 64{ 65 create_schema(database); 66 auto result = execute(database, "CREATE TABLE TestSchema.TestTable1 ( TextColumn1 text, IntColumn integer );"); 67 EXPECT_EQ(result.command(), SQL::SQLCommand::Create); 68 result = execute(database, "CREATE TABLE TestSchema.TestTable2 ( TextColumn2 text, IntColumn integer );"); 69 EXPECT_EQ(result.command(), SQL::SQLCommand::Create); 70} 71 72TEST_CASE(create_schema) 73{ 74 ScopeGuard guard([]() { unlink(db_name); }); 75 auto database = SQL::Database::construct(db_name); 76 EXPECT(!database->open().is_error()); 77 create_schema(database); 78 auto schema_or_error = database->get_schema("TESTSCHEMA"); 79 EXPECT(!schema_or_error.is_error()); 80} 81 82TEST_CASE(create_table) 83{ 84 ScopeGuard guard([]() { unlink(db_name); }); 85 auto database = SQL::Database::construct(db_name); 86 EXPECT(!database->open().is_error()); 87 create_table(database); 88 auto table_or_error = database->get_table("TESTSCHEMA", "TESTTABLE"); 89 EXPECT(!table_or_error.is_error()); 90} 91 92TEST_CASE(insert_into_table) 93{ 94 ScopeGuard guard([]() { unlink(db_name); }); 95 auto database = SQL::Database::construct(db_name); 96 EXPECT(!database->open().is_error()); 97 create_table(database); 98 auto result = execute(database, "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test', 42 );"); 99 EXPECT(result.size() == 1); 100 101 auto table = MUST(database->get_table("TESTSCHEMA", "TESTTABLE")); 102 103 int count = 0; 104 auto rows_or_error = database->select_all(*table); 105 EXPECT(!rows_or_error.is_error()); 106 for (auto& row : rows_or_error.value()) { 107 EXPECT_EQ(row["TEXTCOLUMN"].to_deprecated_string(), "Test"); 108 EXPECT_EQ(row["INTCOLUMN"].to_int<i32>(), 42); 109 count++; 110 } 111 EXPECT_EQ(count, 1); 112} 113 114TEST_CASE(insert_into_table_wrong_data_types) 115{ 116 ScopeGuard guard([]() { unlink(db_name); }); 117 auto database = SQL::Database::construct(db_name); 118 EXPECT(!database->open().is_error()); 119 create_table(database); 120 auto result = try_execute(database, "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES (43, 'Test_2');"); 121 EXPECT(result.is_error()); 122 EXPECT(result.release_error().error() == SQL::SQLErrorCode::InvalidValueType); 123} 124 125TEST_CASE(insert_into_table_multiple_tuples_wrong_data_types) 126{ 127 ScopeGuard guard([]() { unlink(db_name); }); 128 auto database = SQL::Database::construct(db_name); 129 EXPECT(!database->open().is_error()); 130 create_table(database); 131 auto result = try_execute(database, "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ('Test_1', 42), (43, 'Test_2');"); 132 EXPECT(result.is_error()); 133 EXPECT(result.release_error().error() == SQL::SQLErrorCode::InvalidValueType); 134} 135 136TEST_CASE(insert_wrong_number_of_values) 137{ 138 ScopeGuard guard([]() { unlink(db_name); }); 139 auto database = SQL::Database::construct(db_name); 140 EXPECT(!database->open().is_error()); 141 create_table(database); 142 auto result = try_execute(database, "INSERT INTO TestSchema.TestTable VALUES ( 42 );"); 143 EXPECT(result.is_error()); 144 EXPECT(result.release_error().error() == SQL::SQLErrorCode::InvalidNumberOfValues); 145} 146 147TEST_CASE(insert_identifier_as_value) 148{ 149 ScopeGuard guard([]() { unlink(db_name); }); 150 auto database = SQL::Database::construct(db_name); 151 EXPECT(!database->open().is_error()); 152 create_table(database); 153 auto result = try_execute(database, "INSERT INTO TestSchema.TestTable VALUES ( identifier, 42 );"); 154 EXPECT(result.is_error()); 155 EXPECT(result.release_error().error() == SQL::SQLErrorCode::SyntaxError); 156} 157 158TEST_CASE(insert_quoted_identifier_as_value) 159{ 160 ScopeGuard guard([]() { unlink(db_name); }); 161 auto database = SQL::Database::construct(db_name); 162 EXPECT(!database->open().is_error()); 163 create_table(database); 164 auto result = try_execute(database, "INSERT INTO TestSchema.TestTable VALUES ( \"QuotedIdentifier\", 42 );"); 165 EXPECT(result.is_error()); 166 EXPECT(result.release_error().error() == SQL::SQLErrorCode::SyntaxError); 167} 168 169TEST_CASE(insert_without_column_names) 170{ 171 ScopeGuard guard([]() { unlink(db_name); }); 172 auto database = SQL::Database::construct(db_name); 173 EXPECT(!database->open().is_error()); 174 create_table(database); 175 auto result = execute(database, "INSERT INTO TestSchema.TestTable VALUES ('Test_1', 42), ('Test_2', 43);"); 176 EXPECT(result.size() == 2); 177 178 auto table = MUST(database->get_table("TESTSCHEMA", "TESTTABLE")); 179 auto rows_or_error = database->select_all(*table); 180 EXPECT(!rows_or_error.is_error()); 181 EXPECT_EQ(rows_or_error.value().size(), 2u); 182} 183 184TEST_CASE(insert_with_placeholders) 185{ 186 ScopeGuard guard([]() { unlink(db_name); }); 187 188 auto database = SQL::Database::construct(db_name); 189 EXPECT(!database->open().is_error()); 190 create_table(database); 191 192 { 193 auto result = try_execute(database, "INSERT INTO TestSchema.TestTable VALUES (?, ?);"); 194 EXPECT(result.is_error()); 195 EXPECT_EQ(result.error().error(), SQL::SQLErrorCode::InvalidNumberOfPlaceholderValues); 196 197 result = try_execute(database, "INSERT INTO TestSchema.TestTable VALUES (?, ?);", placeholders("Test_1"sv)); 198 EXPECT(result.is_error()); 199 EXPECT_EQ(result.error().error(), SQL::SQLErrorCode::InvalidNumberOfPlaceholderValues); 200 201 result = try_execute(database, "INSERT INTO TestSchema.TestTable VALUES (?, ?);", placeholders(42, 42)); 202 EXPECT(result.is_error()); 203 EXPECT_EQ(result.error().error(), SQL::SQLErrorCode::InvalidValueType); 204 205 result = try_execute(database, "INSERT INTO TestSchema.TestTable VALUES (?, ?);", placeholders("Test_1"sv, "Test_2"sv)); 206 EXPECT(result.is_error()); 207 EXPECT_EQ(result.error().error(), SQL::SQLErrorCode::InvalidValueType); 208 } 209 { 210 auto result = execute(database, "INSERT INTO TestSchema.TestTable VALUES (?, ?);", placeholders("Test_1"sv, 42)); 211 EXPECT_EQ(result.size(), 1u); 212 213 result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable ORDER BY TextColumn;"); 214 EXPECT_EQ(result.size(), 1u); 215 216 EXPECT_EQ(result[0].row[0], "Test_1"sv); 217 EXPECT_EQ(result[0].row[1], 42); 218 } 219 { 220 auto result = execute(database, "INSERT INTO TestSchema.TestTable VALUES (?, ?), (?, ?);", placeholders("Test_2"sv, 43, "Test_3"sv, 44)); 221 EXPECT_EQ(result.size(), 2u); 222 223 result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable ORDER BY TextColumn;"); 224 EXPECT_EQ(result.size(), 3u); 225 226 EXPECT_EQ(result[0].row[0], "Test_1"sv); 227 EXPECT_EQ(result[0].row[1], 42); 228 229 EXPECT_EQ(result[1].row[0], "Test_2"sv); 230 EXPECT_EQ(result[1].row[1], 43); 231 232 EXPECT_EQ(result[2].row[0], "Test_3"sv); 233 EXPECT_EQ(result[2].row[1], 44); 234 } 235} 236 237TEST_CASE(select_from_empty_table) 238{ 239 ScopeGuard guard([]() { unlink(db_name); }); 240 auto database = SQL::Database::construct(db_name); 241 EXPECT(!database->open().is_error()); 242 create_table(database); 243 auto result = execute(database, "SELECT * FROM TestSchema.TestTable;"); 244 EXPECT(result.is_empty()); 245} 246 247TEST_CASE(select_from_table) 248{ 249 ScopeGuard guard([]() { unlink(db_name); }); 250 auto database = SQL::Database::construct(db_name); 251 EXPECT(!database->open().is_error()); 252 create_table(database); 253 auto result = execute(database, 254 "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES " 255 "( 'Test_1', 42 ), " 256 "( 'Test_2', 43 ), " 257 "( 'Test_3', 44 ), " 258 "( 'Test_4', 45 ), " 259 "( 'Test_5', 46 );"); 260 EXPECT(result.size() == 5); 261 result = execute(database, "SELECT * FROM TestSchema.TestTable;"); 262 EXPECT_EQ(result.size(), 5u); 263} 264 265TEST_CASE(select_with_column_names) 266{ 267 ScopeGuard guard([]() { unlink(db_name); }); 268 auto database = SQL::Database::construct(db_name); 269 EXPECT(!database->open().is_error()); 270 create_table(database); 271 auto result = execute(database, 272 "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES " 273 "( 'Test_1', 42 ), " 274 "( 'Test_2', 43 ), " 275 "( 'Test_3', 44 ), " 276 "( 'Test_4', 45 ), " 277 "( 'Test_5', 46 );"); 278 EXPECT(result.size() == 5); 279 result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable;"); 280 EXPECT_EQ(result.size(), 5u); 281 EXPECT_EQ(result[0].row.size(), 1u); 282} 283 284TEST_CASE(select_with_nonexisting_column_name) 285{ 286 ScopeGuard guard([]() { unlink(db_name); }); 287 auto database = SQL::Database::construct(db_name); 288 EXPECT(!database->open().is_error()); 289 create_table(database); 290 auto result = execute(database, 291 "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES " 292 "( 'Test_1', 42 ), " 293 "( 'Test_2', 43 ), " 294 "( 'Test_3', 44 ), " 295 "( 'Test_4', 45 ), " 296 "( 'Test_5', 46 );"); 297 EXPECT(result.size() == 5); 298 299 auto insert_result = try_execute(database, "SELECT Bogus FROM TestSchema.TestTable;"); 300 EXPECT(insert_result.is_error()); 301 EXPECT(insert_result.release_error().error() == SQL::SQLErrorCode::ColumnDoesNotExist); 302} 303 304TEST_CASE(select_with_where) 305{ 306 ScopeGuard guard([]() { unlink(db_name); }); 307 auto database = SQL::Database::construct(db_name); 308 EXPECT(!database->open().is_error()); 309 create_table(database); 310 auto result = execute(database, 311 "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES " 312 "( 'Test_1', 42 ), " 313 "( 'Test_2', 43 ), " 314 "( 'Test_3', 44 ), " 315 "( 'Test_4', 45 ), " 316 "( 'Test_5', 46 );"); 317 EXPECT(result.size() == 5); 318 result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable WHERE IntColumn > 44;"); 319 EXPECT_EQ(result.size(), 2u); 320 for (auto& row : result) { 321 EXPECT(row.row[1].to_int<i32>().value() > 44); 322 } 323} 324 325TEST_CASE(select_cross_join) 326{ 327 ScopeGuard guard([]() { unlink(db_name); }); 328 auto database = SQL::Database::construct(db_name); 329 EXPECT(!database->open().is_error()); 330 create_two_tables(database); 331 auto result = execute(database, 332 "INSERT INTO TestSchema.TestTable1 ( TextColumn1, IntColumn ) VALUES " 333 "( 'Test_1', 42 ), " 334 "( 'Test_2', 43 ), " 335 "( 'Test_3', 44 ), " 336 "( 'Test_4', 45 ), " 337 "( 'Test_5', 46 );"); 338 EXPECT(result.size() == 5); 339 result = execute(database, 340 "INSERT INTO TestSchema.TestTable2 ( TextColumn2, IntColumn ) VALUES " 341 "( 'Test_10', 40 ), " 342 "( 'Test_11', 41 ), " 343 "( 'Test_12', 42 ), " 344 "( 'Test_13', 47 ), " 345 "( 'Test_14', 48 );"); 346 EXPECT(result.size() == 5); 347 result = execute(database, "SELECT * FROM TestSchema.TestTable1, TestSchema.TestTable2;"); 348 EXPECT_EQ(result.size(), 25u); 349 for (auto& row : result) { 350 EXPECT(row.row.size() == 4); 351 EXPECT(row.row[1].to_int<i32>().value() >= 42); 352 EXPECT(row.row[1].to_int<i32>().value() <= 46); 353 EXPECT(row.row[3].to_int<i32>().value() >= 40); 354 EXPECT(row.row[3].to_int<i32>().value() <= 48); 355 } 356} 357 358TEST_CASE(select_inner_join) 359{ 360 ScopeGuard guard([]() { unlink(db_name); }); 361 auto database = SQL::Database::construct(db_name); 362 EXPECT(!database->open().is_error()); 363 create_two_tables(database); 364 auto result = execute(database, 365 "INSERT INTO TestSchema.TestTable1 ( TextColumn1, IntColumn ) VALUES " 366 "( 'Test_1', 42 ), " 367 "( 'Test_2', 43 ), " 368 "( 'Test_3', 44 ), " 369 "( 'Test_4', 45 ), " 370 "( 'Test_5', 46 );"); 371 EXPECT(result.size() == 5); 372 result = execute(database, 373 "INSERT INTO TestSchema.TestTable2 ( TextColumn2, IntColumn ) VALUES " 374 "( 'Test_10', 40 ), " 375 "( 'Test_11', 41 ), " 376 "( 'Test_12', 42 ), " 377 "( 'Test_13', 47 ), " 378 "( 'Test_14', 48 );"); 379 EXPECT(result.size() == 5); 380 result = execute(database, 381 "SELECT TestTable1.IntColumn, TextColumn1, TextColumn2 " 382 "FROM TestSchema.TestTable1, TestSchema.TestTable2 " 383 "WHERE TestTable1.IntColumn = TestTable2.IntColumn;"); 384 EXPECT_EQ(result.size(), 1u); 385 EXPECT_EQ(result[0].row.size(), 3u); 386 EXPECT_EQ(result[0].row[0].to_int<i32>(), 42); 387 EXPECT_EQ(result[0].row[1].to_deprecated_string(), "Test_1"); 388 EXPECT_EQ(result[0].row[2].to_deprecated_string(), "Test_12"); 389} 390 391TEST_CASE(select_with_like) 392{ 393 ScopeGuard guard([]() { unlink(db_name); }); 394 auto database = SQL::Database::construct(db_name); 395 EXPECT(!database->open().is_error()); 396 create_table(database); 397 auto result = execute(database, 398 "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES " 399 "( 'Test+1', 42 ), " 400 "( 'Test+2', 43 ), " 401 "( 'Test+3', 44 ), " 402 "( 'Test+4', 45 ), " 403 "( 'Test+5', 46 ), " 404 "( 'Another+Test_6', 47 );"); 405 EXPECT(result.size() == 6); 406 407 // Simple match 408 result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE 'Test+1';"); 409 EXPECT_EQ(result.size(), 1u); 410 411 // Use % to match most rows 412 result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE 'T%';"); 413 EXPECT_EQ(result.size(), 5u); 414 415 // Same as above but invert the match 416 result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn NOT LIKE 'T%';"); 417 EXPECT_EQ(result.size(), 1u); 418 419 // Use _ and % to match all rows 420 result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE '%e_t%';"); 421 EXPECT_EQ(result.size(), 6u); 422 423 // Use escape to match a single row. The escape character happens to be a 424 // Regex metacharacter, let's make sure we don't get confused by that. 425 result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE '%Test^_%' ESCAPE '^';"); 426 EXPECT_EQ(result.size(), 1u); 427 428 // Same as above but escape the escape character happens to be a SQL 429 // metacharacter - we want to make sure it's treated as an escape. 430 result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE '%Test__%' ESCAPE '_';"); 431 EXPECT_EQ(result.size(), 1u); 432 433 // (Unnecessarily) escaping a character that happens to be a Regex 434 // metacharacter should have no effect. 435 result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE 'Test:+_' ESCAPE ':';"); 436 EXPECT_EQ(result.size(), 5u); 437 438 // Make sure we error out if the ESCAPE is empty 439 auto select_result = try_execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE '%' ESCAPE '';"); 440 EXPECT(select_result.is_error()); 441 EXPECT(select_result.release_error().error() == SQL::SQLErrorCode::SyntaxError); 442 443 // Make sure we error out if the ESCAPE has more than a single character 444 select_result = try_execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE '%' ESCAPE 'whf';"); 445 EXPECT(select_result.is_error()); 446 EXPECT(select_result.release_error().error() == SQL::SQLErrorCode::SyntaxError); 447} 448 449TEST_CASE(select_with_order) 450{ 451 ScopeGuard guard([]() { unlink(db_name); }); 452 auto database = SQL::Database::construct(db_name); 453 EXPECT(!database->open().is_error()); 454 create_table(database); 455 auto result = execute(database, 456 "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES " 457 "( 'Test_5', 44 ), " 458 "( 'Test_2', 42 ), " 459 "( 'Test_1', 47 ), " 460 "( 'Test_3', 40 ), " 461 "( 'Test_4', 41 );"); 462 EXPECT(result.size() == 5); 463 464 result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable ORDER BY IntColumn;"); 465 EXPECT_EQ(result.size(), 5u); 466 EXPECT_EQ(result[0].row[1].to_int<i32>(), 40); 467 EXPECT_EQ(result[1].row[1].to_int<i32>(), 41); 468 EXPECT_EQ(result[2].row[1].to_int<i32>(), 42); 469 EXPECT_EQ(result[3].row[1].to_int<i32>(), 44); 470 EXPECT_EQ(result[4].row[1].to_int<i32>(), 47); 471 472 result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable ORDER BY TextColumn;"); 473 EXPECT_EQ(result.size(), 5u); 474 EXPECT_EQ(result[0].row[0].to_deprecated_string(), "Test_1"); 475 EXPECT_EQ(result[1].row[0].to_deprecated_string(), "Test_2"); 476 EXPECT_EQ(result[2].row[0].to_deprecated_string(), "Test_3"); 477 EXPECT_EQ(result[3].row[0].to_deprecated_string(), "Test_4"); 478 EXPECT_EQ(result[4].row[0].to_deprecated_string(), "Test_5"); 479} 480 481TEST_CASE(select_with_regexp) 482{ 483 ScopeGuard guard([]() { unlink(db_name); }); 484 auto database = SQL::Database::construct(db_name); 485 EXPECT(!database->open().is_error()); 486 create_table(database); 487 auto result = execute(database, 488 "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES " 489 "( 'Test+1', 42 ), " 490 "( 'Pröv+2', 43 ), " 491 "( 'Test(3)', 44 ), " 492 "( 'Test[4]', 45 ), " 493 "( 'Test+5', 46 ), " 494 "( 'Another-Test_6', 47 );"); 495 EXPECT(result.size() == 6); 496 497 // Simple match 498 result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn REGEXP 'Test\\+1';"); 499 EXPECT_EQ(result.size(), 1u); 500 501 // Match all 502 result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn REGEXP '.*';"); 503 EXPECT_EQ(result.size(), 6u); 504 505 // Match with wildcards 506 result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn REGEXP '^Test.+';"); 507 EXPECT_EQ(result.size(), 4u); 508 509 // Match with case insensitive basic Latin and case sensitive Swedish ö 510 // FIXME: If LibRegex is changed to support case insensitive matches of Unicode characters 511 // This test should be updated and changed to match 'PRÖV'. 512 result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn REGEXP 'PRöV.*';"); 513 EXPECT_EQ(result.size(), 1u); 514} 515 516TEST_CASE(handle_regexp_errors) 517{ 518 ScopeGuard guard([]() { unlink(db_name); }); 519 auto database = SQL::Database::construct(db_name); 520 EXPECT(!database->open().is_error()); 521 create_table(database); 522 auto result = execute(database, 523 "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES " 524 "( 'Test', 0 );"); 525 EXPECT(result.size() == 1); 526 527 // Malformed regex, unmatched square bracket 528 auto select_result = try_execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn REGEXP 'Test\\+[0-9.*';"); 529 EXPECT(select_result.is_error()); 530} 531 532TEST_CASE(select_with_order_two_columns) 533{ 534 ScopeGuard guard([]() { unlink(db_name); }); 535 auto database = SQL::Database::construct(db_name); 536 EXPECT(!database->open().is_error()); 537 create_table(database); 538 auto result = execute(database, 539 "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES " 540 "( 'Test_5', 44 ), " 541 "( 'Test_2', 42 ), " 542 "( 'Test_1', 47 ), " 543 "( 'Test_2', 40 ), " 544 "( 'Test_4', 41 );"); 545 EXPECT(result.size() == 5); 546 547 result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable ORDER BY TextColumn, IntColumn;"); 548 EXPECT_EQ(result.size(), 5u); 549 EXPECT_EQ(result[0].row[0].to_deprecated_string(), "Test_1"); 550 EXPECT_EQ(result[0].row[1].to_int<i32>(), 47); 551 EXPECT_EQ(result[1].row[0].to_deprecated_string(), "Test_2"); 552 EXPECT_EQ(result[1].row[1].to_int<i32>(), 40); 553 EXPECT_EQ(result[2].row[0].to_deprecated_string(), "Test_2"); 554 EXPECT_EQ(result[2].row[1].to_int<i32>(), 42); 555 EXPECT_EQ(result[3].row[0].to_deprecated_string(), "Test_4"); 556 EXPECT_EQ(result[3].row[1].to_int<i32>(), 41); 557 EXPECT_EQ(result[4].row[0].to_deprecated_string(), "Test_5"); 558 EXPECT_EQ(result[4].row[1].to_int<i32>(), 44); 559} 560 561TEST_CASE(select_with_order_by_column_not_in_result) 562{ 563 ScopeGuard guard([]() { unlink(db_name); }); 564 auto database = SQL::Database::construct(db_name); 565 EXPECT(!database->open().is_error()); 566 create_table(database); 567 auto result = execute(database, 568 "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES " 569 "( 'Test_5', 44 ), " 570 "( 'Test_2', 42 ), " 571 "( 'Test_1', 47 ), " 572 "( 'Test_3', 40 ), " 573 "( 'Test_4', 41 );"); 574 EXPECT(result.size() == 5); 575 576 result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable ORDER BY IntColumn;"); 577 EXPECT_EQ(result.size(), 5u); 578 EXPECT_EQ(result[0].row[0].to_deprecated_string(), "Test_3"); 579 EXPECT_EQ(result[1].row[0].to_deprecated_string(), "Test_4"); 580 EXPECT_EQ(result[2].row[0].to_deprecated_string(), "Test_2"); 581 EXPECT_EQ(result[3].row[0].to_deprecated_string(), "Test_5"); 582 EXPECT_EQ(result[4].row[0].to_deprecated_string(), "Test_1"); 583} 584 585TEST_CASE(select_with_limit) 586{ 587 ScopeGuard guard([]() { unlink(db_name); }); 588 auto database = SQL::Database::construct(db_name); 589 EXPECT(!database->open().is_error()); 590 create_table(database); 591 for (auto count = 0; count < 100; count++) { 592 auto result = execute(database, 593 DeprecatedString::formatted("INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test_{}', {} );", count, count)); 594 EXPECT(result.size() == 1); 595 } 596 auto result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable LIMIT 10;"); 597 auto rows = result; 598 EXPECT_EQ(rows.size(), 10u); 599} 600 601TEST_CASE(select_with_limit_and_offset) 602{ 603 ScopeGuard guard([]() { unlink(db_name); }); 604 auto database = SQL::Database::construct(db_name); 605 EXPECT(!database->open().is_error()); 606 create_table(database); 607 for (auto count = 0; count < 100; count++) { 608 auto result = execute(database, 609 DeprecatedString::formatted("INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test_{}', {} );", count, count)); 610 EXPECT(result.size() == 1); 611 } 612 auto result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable LIMIT 10 OFFSET 10;"); 613 EXPECT_EQ(result.size(), 10u); 614} 615 616TEST_CASE(select_with_order_limit_and_offset) 617{ 618 ScopeGuard guard([]() { unlink(db_name); }); 619 auto database = SQL::Database::construct(db_name); 620 EXPECT(!database->open().is_error()); 621 create_table(database); 622 for (auto count = 0; count < 100; count++) { 623 auto result = execute(database, 624 DeprecatedString::formatted("INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test_{}', {} );", count, count)); 625 EXPECT(result.size() == 1); 626 } 627 auto result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable ORDER BY IntColumn LIMIT 10 OFFSET 10;"); 628 EXPECT_EQ(result.size(), 10u); 629 EXPECT_EQ(result[0].row[1].to_int<i32>(), 10); 630 EXPECT_EQ(result[1].row[1].to_int<i32>(), 11); 631 EXPECT_EQ(result[2].row[1].to_int<i32>(), 12); 632 EXPECT_EQ(result[3].row[1].to_int<i32>(), 13); 633 EXPECT_EQ(result[4].row[1].to_int<i32>(), 14); 634 EXPECT_EQ(result[5].row[1].to_int<i32>(), 15); 635 EXPECT_EQ(result[6].row[1].to_int<i32>(), 16); 636 EXPECT_EQ(result[7].row[1].to_int<i32>(), 17); 637 EXPECT_EQ(result[8].row[1].to_int<i32>(), 18); 638 EXPECT_EQ(result[9].row[1].to_int<i32>(), 19); 639} 640 641TEST_CASE(select_with_limit_out_of_bounds) 642{ 643 ScopeGuard guard([]() { unlink(db_name); }); 644 auto database = SQL::Database::construct(db_name); 645 EXPECT(!database->open().is_error()); 646 create_table(database); 647 for (auto count = 0; count < 100; count++) { 648 auto result = execute(database, 649 DeprecatedString::formatted("INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test_{}', {} );", count, count)); 650 EXPECT(result.size() == 1); 651 } 652 auto result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable LIMIT 500;"); 653 EXPECT_EQ(result.size(), 100u); 654} 655 656TEST_CASE(select_with_offset_out_of_bounds) 657{ 658 ScopeGuard guard([]() { unlink(db_name); }); 659 auto database = SQL::Database::construct(db_name); 660 EXPECT(!database->open().is_error()); 661 create_table(database); 662 for (auto count = 0; count < 100; count++) { 663 auto result = execute(database, 664 DeprecatedString::formatted("INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test_{}', {} );", count, count)); 665 EXPECT(result.size() == 1); 666 } 667 auto result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable LIMIT 10 OFFSET 200;"); 668 EXPECT_EQ(result.size(), 0u); 669} 670 671TEST_CASE(describe_table) 672{ 673 ScopeGuard guard([]() { unlink(db_name); }); 674 auto database = SQL::Database::construct(db_name); 675 EXPECT(!database->open().is_error()); 676 create_table(database); 677 auto result = execute(database, "DESCRIBE TABLE TestSchema.TestTable;"); 678 EXPECT_EQ(result.size(), 2u); 679 680 EXPECT_EQ(result[0].row[0].to_deprecated_string(), "TEXTCOLUMN"); 681 EXPECT_EQ(result[0].row[1].to_deprecated_string(), "text"); 682 683 EXPECT_EQ(result[1].row[0].to_deprecated_string(), "INTCOLUMN"); 684 EXPECT_EQ(result[1].row[1].to_deprecated_string(), "int"); 685} 686 687TEST_CASE(binary_operator_execution) 688{ 689 ScopeGuard guard([]() { unlink(db_name); }); 690 auto database = SQL::Database::construct(db_name); 691 EXPECT(!database->open().is_error()); 692 create_table(database); 693 694 for (auto count = 0; count < 10; ++count) { 695 auto result = execute(database, DeprecatedString::formatted("INSERT INTO TestSchema.TestTable VALUES ( 'T{}', {} );", count, count)); 696 EXPECT_EQ(result.size(), 1u); 697 } 698 699 auto compare_result = [](SQL::ResultSet const& result, Vector<int> const& expected) { 700 EXPECT_EQ(result.command(), SQL::SQLCommand::Select); 701 EXPECT_EQ(result.size(), expected.size()); 702 703 Vector<int> result_values; 704 result_values.ensure_capacity(result.size()); 705 706 for (size_t i = 0; i < result.size(); ++i) { 707 auto const& result_row = result.at(i).row; 708 EXPECT_EQ(result_row.size(), 1u); 709 710 auto result_column = result_row[0].to_int<i32>(); 711 result_values.append(result_column.value()); 712 } 713 714 quick_sort(result_values); 715 EXPECT_EQ(result_values, expected); 716 }; 717 718 auto result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn + 1) < 5);"); 719 compare_result(result, { 0, 1, 2, 3 }); 720 721 result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn + 1) <= 5);"); 722 compare_result(result, { 0, 1, 2, 3, 4 }); 723 724 result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn - 1) > 4);"); 725 compare_result(result, { 6, 7, 8, 9 }); 726 727 result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn - 1) >= 4);"); 728 compare_result(result, { 5, 6, 7, 8, 9 }); 729 730 result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn * 2) < 10);"); 731 compare_result(result, { 0, 1, 2, 3, 4 }); 732 733 result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn * 2) <= 10);"); 734 compare_result(result, { 0, 1, 2, 3, 4, 5 }); 735 736 result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn / 3) > 2);"); 737 compare_result(result, { 7, 8, 9 }); 738 739 result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn / 3) >= 2);"); 740 compare_result(result, { 6, 7, 8, 9 }); 741 742 result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn % 2) = 0);"); 743 compare_result(result, { 0, 2, 4, 6, 8 }); 744 745 result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn % 2) = 1);"); 746 compare_result(result, { 1, 3, 5, 7, 9 }); 747 748 result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((1 << IntColumn) <= 32);"); 749 compare_result(result, { 0, 1, 2, 3, 4, 5 }); 750 751 result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((1024 >> IntColumn) >= 32);"); 752 compare_result(result, { 0, 1, 2, 3, 4, 5 }); 753 754 result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn | 1) != IntColumn);"); 755 compare_result(result, { 0, 2, 4, 6, 8 }); 756 757 result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn & 1) = 1);"); 758 compare_result(result, { 1, 3, 5, 7, 9 }); 759} 760 761TEST_CASE(binary_operator_failure) 762{ 763 ScopeGuard guard([]() { unlink(db_name); }); 764 auto database = SQL::Database::construct(db_name); 765 EXPECT(!database->open().is_error()); 766 create_table(database); 767 768 for (auto count = 0; count < 10; ++count) { 769 auto result = execute(database, DeprecatedString::formatted("INSERT INTO TestSchema.TestTable VALUES ( 'T{}', {} );", count, count)); 770 EXPECT_EQ(result.size(), 1u); 771 } 772 773 auto expect_failure = [](auto result, auto op) { 774 EXPECT(result.is_error()); 775 776 auto error = result.release_error(); 777 EXPECT_EQ(error.error(), SQL::SQLErrorCode::NumericOperatorTypeMismatch); 778 779 auto message = DeprecatedString::formatted("NumericOperatorTypeMismatch: Cannot apply '{}' operator to non-numeric operands", op); 780 EXPECT_EQ(error.error_string(), message); 781 }; 782 783 auto result = try_execute(database, "SELECT * FROM TestSchema.TestTable WHERE ((IntColumn + TextColumn) < 5);"); 784 expect_failure(move(result), '+'); 785 786 result = try_execute(database, "SELECT * FROM TestSchema.TestTable WHERE ((IntColumn - TextColumn) < 5);"); 787 expect_failure(move(result), '-'); 788 789 result = try_execute(database, "SELECT * FROM TestSchema.TestTable WHERE ((IntColumn * TextColumn) < 5);"); 790 expect_failure(move(result), '*'); 791 792 result = try_execute(database, "SELECT * FROM TestSchema.TestTable WHERE ((IntColumn / TextColumn) < 5);"); 793 expect_failure(move(result), '/'); 794 795 result = try_execute(database, "SELECT * FROM TestSchema.TestTable WHERE ((IntColumn % TextColumn) < 5);"); 796 expect_failure(move(result), '%'); 797 798 result = try_execute(database, "SELECT * FROM TestSchema.TestTable WHERE ((IntColumn << TextColumn) < 5);"); 799 expect_failure(move(result), "<<"sv); 800 801 result = try_execute(database, "SELECT * FROM TestSchema.TestTable WHERE ((IntColumn >> TextColumn) < 5);"); 802 expect_failure(move(result), ">>"sv); 803 804 result = try_execute(database, "SELECT * FROM TestSchema.TestTable WHERE ((IntColumn | TextColumn) < 5);"); 805 expect_failure(move(result), '|'); 806 807 result = try_execute(database, "SELECT * FROM TestSchema.TestTable WHERE ((IntColumn & TextColumn) < 5);"); 808 expect_failure(move(result), '&'); 809} 810 811TEST_CASE(describe_large_table_after_persist) 812{ 813 ScopeGuard guard([]() { unlink(db_name); }); 814 { 815 auto database = SQL::Database::construct(db_name); 816 EXPECT(!database->open().is_error()); 817 818 auto result = execute(database, "CREATE TABLE Cookies ( name TEXT, value TEXT, same_site INTEGER, creation_time INTEGER, last_access_time INTEGER, expiry_time INTEGER, domain TEXT, path TEXT, secure INTEGER, http_only INTEGER, host_only INTEGER, persistent INTEGER );"); 819 EXPECT_EQ(result.command(), SQL::SQLCommand::Create); 820 } 821 { 822 auto database = SQL::Database::construct(db_name); 823 EXPECT(!database->open().is_error()); 824 825 auto result = execute(database, "DESCRIBE TABLE Cookies;"); 826 EXPECT_EQ(result.size(), 12u); 827 } 828} 829 830TEST_CASE(delete_single_row) 831{ 832 ScopeGuard guard([]() { unlink(db_name); }); 833 { 834 auto database = SQL::Database::construct(db_name); 835 EXPECT(!database->open().is_error()); 836 837 create_table(database); 838 for (auto count = 0; count < 10; ++count) { 839 auto result = execute(database, DeprecatedString::formatted("INSERT INTO TestSchema.TestTable VALUES ( 'T{}', {} );", count, count)); 840 EXPECT_EQ(result.size(), 1u); 841 } 842 843 auto result = execute(database, "SELECT * FROM TestSchema.TestTable;"); 844 EXPECT_EQ(result.size(), 10u); 845 } 846 { 847 auto database = SQL::Database::construct(db_name); 848 EXPECT(!database->open().is_error()); 849 850 execute(database, "DELETE FROM TestSchema.TestTable WHERE (IntColumn = 4);"); 851 852 auto result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable ORDER BY IntColumn;"); 853 EXPECT_EQ(result.size(), 9u); 854 855 for (auto i = 0u; i < 4; ++i) 856 EXPECT_EQ(result[i].row[0], i); 857 for (auto i = 5u; i < 9; ++i) 858 EXPECT_EQ(result[i].row[0], i + 1); 859 } 860 { 861 auto database = SQL::Database::construct(db_name); 862 EXPECT(!database->open().is_error()); 863 864 auto result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable ORDER BY IntColumn;"); 865 EXPECT_EQ(result.size(), 9u); 866 867 for (auto i = 0u; i < 4; ++i) 868 EXPECT_EQ(result[i].row[0], i); 869 for (auto i = 5u; i < 9; ++i) 870 EXPECT_EQ(result[i].row[0], i + 1); 871 } 872} 873 874TEST_CASE(delete_multiple_rows) 875{ 876 ScopeGuard guard([]() { unlink(db_name); }); 877 { 878 auto database = SQL::Database::construct(db_name); 879 EXPECT(!database->open().is_error()); 880 881 create_table(database); 882 for (auto count = 0; count < 10; ++count) { 883 auto result = execute(database, DeprecatedString::formatted("INSERT INTO TestSchema.TestTable VALUES ( 'T{}', {} );", count, count)); 884 EXPECT_EQ(result.size(), 1u); 885 } 886 887 auto result = execute(database, "SELECT * FROM TestSchema.TestTable;"); 888 EXPECT_EQ(result.size(), 10u); 889 } 890 { 891 auto database = SQL::Database::construct(db_name); 892 EXPECT(!database->open().is_error()); 893 894 execute(database, "DELETE FROM TestSchema.TestTable WHERE (IntColumn >= 4);"); 895 896 auto result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable ORDER BY IntColumn;"); 897 EXPECT_EQ(result.size(), 4u); 898 899 for (auto i = 0u; i < result.size(); ++i) 900 EXPECT_EQ(result[i].row[0], i); 901 } 902 { 903 auto database = SQL::Database::construct(db_name); 904 EXPECT(!database->open().is_error()); 905 906 auto result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable ORDER BY IntColumn;"); 907 EXPECT_EQ(result.size(), 4u); 908 909 for (auto i = 0u; i < result.size(); ++i) 910 EXPECT_EQ(result[i].row[0], i); 911 } 912} 913 914TEST_CASE(delete_all_rows) 915{ 916 ScopeGuard guard([]() { unlink(db_name); }); 917 { 918 auto database = SQL::Database::construct(db_name); 919 EXPECT(!database->open().is_error()); 920 921 create_table(database); 922 for (auto count = 0; count < 10; ++count) { 923 auto result = execute(database, DeprecatedString::formatted("INSERT INTO TestSchema.TestTable VALUES ( 'T{}', {} );", count, count)); 924 EXPECT_EQ(result.size(), 1u); 925 } 926 927 auto result = execute(database, "SELECT * FROM TestSchema.TestTable;"); 928 EXPECT_EQ(result.size(), 10u); 929 } 930 { 931 auto database = SQL::Database::construct(db_name); 932 EXPECT(!database->open().is_error()); 933 934 execute(database, "DELETE FROM TestSchema.TestTable;"); 935 936 auto result = execute(database, "SELECT * FROM TestSchema.TestTable;"); 937 EXPECT(result.is_empty()); 938 } 939 { 940 auto database = SQL::Database::construct(db_name); 941 EXPECT(!database->open().is_error()); 942 943 auto result = execute(database, "SELECT * FROM TestSchema.TestTable;"); 944 EXPECT(result.is_empty()); 945 } 946} 947 948TEST_CASE(update_single_row) 949{ 950 ScopeGuard guard([]() { unlink(db_name); }); 951 { 952 auto database = SQL::Database::construct(db_name); 953 EXPECT(!database->open().is_error()); 954 955 create_table(database); 956 for (auto count = 0; count < 10; ++count) { 957 auto result = execute(database, DeprecatedString::formatted("INSERT INTO TestSchema.TestTable VALUES ( 'T{}', {} );", count, count)); 958 EXPECT_EQ(result.size(), 1u); 959 } 960 961 execute(database, "UPDATE TestSchema.TestTable SET IntColumn=123456 WHERE (TextColumn = 'T3');"); 962 963 auto result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable ORDER BY IntColumn;"); 964 EXPECT_EQ(result.size(), 10u); 965 966 for (auto i = 0u; i < 10; ++i) { 967 if (i < 3) 968 EXPECT_EQ(result[i].row[0], i); 969 else if (i < 9) 970 EXPECT_EQ(result[i].row[0], i + 1); 971 else 972 EXPECT_EQ(result[i].row[0], 123456); 973 } 974 } 975 { 976 auto database = SQL::Database::construct(db_name); 977 EXPECT(!database->open().is_error()); 978 979 auto result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable ORDER BY IntColumn;"); 980 EXPECT_EQ(result.size(), 10u); 981 982 for (auto i = 0u; i < 10; ++i) { 983 if (i < 3) 984 EXPECT_EQ(result[i].row[0], i); 985 else if (i < 9) 986 EXPECT_EQ(result[i].row[0], i + 1); 987 else 988 EXPECT_EQ(result[i].row[0], 123456); 989 } 990 } 991} 992 993TEST_CASE(update_multiple_rows) 994{ 995 ScopeGuard guard([]() { unlink(db_name); }); 996 { 997 auto database = SQL::Database::construct(db_name); 998 EXPECT(!database->open().is_error()); 999 1000 create_table(database); 1001 for (auto count = 0; count < 10; ++count) { 1002 auto result = execute(database, DeprecatedString::formatted("INSERT INTO TestSchema.TestTable VALUES ( 'T{}', {} );", count, count)); 1003 EXPECT_EQ(result.size(), 1u); 1004 } 1005 1006 execute(database, "UPDATE TestSchema.TestTable SET IntColumn=123456 WHERE (IntColumn > 4);"); 1007 1008 auto result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable ORDER BY IntColumn;"); 1009 EXPECT_EQ(result.size(), 10u); 1010 1011 for (auto i = 0u; i < 10; ++i) { 1012 if (i < 5) 1013 EXPECT_EQ(result[i].row[0], i); 1014 else 1015 EXPECT_EQ(result[i].row[0], 123456); 1016 } 1017 } 1018 { 1019 auto database = SQL::Database::construct(db_name); 1020 EXPECT(!database->open().is_error()); 1021 1022 auto result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable ORDER BY IntColumn;"); 1023 EXPECT_EQ(result.size(), 10u); 1024 1025 for (auto i = 0u; i < 10; ++i) { 1026 if (i < 5) 1027 EXPECT_EQ(result[i].row[0], i); 1028 else 1029 EXPECT_EQ(result[i].row[0], 123456); 1030 } 1031 } 1032} 1033 1034TEST_CASE(update_all_rows) 1035{ 1036 ScopeGuard guard([]() { unlink(db_name); }); 1037 { 1038 auto database = SQL::Database::construct(db_name); 1039 EXPECT(!database->open().is_error()); 1040 1041 create_table(database); 1042 for (auto count = 0; count < 10; ++count) { 1043 auto result = execute(database, DeprecatedString::formatted("INSERT INTO TestSchema.TestTable VALUES ( 'T{}', {} );", count, count)); 1044 EXPECT_EQ(result.size(), 1u); 1045 } 1046 1047 execute(database, "UPDATE TestSchema.TestTable SET IntColumn=123456;"); 1048 1049 auto result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable ORDER BY IntColumn;"); 1050 EXPECT_EQ(result.size(), 10u); 1051 1052 for (auto i = 0u; i < 10; ++i) 1053 EXPECT_EQ(result[i].row[0], 123456); 1054 } 1055 { 1056 auto database = SQL::Database::construct(db_name); 1057 EXPECT(!database->open().is_error()); 1058 1059 auto result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable ORDER BY IntColumn;"); 1060 EXPECT_EQ(result.size(), 10u); 1061 1062 for (auto i = 0u; i < 10; ++i) 1063 EXPECT_EQ(result[i].row[0], 123456); 1064 } 1065} 1066 1067}