TestSqlStatementExecution.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * Copyright (c) 2021, Jan de Visser <jan@de-visser.net>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <unistd.h>
  7. #include <AK/ScopeGuard.h>
  8. #include <LibSQL/AST/Parser.h>
  9. #include <LibSQL/Database.h>
  10. #include <LibSQL/Row.h>
  11. #include <LibSQL/SQLResult.h>
  12. #include <LibSQL/Value.h>
  13. #include <LibTest/TestCase.h>
  14. namespace {
  15. constexpr const char* db_name = "/tmp/test.db";
  16. RefPtr<SQL::SQLResult> execute(NonnullRefPtr<SQL::Database> database, String const& sql)
  17. {
  18. auto parser = SQL::AST::Parser(SQL::AST::Lexer(sql));
  19. auto statement = parser.next_statement();
  20. EXPECT(!parser.has_errors());
  21. if (parser.has_errors())
  22. outln("{}", parser.errors()[0].to_string());
  23. SQL::AST::ExecutionContext context { database };
  24. auto result = statement->execute(context);
  25. if (result->error().code != SQL::SQLErrorCode::NoError)
  26. outln("{}", result->error().to_string());
  27. return result;
  28. }
  29. void create_schema(NonnullRefPtr<SQL::Database> database)
  30. {
  31. auto result = execute(database, "CREATE SCHEMA TestSchema;");
  32. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  33. EXPECT(result->inserted() == 1);
  34. }
  35. void create_table(NonnullRefPtr<SQL::Database> database)
  36. {
  37. create_schema(database);
  38. auto result = execute(database, "CREATE TABLE TestSchema.TestTable ( TextColumn text, IntColumn integer );");
  39. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  40. EXPECT(result->inserted() == 1);
  41. }
  42. TEST_CASE(create_schema)
  43. {
  44. ScopeGuard guard([]() { unlink(db_name); });
  45. auto database = SQL::Database::construct(db_name);
  46. create_schema(database);
  47. auto schema = database->get_schema("TESTSCHEMA");
  48. EXPECT(schema);
  49. }
  50. TEST_CASE(create_table)
  51. {
  52. ScopeGuard guard([]() { unlink(db_name); });
  53. auto database = SQL::Database::construct(db_name);
  54. create_table(database);
  55. auto table = database->get_table("TESTSCHEMA", "TESTTABLE");
  56. EXPECT(table);
  57. }
  58. TEST_CASE(insert_into_table)
  59. {
  60. ScopeGuard guard([]() { unlink(db_name); });
  61. auto database = SQL::Database::construct(db_name);
  62. create_table(database);
  63. auto result = execute(database, "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test', 42 );");
  64. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  65. EXPECT(result->inserted() == 1);
  66. auto table = database->get_table("TESTSCHEMA", "TESTTABLE");
  67. int count = 0;
  68. for (auto& row : database->select_all(*table)) {
  69. EXPECT_EQ(row["TEXTCOLUMN"].to_string(), "Test");
  70. EXPECT_EQ(row["INTCOLUMN"].to_int().value(), 42);
  71. count++;
  72. }
  73. EXPECT_EQ(count, 1);
  74. }
  75. TEST_CASE(insert_into_table_wrong_data_types)
  76. {
  77. ScopeGuard guard([]() { unlink(db_name); });
  78. auto database = SQL::Database::construct(db_name);
  79. create_table(database);
  80. auto result = execute(database, "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES (43, 'Test_2');");
  81. EXPECT(result->inserted() == 0);
  82. EXPECT(result->error().code == SQL::SQLErrorCode::InvalidValueType);
  83. }
  84. TEST_CASE(insert_into_table_multiple_tuples_wrong_data_types)
  85. {
  86. ScopeGuard guard([]() { unlink(db_name); });
  87. auto database = SQL::Database::construct(db_name);
  88. create_table(database);
  89. auto result = execute(database, "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ('Test_1', 42), (43, 'Test_2');");
  90. EXPECT(result->inserted() == 0);
  91. EXPECT(result->error().code == SQL::SQLErrorCode::InvalidValueType);
  92. }
  93. TEST_CASE(insert_wrong_number_of_values)
  94. {
  95. ScopeGuard guard([]() { unlink(db_name); });
  96. auto database = SQL::Database::construct(db_name);
  97. create_table(database);
  98. auto result = execute(database, "INSERT INTO TestSchema.TestTable VALUES ( 42 );");
  99. EXPECT(result->error().code == SQL::SQLErrorCode::InvalidNumberOfValues);
  100. EXPECT(result->inserted() == 0);
  101. }
  102. TEST_CASE(insert_without_column_names)
  103. {
  104. ScopeGuard guard([]() { unlink(db_name); });
  105. auto database = SQL::Database::construct(db_name);
  106. create_table(database);
  107. auto result = execute(database, "INSERT INTO TestSchema.TestTable VALUES ('Test_1', 42), ('Test_2', 43);");
  108. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  109. EXPECT(result->inserted() == 2);
  110. auto table = database->get_table("TESTSCHEMA", "TESTTABLE");
  111. EXPECT_EQ(database->select_all(*table).size(), 2u);
  112. }
  113. TEST_CASE(select_from_table)
  114. {
  115. ScopeGuard guard([]() { unlink(db_name); });
  116. auto database = SQL::Database::construct(db_name);
  117. create_table(database);
  118. auto result = execute(database, "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test_1', 42 ), ( 'Test_2', 43 );");
  119. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  120. EXPECT(result->inserted() == 2);
  121. result = execute(database, "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test_3', 44 ), ( 'Test_4', 45 );");
  122. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  123. EXPECT(result->inserted() == 2);
  124. result = execute(database, "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test_5', 46 );");
  125. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  126. EXPECT(result->inserted() == 1);
  127. result = execute(database, "SELECT * FROM TestSchema.TestTable;");
  128. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  129. EXPECT(result->has_results());
  130. EXPECT_EQ(result->results().size(), 5u);
  131. }
  132. TEST_CASE(select_with_column_names)
  133. {
  134. ScopeGuard guard([]() { unlink(db_name); });
  135. auto database = SQL::Database::construct(db_name);
  136. create_table(database);
  137. auto result = execute(database, "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test_1', 42 ), ( 'Test_2', 43 );");
  138. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  139. EXPECT(result->inserted() == 2);
  140. result = execute(database, "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test_3', 44 ), ( 'Test_4', 45 );");
  141. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  142. EXPECT(result->inserted() == 2);
  143. result = execute(database, "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test_5', 46 );");
  144. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  145. EXPECT(result->inserted() == 1);
  146. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable;");
  147. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  148. EXPECT(result->has_results());
  149. EXPECT_EQ(result->results().size(), 5u);
  150. EXPECT_EQ(result->results()[0].size(), 1u);
  151. }
  152. TEST_CASE(select_with_nonexisting_column_name)
  153. {
  154. ScopeGuard guard([]() { unlink(db_name); });
  155. auto database = SQL::Database::construct(db_name);
  156. create_table(database);
  157. auto result = execute(database,
  158. "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES "
  159. "( 'Test_1', 42 ), "
  160. "( 'Test_2', 43 ), "
  161. "( 'Test_3', 44 ), "
  162. "( 'Test_4', 45 ), "
  163. "( 'Test_5', 46 );");
  164. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  165. EXPECT(result->inserted() == 5);
  166. result = execute(database, "SELECT Bogus FROM TestSchema.TestTable;");
  167. EXPECT(result->error().code == SQL::SQLErrorCode::ColumnDoesNotExist);
  168. }
  169. TEST_CASE(select_with_where)
  170. {
  171. ScopeGuard guard([]() { unlink(db_name); });
  172. auto database = SQL::Database::construct(db_name);
  173. create_table(database);
  174. auto result = execute(database,
  175. "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES "
  176. "( 'Test_1', 42 ), "
  177. "( 'Test_2', 43 ), "
  178. "( 'Test_3', 44 ), "
  179. "( 'Test_4', 45 ), "
  180. "( 'Test_5', 46 );");
  181. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  182. EXPECT(result->inserted() == 5);
  183. result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable WHERE IntColumn > 44;");
  184. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  185. EXPECT(result->has_results());
  186. EXPECT_EQ(result->results().size(), 2u);
  187. for (auto& row : result->results()) {
  188. EXPECT(row[1].to_int().value() > 44);
  189. }
  190. }
  191. }