diff options
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibSQL/AST/AST.h | 12 | ||||
-rw-r--r-- | Userland/Libraries/LibSQL/Forward.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibSQL/Meta.cpp | 26 | ||||
-rw-r--r-- | Userland/Libraries/LibSQL/Meta.h | 9 | ||||
-rw-r--r-- | Userland/Libraries/LibSQL/SQLResult.h | 141 | ||||
-rw-r--r-- | Userland/Libraries/LibSQL/Tuple.cpp | 13 | ||||
-rw-r--r-- | Userland/Libraries/LibSQL/Tuple.h | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibSQL/TupleDescriptor.h | 3 | ||||
-rw-r--r-- | Userland/Libraries/LibSQL/Type.h | 10 |
9 files changed, 185 insertions, 32 deletions
diff --git a/Userland/Libraries/LibSQL/AST/AST.h b/Userland/Libraries/LibSQL/AST/AST.h index 8f22bbab65..855c0bbd26 100644 --- a/Userland/Libraries/LibSQL/AST/AST.h +++ b/Userland/Libraries/LibSQL/AST/AST.h @@ -13,6 +13,8 @@ #include <AK/String.h> #include <LibSQL/AST/Token.h> #include <LibSQL/Forward.h> +#include <LibSQL/SQLResult.h> +#include <LibSQL/Type.h> namespace SQL::AST { @@ -251,16 +253,6 @@ private: NonnullRefPtrVector<TableOrSubquery> m_subqueries {}; }; -enum class Order { - Ascending, - Descending, -}; - -enum class Nulls { - First, - Last, -}; - class OrderingTerm : public ASTNode { public: OrderingTerm(NonnullRefPtr<Expression> expression, String collation_name, Order order, Nulls nulls) diff --git a/Userland/Libraries/LibSQL/Forward.h b/Userland/Libraries/LibSQL/Forward.h index e844a1e782..1ef5e733be 100644 --- a/Userland/Libraries/LibSQL/Forward.h +++ b/Userland/Libraries/LibSQL/Forward.h @@ -22,6 +22,7 @@ class IndexDef; class Key; class KeyPartDef; class Row; +class SQLResult; class TableDef; class TreeNode; class Tuple; diff --git a/Userland/Libraries/LibSQL/Meta.cpp b/Userland/Libraries/LibSQL/Meta.cpp index ce8dc12bd2..43a240f9af 100644 --- a/Userland/Libraries/LibSQL/Meta.cpp +++ b/Userland/Libraries/LibSQL/Meta.cpp @@ -37,7 +37,7 @@ NonnullRefPtr<IndexDef> SchemaDef::index_def() { NonnullRefPtr<IndexDef> s_index_def = IndexDef::construct("$schema", true, 0); if (!s_index_def->size()) { - s_index_def->append_column("schema_name", SQLType::Text, AST::Order::Ascending); + s_index_def->append_column("schema_name", SQLType::Text, Order::Ascending); } return s_index_def; } @@ -70,15 +70,15 @@ NonnullRefPtr<IndexDef> ColumnDef::index_def() { NonnullRefPtr<IndexDef> s_index_def = IndexDef::construct("$column", true, 0); if (!s_index_def->size()) { - s_index_def->append_column("table_hash", SQLType::Integer, AST::Order::Ascending); - s_index_def->append_column("column_number", SQLType::Integer, AST::Order::Ascending); - s_index_def->append_column("column_name", SQLType::Text, AST::Order::Ascending); - s_index_def->append_column("column_type", SQLType::Integer, AST::Order::Ascending); + s_index_def->append_column("table_hash", SQLType::Integer, Order::Ascending); + s_index_def->append_column("column_number", SQLType::Integer, Order::Ascending); + s_index_def->append_column("column_name", SQLType::Text, Order::Ascending); + s_index_def->append_column("column_type", SQLType::Integer, Order::Ascending); } return s_index_def; } -KeyPartDef::KeyPartDef(IndexDef* index, String name, SQLType sql_type, AST::Order sort_order) +KeyPartDef::KeyPartDef(IndexDef* index, String name, SQLType sql_type, Order sort_order) : ColumnDef(index, index->size(), move(name), sql_type) , m_sort_order(sort_order) { @@ -96,7 +96,7 @@ IndexDef::IndexDef(String name, bool unique, u32 pointer) { } -void IndexDef::append_column(String name, SQLType sql_type, AST::Order sort_order) +void IndexDef::append_column(String name, SQLType sql_type, Order sort_order) { auto part = KeyPartDef::construct(this, move(name), sql_type, sort_order); m_key_definition.append(part); @@ -131,9 +131,9 @@ NonnullRefPtr<IndexDef> IndexDef::index_def() { NonnullRefPtr<IndexDef> s_index_def = IndexDef::construct("$index", true, 0); if (!s_index_def->size()) { - s_index_def->append_column("table_hash", SQLType::Integer, AST::Order::Ascending); - s_index_def->append_column("index_name", SQLType::Text, AST::Order::Ascending); - s_index_def->append_column("unique", SQLType::Integer, AST::Order::Ascending); + s_index_def->append_column("table_hash", SQLType::Integer, Order::Ascending); + s_index_def->append_column("index_name", SQLType::Text, Order::Ascending); + s_index_def->append_column("unique", SQLType::Integer, Order::Ascending); } return s_index_def; } @@ -149,7 +149,7 @@ TupleDescriptor TableDef::to_tuple_descriptor() const { TupleDescriptor ret; for (auto& part : m_columns) { - ret.append({ part.name(), part.type(), AST::Order::Ascending }); + ret.append({ part.name(), part.type(), Order::Ascending }); } return ret; } @@ -192,8 +192,8 @@ NonnullRefPtr<IndexDef> TableDef::index_def() { NonnullRefPtr<IndexDef> s_index_def = IndexDef::construct("$table", true, 0); if (!s_index_def->size()) { - s_index_def->append_column("schema_hash", SQLType::Integer, AST::Order::Ascending); - s_index_def->append_column("table_name", SQLType::Text, AST::Order::Ascending); + s_index_def->append_column("schema_hash", SQLType::Integer, Order::Ascending); + s_index_def->append_column("table_name", SQLType::Text, Order::Ascending); } return s_index_def; } diff --git a/Userland/Libraries/LibSQL/Meta.h b/Userland/Libraries/LibSQL/Meta.h index 468e34cb95..ed2737e46e 100644 --- a/Userland/Libraries/LibSQL/Meta.h +++ b/Userland/Libraries/LibSQL/Meta.h @@ -13,7 +13,6 @@ #include <AK/String.h> #include <AK/Vector.h> #include <LibCore/Object.h> -#include <LibSQL/AST/AST.h> #include <LibSQL/Forward.h> #include <LibSQL/Key.h> #include <LibSQL/Type.h> @@ -90,11 +89,11 @@ class KeyPartDef : public ColumnDef { C_OBJECT(KeyPartDef); public: - KeyPartDef(IndexDef*, String, SQLType, AST::Order = AST::Order::Ascending); - AST::Order sort_order() const { return m_sort_order; } + KeyPartDef(IndexDef*, String, SQLType, Order = Order::Ascending); + Order sort_order() const { return m_sort_order; } private: - AST::Order m_sort_order { AST::Order::Ascending }; + Order m_sort_order { Order::Ascending }; }; class IndexDef : public Relation { @@ -106,7 +105,7 @@ public: NonnullRefPtrVector<KeyPartDef> key_definition() const { return m_key_definition; } bool unique() const { return m_unique; } [[nodiscard]] size_t size() const { return m_key_definition.size(); } - void append_column(String, SQLType, AST::Order = AST::Order::Ascending); + void append_column(String, SQLType, Order = Order::Ascending); Key key() const override; [[nodiscard]] TupleDescriptor to_tuple_descriptor() const; static NonnullRefPtr<IndexDef> index_def(); diff --git a/Userland/Libraries/LibSQL/SQLResult.h b/Userland/Libraries/LibSQL/SQLResult.h new file mode 100644 index 0000000000..0c83b19b40 --- /dev/null +++ b/Userland/Libraries/LibSQL/SQLResult.h @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2021, Jan de Visser <jan@de-visser.net> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/NonnullOwnPtrVector.h> +#include <AK/Vector.h> +#include <LibCore/Object.h> +#include <LibSQL/Tuple.h> +#include <LibSQL/Type.h> + +namespace SQL { + +#define ENUMERATE_SQL_COMMANDS(S) \ + S(Create) \ + S(Delete) \ + S(Insert) \ + S(Select) \ + S(Update) + +enum class SQLCommand { +#undef __ENUMERATE_SQL_COMMAND +#define __ENUMERATE_SQL_COMMAND(command) command, + ENUMERATE_SQL_COMMANDS(__ENUMERATE_SQL_COMMAND) +#undef __ENUMERATE_SQL_COMMAND +}; + +constexpr char const* command_tag(SQLCommand command) +{ + switch (command) { +#undef __ENUMERATE_SQL_COMMAND +#define __ENUMERATE_SQL_COMMAND(command) \ + case SQLCommand::command: \ + return #command; + ENUMERATE_SQL_COMMANDS(__ENUMERATE_SQL_COMMAND) +#undef __ENUMERATE_SQL_COMMAND + } +} + +#define ENUMERATE_SQL_ERRORS(S) \ + S(NoError, "No error") \ + S(DatabaseUnavailable, "Database Unavailable") \ + S(StatementUnavailable, "Statement with id {} Unavailable") \ + S(SyntaxError, "Syntax Error") \ + S(DatabaseDoesNotExist, "Database {} does not exist") \ + S(SchemaDoesNotExist, "Schema {} does not exist") \ + S(SchemaExists, "Schema {} already exist") \ + S(TableDoesNotExist, "Table {} does not exist") \ + S(TableExists, "Table {} already exist") \ + S(InvalidType, "Invalid type {}") + +enum class SQLErrorCode { +#undef __ENUMERATE_SQL_ERROR +#define __ENUMERATE_SQL_ERROR(error, description) error, + ENUMERATE_SQL_ERRORS(__ENUMERATE_SQL_ERROR) +#undef __ENUMERATE_SQL_ERROR +}; + +struct SQLError { + SQLErrorCode code { SQLErrorCode::NoError }; + String error_argument { "" }; + + String to_string() const + { + String code_string; + String message; + switch (code) { +#undef __ENUMERATE_SQL_ERROR +#define __ENUMERATE_SQL_ERROR(error, description) \ + case SQLErrorCode::error: \ + code_string = #error; \ + message = description; \ + break; + ENUMERATE_SQL_ERRORS(__ENUMERATE_SQL_ERROR) +#undef __ENUMERATE_SQL_ERROR + default: + VERIFY_NOT_REACHED(); + } + if (!error_argument.is_null() && !error_argument.is_empty()) { + if (message.find("{}").has_value()) { + message = String::formatted(message, error_argument); + } else { + message = String::formatted("{}: {}", message, error_argument); + } + } + if (message.is_null() || (message.is_empty())) { + return code_string; + } else { + return String::formatted("{}: {}", code_string, message); + } + } +}; + +class SQLResult : public Core::Object { + C_OBJECT(SQLResult) + +public: + void append(Tuple const& tuple) + { + m_has_results = true; + m_result_set.append(tuple); + } + + SQLCommand command() const { return m_command; } + int updated() const { return m_update_count; } + int inserted() const { return m_insert_count; } + int deleted() const { return m_delete_count; } + SQLError const& error() const { return m_error; } + bool has_results() const { return m_has_results; } + Vector<Tuple> const& results() const { return m_result_set; } + +private: + SQLResult() = default; + + explicit SQLResult(SQLCommand command, int update_count = 0, int insert_count = 0, int delete_count = 0) + : m_command(command) + , m_update_count(update_count) + , m_insert_count(insert_count) + , m_delete_count(delete_count) + { + } + + SQLResult(SQLCommand command, SQLErrorCode error_code, String error_argument) + : m_command(command) + , m_error({ error_code, move(error_argument) }) + { + } + + SQLCommand m_command { SQLCommand::Select }; + SQLError m_error { SQLErrorCode::NoError, "" }; + int m_update_count { 0 }; + int m_insert_count { 0 }; + int m_delete_count { 0 }; + bool m_has_results { false }; + Vector<Tuple> m_result_set; +}; + +} diff --git a/Userland/Libraries/LibSQL/Tuple.cpp b/Userland/Libraries/LibSQL/Tuple.cpp index c9d5da5c1f..aee5788d1f 100644 --- a/Userland/Libraries/LibSQL/Tuple.cpp +++ b/Userland/Libraries/LibSQL/Tuple.cpp @@ -174,6 +174,15 @@ String Tuple::to_string() const return builder.build(); } +Vector<String> Tuple::to_string_vector() const +{ + Vector<String> ret; + for (auto& value : m_data) { + ret.append(value.to_string().value()); + } + return ret; +} + size_t Tuple::size() const { size_t sz = sizeof(u32); @@ -203,7 +212,7 @@ int Tuple::compare(const Tuple& other) const for (auto ix = 0u; ix < num_values; ix++) { auto ret = m_data[ix].compare(other.m_data[ix]); if (ret != 0) { - if ((ix < m_descriptor.size()) && m_descriptor[ix].order == AST::Order::Descending) + if ((ix < m_descriptor.size()) && m_descriptor[ix].order == Order::Descending) ret = -ret; return ret; } @@ -223,7 +232,7 @@ int Tuple::match(const Tuple& other) const return -1; auto ret = m_data[my_index.value()].compare(other_value); if (ret != 0) - return (m_descriptor[my_index.value()].order == AST::Order::Descending) ? -ret : ret; + return (m_descriptor[my_index.value()].order == Order::Descending) ? -ret : ret; other_index++; } return 0; diff --git a/Userland/Libraries/LibSQL/Tuple.h b/Userland/Libraries/LibSQL/Tuple.h index 19dc2d4dd9..20fb3525e7 100644 --- a/Userland/Libraries/LibSQL/Tuple.h +++ b/Userland/Libraries/LibSQL/Tuple.h @@ -7,6 +7,7 @@ #pragma once #include <AK/Debug.h> +#include <AK/Vector.h> #include <LibSQL/Forward.h> #include <LibSQL/TupleDescriptor.h> #include <LibSQL/Value.h> @@ -42,6 +43,7 @@ public: [[nodiscard]] String to_string() const; explicit operator String() const { return to_string(); } + [[nodiscard]] Vector<String> to_string_vector() const; bool operator<(Tuple const& other) const { return compare(other) < 0; } bool operator<=(Tuple const& other) const { return compare(other) <= 0; } diff --git a/Userland/Libraries/LibSQL/TupleDescriptor.h b/Userland/Libraries/LibSQL/TupleDescriptor.h index c95dcfcb07..e1744d58ce 100644 --- a/Userland/Libraries/LibSQL/TupleDescriptor.h +++ b/Userland/Libraries/LibSQL/TupleDescriptor.h @@ -7,7 +7,6 @@ #pragma once #include <AK/Vector.h> -#include <LibSQL/AST/AST.h> #include <LibSQL/Type.h> namespace SQL { @@ -15,7 +14,7 @@ namespace SQL { struct TupleElement { String name { "" }; SQLType type { SQLType::Text }; - AST::Order order { AST::Order::Ascending }; + Order order { Order::Ascending }; bool operator==(TupleElement const&) const = default; }; diff --git a/Userland/Libraries/LibSQL/Type.h b/Userland/Libraries/LibSQL/Type.h index c9350d899e..865276a1de 100644 --- a/Userland/Libraries/LibSQL/Type.h +++ b/Userland/Libraries/LibSQL/Type.h @@ -37,4 +37,14 @@ inline static size_t size_of(SQLType t) } } +enum class Order { + Ascending, + Descending, +}; + +enum class Nulls { + First, + Last, +}; + } |