summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibSQL
diff options
context:
space:
mode:
authorJan de Visser <jan@de-visser.net>2021-06-28 21:15:17 -0400
committerAli Mohammad Pur <Ali.mpfard@gmail.com>2021-07-08 17:55:59 +0430
commita034774e3aceaf6c04efcf5bb2ba1313a91a17be (patch)
tree9d74ba1f73f783f7fdab1801b75800432a3bdadc /Userland/Libraries/LibSQL
parent1037d6b0eb453a11d58ab7a821a2fe1c5e82f325 (diff)
downloadserenity-a034774e3aceaf6c04efcf5bb2ba1313a91a17be.zip
LibSQL+SQLServer: Build SQLServer system service
This patch introduces the SQLServer system server. This service is supposed to be the only process/application talking to database storage. This makes things like locking and caching more reliable, easier to implement, and more efficient. In LibSQL we added a client component that does the ugly IPC nitty- gritty for you. All that's needed is setting a number of event handler lambdas and you can connect to databases and execute statements on them. Applications that wish to use this SQLClient class obviously need to link LibSQL and LibIPC.
Diffstat (limited to 'Userland/Libraries/LibSQL')
-rw-r--r--Userland/Libraries/LibSQL/CMakeLists.txt6
-rw-r--r--Userland/Libraries/LibSQL/SQLClient.cpp75
-rw-r--r--Userland/Libraries/LibSQL/SQLClient.h44
-rw-r--r--Userland/Libraries/LibSQL/SQLResult.h24
4 files changed, 138 insertions, 11 deletions
diff --git a/Userland/Libraries/LibSQL/CMakeLists.txt b/Userland/Libraries/LibSQL/CMakeLists.txt
index 3e7f033067..a5ba1f6b69 100644
--- a/Userland/Libraries/LibSQL/CMakeLists.txt
+++ b/Userland/Libraries/LibSQL/CMakeLists.txt
@@ -14,10 +14,16 @@ set(SOURCES
Key.cpp
Meta.cpp
Row.cpp
+ SQLClient.cpp
TreeNode.cpp
Tuple.cpp
Value.cpp
)
+set(GENERATED_SOURCES
+ ../../Services/SQLServer/SQLClientEndpoint.h
+ ../../Services/SQLServer/SQLServerEndpoint.h
+ )
+
serenity_lib(LibSQL sql)
target_link_libraries(LibSQL LibCore LibSyntax)
diff --git a/Userland/Libraries/LibSQL/SQLClient.cpp b/Userland/Libraries/LibSQL/SQLClient.cpp
new file mode 100644
index 0000000000..8114ef8075
--- /dev/null
+++ b/Userland/Libraries/LibSQL/SQLClient.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2021, Jan de Visser <jan@de-visser.net>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <LibSQL/SQLClient.h>
+
+namespace SQL {
+
+SQLClient::~SQLClient()
+{
+}
+
+void SQLClient::connected(int connection_id)
+{
+ if (on_connected)
+ on_connected(connection_id);
+}
+
+void SQLClient::disconnected(int connection_id)
+{
+ if (on_disconnected)
+ on_disconnected(connection_id);
+}
+
+void SQLClient::connection_error(int connection_id, int code, String const& message)
+{
+ if (on_connection_error)
+ on_connection_error(connection_id, code, message);
+ else
+ warnln("Connection error for connection_id {}: {} ({})", connection_id, message, code);
+}
+
+void SQLClient::execution_error(int statement_id, int code, String const& message)
+{
+ if (on_execution_error)
+ on_execution_error(statement_id, code, message);
+ else
+ warnln("Execution error for statement_id {}: {} ({})", statement_id, message, code);
+}
+
+void SQLClient::execution_success(int statement_id, bool has_results, int created, int updated, int deleted)
+{
+ if (on_execution_success)
+ on_execution_success(statement_id, has_results, created, updated, deleted);
+ else
+ outln("{} row(s) created, {} updated, {} deleted", created, updated, deleted);
+}
+
+void SQLClient::next_result(int statement_id, Vector<String> const& row)
+{
+ if (on_next_result) {
+ on_next_result(statement_id, row);
+ return;
+ }
+ bool first = true;
+ for (auto& column : row) {
+ if (!first)
+ out(", ");
+ out("\"{}\"", column);
+ first = false;
+ }
+ outln();
+}
+
+void SQLClient::results_exhausted(int statement_id, int total_rows)
+{
+ if (on_results_exhausted)
+ on_results_exhausted(statement_id, total_rows);
+ else
+ outln("{} total row(s)", total_rows);
+}
+
+}
diff --git a/Userland/Libraries/LibSQL/SQLClient.h b/Userland/Libraries/LibSQL/SQLClient.h
new file mode 100644
index 0000000000..d473c8f65d
--- /dev/null
+++ b/Userland/Libraries/LibSQL/SQLClient.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2021, Jan de Visser <jan@de-visser.net>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <LibIPC/ServerConnection.h>
+#include <SQLServer/SQLClientEndpoint.h>
+#include <SQLServer/SQLServerEndpoint.h>
+
+namespace SQL {
+
+class SQLClient
+ : public IPC::ServerConnection<SQLClientEndpoint, SQLServerEndpoint>
+ , public SQLClientEndpoint {
+ C_OBJECT(SQLClient);
+ virtual ~SQLClient();
+
+ Function<void(int)> on_connected;
+ Function<void(int)> on_disconnected;
+ Function<void(int, int, String const&)> on_connection_error;
+ Function<void(int, int, String const&)> on_execution_error;
+ Function<void(int, bool, int, int, int)> on_execution_success;
+ Function<void(int, Vector<String> const&)> on_next_result;
+ Function<void(int, int)> on_results_exhausted;
+
+private:
+ SQLClient()
+ : IPC::ServerConnection<SQLClientEndpoint, SQLServerEndpoint>(*this, "/tmp/portal/sql")
+ {
+ }
+
+ virtual void connected(int connection_id) override;
+ virtual void connection_error(int connection_id, int code, String const& message) override;
+ virtual void execution_success(int statement_id, bool has_results, int created, int updated, int deleted) override;
+ virtual void next_result(int statement_id, Vector<String> const&) override;
+ virtual void results_exhausted(int statement_id, int total_rows) override;
+ virtual void execution_error(int statement_id, int code, String const& message) override;
+ virtual void disconnected(int connection_id) override;
+};
+
+}
diff --git a/Userland/Libraries/LibSQL/SQLResult.h b/Userland/Libraries/LibSQL/SQLResult.h
index 0c83b19b40..f2871270f7 100644
--- a/Userland/Libraries/LibSQL/SQLResult.h
+++ b/Userland/Libraries/LibSQL/SQLResult.h
@@ -40,17 +40,18 @@ constexpr char const* command_tag(SQLCommand 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 {}")
+#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 '{}'") \
+ S(InvalidDatabaseName, "Invalid database name '{}'")
enum class SQLErrorCode {
#undef __ENUMERATE_SQL_ERROR
@@ -120,6 +121,7 @@ private:
, m_update_count(update_count)
, m_insert_count(insert_count)
, m_delete_count(delete_count)
+ , m_has_results(command == SQLCommand::Select)
{
}