mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-10 13:00:29 +03:00
LibSQL: Move Order and Nulls enums from SQL::AST to SQL namespace
The Order enum is used in the Meta component of LibSQL. Using this enum meant having to include the monster AST/AST.h include file. Furthermore, they are sort of basic and therefore can live in the general SQL namespace. Moved to LibSQL/Type.h. Also introduced a new class, SQLResult, which is needed in future patches.
This commit is contained in:
parent
633dc74606
commit
30691549fd
Notes:
sideshowbarker
2024-07-18 10:04:43 +09:00
Author: https://github.com/JanDeVisser Commit: https://github.com/SerenityOS/serenity/commit/30691549fdc Pull-request: https://github.com/SerenityOS/serenity/pull/8306 Reviewed-by: https://github.com/MaxWipfli Reviewed-by: https://github.com/alimpfard ✅ Reviewed-by: https://github.com/trflynn89 ✅
@ -127,7 +127,7 @@ void insert_into_and_scan_btree(int num_keys);
|
||||
NonnullRefPtr<SQL::BTree> setup_btree(SQL::Heap& heap)
|
||||
{
|
||||
SQL::TupleDescriptor tuple_descriptor;
|
||||
tuple_descriptor.append({ "key_value", SQL::SQLType::Integer, SQL::AST::Order::Ascending });
|
||||
tuple_descriptor.append({ "key_value", SQL::SQLType::Integer, SQL::Order::Ascending });
|
||||
|
||||
auto root_pointer = heap.user_value(0);
|
||||
if (!root_pointer) {
|
||||
|
@ -124,8 +124,8 @@ void insert_into_and_scan_hash_index(int num_keys);
|
||||
NonnullRefPtr<SQL::HashIndex> setup_hash_index(SQL::Heap& heap)
|
||||
{
|
||||
SQL::TupleDescriptor tuple_descriptor;
|
||||
tuple_descriptor.append({ "key_value", SQL::SQLType::Integer, SQL::AST::Order::Ascending });
|
||||
tuple_descriptor.append({ "text_value", SQL::SQLType::Text, SQL::AST::Order::Ascending });
|
||||
tuple_descriptor.append({ "key_value", SQL::SQLType::Integer, SQL::Order::Ascending });
|
||||
tuple_descriptor.append({ "text_value", SQL::SQLType::Text, SQL::Order::Ascending });
|
||||
|
||||
auto directory_pointer = heap.user_value(0);
|
||||
if (!directory_pointer) {
|
||||
|
@ -567,8 +567,8 @@ TEST_CASE(select)
|
||||
|
||||
struct Ordering {
|
||||
String collation_name;
|
||||
SQL::AST::Order order;
|
||||
SQL::AST::Nulls nulls;
|
||||
SQL::Order order;
|
||||
SQL::Nulls nulls;
|
||||
};
|
||||
|
||||
auto validate = [](StringView sql, Vector<Type> expected_columns, Vector<From> expected_from_list, bool expect_where_clause, size_t expected_group_by_size, bool expect_having_clause, Vector<Ordering> expected_ordering, bool expect_limit_clause, bool expect_offset_clause) {
|
||||
@ -674,13 +674,13 @@ TEST_CASE(select)
|
||||
validate("SELECT * FROM table_name GROUP BY column1, column2, column3;", all, from, false, 3, false, {}, false, false);
|
||||
validate("SELECT * FROM table_name GROUP BY column_name HAVING 'abc';", all, from, false, 1, true, {}, false, false);
|
||||
|
||||
validate("SELECT * FROM table_name ORDER BY column_name;", all, from, false, 0, false, { { {}, SQL::AST::Order::Ascending, SQL::AST::Nulls::First } }, false, false);
|
||||
validate("SELECT * FROM table_name ORDER BY column_name COLLATE collation;", all, from, false, 0, false, { { "COLLATION", SQL::AST::Order::Ascending, SQL::AST::Nulls::First } }, false, false);
|
||||
validate("SELECT * FROM table_name ORDER BY column_name ASC;", all, from, false, 0, false, { { {}, SQL::AST::Order::Ascending, SQL::AST::Nulls::First } }, false, false);
|
||||
validate("SELECT * FROM table_name ORDER BY column_name DESC;", all, from, false, 0, false, { { {}, SQL::AST::Order::Descending, SQL::AST::Nulls::Last } }, false, false);
|
||||
validate("SELECT * FROM table_name ORDER BY column_name ASC NULLS LAST;", all, from, false, 0, false, { { {}, SQL::AST::Order::Ascending, SQL::AST::Nulls::Last } }, false, false);
|
||||
validate("SELECT * FROM table_name ORDER BY column_name DESC NULLS FIRST;", all, from, false, 0, false, { { {}, SQL::AST::Order::Descending, SQL::AST::Nulls::First } }, false, false);
|
||||
validate("SELECT * FROM table_name ORDER BY column1, column2 DESC, column3 NULLS LAST;", all, from, false, 0, false, { { {}, SQL::AST::Order::Ascending, SQL::AST::Nulls::First }, { {}, SQL::AST::Order::Descending, SQL::AST::Nulls::Last }, { {}, SQL::AST::Order::Ascending, SQL::AST::Nulls::Last } }, false, false);
|
||||
validate("SELECT * FROM table_name ORDER BY column_name;", all, from, false, 0, false, { { {}, SQL::Order::Ascending, SQL::Nulls::First } }, false, false);
|
||||
validate("SELECT * FROM table_name ORDER BY column_name COLLATE collation;", all, from, false, 0, false, { { "COLLATION", SQL::Order::Ascending, SQL::Nulls::First } }, false, false);
|
||||
validate("SELECT * FROM table_name ORDER BY column_name ASC;", all, from, false, 0, false, { { {}, SQL::Order::Ascending, SQL::Nulls::First } }, false, false);
|
||||
validate("SELECT * FROM table_name ORDER BY column_name DESC;", all, from, false, 0, false, { { {}, SQL::Order::Descending, SQL::Nulls::Last } }, false, false);
|
||||
validate("SELECT * FROM table_name ORDER BY column_name ASC NULLS LAST;", all, from, false, 0, false, { { {}, SQL::Order::Ascending, SQL::Nulls::Last } }, false, false);
|
||||
validate("SELECT * FROM table_name ORDER BY column_name DESC NULLS FIRST;", all, from, false, 0, false, { { {}, SQL::Order::Descending, SQL::Nulls::First } }, false, false);
|
||||
validate("SELECT * FROM table_name ORDER BY column1, column2 DESC, column3 NULLS LAST;", all, from, false, 0, false, { { {}, SQL::Order::Ascending, SQL::Nulls::First }, { {}, SQL::Order::Descending, SQL::Nulls::Last }, { {}, SQL::Order::Ascending, SQL::Nulls::Last } }, false, false);
|
||||
|
||||
validate("SELECT * FROM table_name LIMIT 15;", all, from, false, 0, false, {}, true, false);
|
||||
validate("SELECT * FROM table_name LIMIT 15 OFFSET 16;", all, from, false, 0, false, {}, true, true);
|
||||
|
@ -136,8 +136,8 @@ TEST_CASE(order_int_values)
|
||||
TEST_CASE(tuple)
|
||||
{
|
||||
SQL::TupleDescriptor descriptor;
|
||||
descriptor.append({ "col1", SQL::SQLType::Text, SQL::AST::Order::Ascending });
|
||||
descriptor.append({ "col2", SQL::SQLType::Integer, SQL::AST::Order::Descending });
|
||||
descriptor.append({ "col1", SQL::SQLType::Text, SQL::Order::Ascending });
|
||||
descriptor.append({ "col2", SQL::SQLType::Integer, SQL::Order::Descending });
|
||||
SQL::Tuple tuple(descriptor);
|
||||
|
||||
tuple["col1"] = "Test";
|
||||
@ -149,8 +149,8 @@ TEST_CASE(tuple)
|
||||
TEST_CASE(serialize_tuple)
|
||||
{
|
||||
SQL::TupleDescriptor descriptor;
|
||||
descriptor.append({ "col1", SQL::SQLType::Text, SQL::AST::Order::Ascending });
|
||||
descriptor.append({ "col2", SQL::SQLType::Integer, SQL::AST::Order::Descending });
|
||||
descriptor.append({ "col1", SQL::SQLType::Text, SQL::Order::Ascending });
|
||||
descriptor.append({ "col2", SQL::SQLType::Integer, SQL::Order::Descending });
|
||||
SQL::Tuple tuple(descriptor);
|
||||
|
||||
tuple["col1"] = "Test";
|
||||
@ -170,8 +170,8 @@ TEST_CASE(serialize_tuple)
|
||||
TEST_CASE(copy_tuple)
|
||||
{
|
||||
SQL::TupleDescriptor descriptor;
|
||||
descriptor.append({ "col1", SQL::SQLType::Text, SQL::AST::Order::Ascending });
|
||||
descriptor.append({ "col2", SQL::SQLType::Integer, SQL::AST::Order::Descending });
|
||||
descriptor.append({ "col1", SQL::SQLType::Text, SQL::Order::Ascending });
|
||||
descriptor.append({ "col2", SQL::SQLType::Integer, SQL::Order::Descending });
|
||||
SQL::Tuple tuple(descriptor);
|
||||
|
||||
tuple["col1"] = "Test";
|
||||
@ -188,8 +188,8 @@ TEST_CASE(copy_tuple)
|
||||
TEST_CASE(compare_tuples)
|
||||
{
|
||||
SQL::TupleDescriptor descriptor;
|
||||
descriptor.append({ "col1", SQL::SQLType::Text, SQL::AST::Order::Ascending });
|
||||
descriptor.append({ "col2", SQL::SQLType::Integer, SQL::AST::Order::Descending });
|
||||
descriptor.append({ "col1", SQL::SQLType::Text, SQL::Order::Ascending });
|
||||
descriptor.append({ "col2", SQL::SQLType::Integer, SQL::Order::Descending });
|
||||
|
||||
SQL::Tuple tuple1(descriptor);
|
||||
tuple1["col1"] = "Test";
|
||||
|
@ -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)
|
||||
|
@ -22,6 +22,7 @@ class IndexDef;
|
||||
class Key;
|
||||
class KeyPartDef;
|
||||
class Row;
|
||||
class SQLResult;
|
||||
class TableDef;
|
||||
class TreeNode;
|
||||
class Tuple;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
141
Userland/Libraries/LibSQL/SQLResult.h
Normal file
141
Userland/Libraries/LibSQL/SQLResult.h
Normal file
@ -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;
|
||||
};
|
||||
|
||||
}
|
@ -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;
|
||||
|
@ -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; }
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -37,4 +37,14 @@ inline static size_t size_of(SQLType t)
|
||||
}
|
||||
}
|
||||
|
||||
enum class Order {
|
||||
Ascending,
|
||||
Descending,
|
||||
};
|
||||
|
||||
enum class Nulls {
|
||||
First,
|
||||
Last,
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user