Commit Graph

50 Commits

Author SHA1 Message Date
Jelle Raaijmakers
70ca295404 LibSQL+SQLServer: Do not re-open databases
Both `Database` and `Heap` were allowed to be opened twice. Prevent
this, and change SQLServer to only open databases that are not already
opened.

This fixes a Ladybird crash where opening the application twice would
erroneously duplicate free heap block indices.
2023-06-13 16:33:42 -04:00
Ben Wiederhake
560133a0c6 Everywhere: Remove unused DeprecatedString includes 2023-04-09 22:00:54 +02:00
Tim Schumacher
a96339b72b LibCore: Move Stream-based sockets into the Core namespace 2023-02-13 00:50:07 +00:00
MacDue
ab5bdc598d Revert "SQLServer: Unveil /etc/passwd"
This reverts commit c3bd841d50.
2023-02-05 16:40:51 +01:00
Timothy Flynn
cb06031180 LibSQL+SQLServer: Send result column names over IPC to SQL clients 2023-02-03 20:34:45 +01:00
MacDue
c3bd841d50 SQLServer: Unveil /etc/passwd
This is now required to launch the SQLServer for Browser (without
this it now fails to launch).
2023-02-02 02:17:06 -07:00
Timothy Flynn
c08956028a SQLServer: Mark a deferred invocation lambda as mutable
Otherwise the `move(result)` statement inside the lambda does not
actually move anything, because `result` is constant without the mutable
attribute. Caught by clangd.
2022-12-30 14:17:18 +01:00
Timothy Flynn
21255cb2b8 SQLServer: Explicitly return empty optionals over IPC upon errors
These are currently hitting the `decltype(nullptr)` constructor, which
marks the response as invalid, resulting in no response being sent to
the waiting client.
2022-12-30 14:17:18 +01:00
Timothy Flynn
12152a4556 SQLServer: Re-use already opened SQL::Database objects
Currently, we create a new SQL::Database object for each database we are
requested to open. When multiple clients connect to the same database,
the same underlying database file is opened and cached each time. This
results in updates from one client not being propagated to others.

To prevent this, when a database is requested to be open, check if it is
already open. We can then re-use that SQL::Database object for the new
connection.
2022-12-11 10:08:17 -05:00
Timothy Flynn
5ece0a13c4 SQLServer: Add a hook to inform owners of disconnected SQL clients 2022-12-09 20:33:19 +00:00
Timothy Flynn
c372012842 LibSQL+SQLServer+SQLStudio+sql: Give ID types a distinct name
Makes it clearer what is being stored, especially in future clients that
will store a bunch of statement IDs.
2022-12-08 17:14:48 +01:00
Timothy Flynn
b3e287342f SQLServer: Store LibSQL database files in the standard data directory
This also allows for overriding the path. Ladybird will want to store
the database files in a subdirectory of the standard data directory that
contains the Ladybird application name.

Fixes #16000.
2022-12-08 17:14:48 +01:00
Timothy Flynn
b159bdd4fd LibSQL+SQLServer+sql: Send and parse the correct number of changed rows
The sql REPL had the created/updated rows swapped by mistake. Also make
sure SQLServer fills in the correct value depending on the executed
command, and that the DELETE command indicates the rows it deleted.
2022-12-07 13:09:00 +01:00
Timothy Flynn
b9d8c25b0b LibSQL+SQLServer+SQLStudio+sql: Send result rows over IPC as SQL::Value
We've been sending the values converted to a string, but now that the
Value type is transferrable over IPC, send the values themselves. Any
client that wants the value as a string may do so easily, whereas this
will allow less trivial clients to avoid string parsing.
2022-12-07 13:09:00 +01:00
Timothy Flynn
27ce88864f SQLServer: Do not store statement execution results at the class level
If a statement is executed multiple times in quick succession, we may
overwrite the results of a previous execution. Instead of storing the
result, pass it around as it is sent to the client.
2022-12-07 13:09:00 +01:00
Timothy Flynn
f9d23e1d2f LibSQL+SQLServer+SQLStudio+sql: Propagate connection errors immediately
Currently, when clients connect to SQL server, we inform them of any
errors opening the database via an asynchronous IPC. But we already know
about these errors before returning from the connect() IPC, so this
roundabout propagation is a bit unnecessary. Now if we fail to open the
database, we will simply not send back a valid connection ID.

Disconnect has a similar story. Rather than disconnecting and invoking
an asynchronous IPC to inform the client of the disconnect, make the
disconnect() IPC synchronous (because all it does is remove the database
from the map of open databases). Further, the only user of this command
is the SQL REPL when it wants to connect to a different database, so it
makes sense to block it. This did require moving a bit of logic around
in the REPL to accommodate this change.
2022-12-07 13:09:00 +01:00
Timothy Flynn
aec75d749a LibSQL+SQLServer+SQLStudio+sql: Allocate per-statement-execution IDs
In order to execute a prepared statement multiple times, and track each
execution's results, clients will need to be provided an execution ID.
This will create a monotonically increasing ID each time a prepared
statement is executed for this purpose.
2022-12-07 13:09:00 +01:00
Timothy Flynn
e2f71d2808 LibSQL+SQLServer+SQLStudio+sql: Use proper types for SQL IPC and IDs
When storing IDs and sending values over IPC, this changes SQLServer to:

1. Stop using -1 as a nominal "bad" ID. Store the IDs as unsigned, and
   use Optional in the one place that the IPC needs to indicate an ID
   was not allocated.

2. Let LibIPC encode/decode enumerations (SQLErrorCode) on our behalf.

3. Use size_t for array sizes.
2022-12-07 13:09:00 +01:00
Timothy Flynn
8fcb8c30c6 SQLServer+SQLStudio+sql: Allow sending placeholder values to SQLServer 2022-12-07 13:09:00 +01:00
Timothy Flynn
b13527b8b2 SQLServer: Parse SQL a single time to actually "prepare" the statement
One of the benefits of prepared statements is that the SQL string is
parsed just once and re-used. This updates SQLStatement to do just that
and store the parsed result.
2022-12-07 13:09:00 +01:00
Linus Groh
57dc179b1f Everywhere: Rename to_{string => deprecated_string}() where applicable
This will make it easier to support both string types at the same time
while we convert code, and tracking down remaining uses.

One big exception is Value::to_string() in LibJS, where the name is
dictated by the ToString AO.
2022-12-06 08:54:33 +01:00
Linus Groh
6e19ab2bbc AK+Everywhere: Rename String to DeprecatedString
We have a new, improved string type coming up in AK (OOM aware, no null
state), and while it's going to use UTF-8, the name UTF8String is a
mouthful - so let's free up the String name by renaming the existing
class.
Making the old one have an annoying name will hopefully also help with
quick adoption :^)
2022-12-06 08:54:33 +01:00
Timothy Flynn
56843baff9 LibSQL+SQLServer: Return a NonnullRefPtr from Database::get_schema
Database::get_schema currently either returns a RefPtr to an existing
schema, a nullptr if the schema doesn't exist, or an Error if some
internal error occured. Change this to return a NonnullRefPtr to an
exisiting schema, or a SQL::Result with any error, including if the
schema was not found. Callers can then handle that specific error code
if they want.

Returning a NonnullRefPtr will enable some further cleanup. This had
some fallout of needing to change some other methods' return types from
AK::ErrorOr to SQL::Result so that TRY may continue to be used.
2022-11-30 11:43:13 +01:00
Timothy Flynn
0986b383cd SQLServer+SQLStudio+sql: Rename a couple of SQL IPC commands for clarity
Rename sql_statement to prepare_statement and statement_execute to
execute_statement. The former aligns more with other database libraries
(e.g. Java's JDBC prepareStatement). The latter reads less awkwardly.
2022-11-30 11:43:13 +01:00
MacDue
8a5d2be617 Everywhere: Remove unnecessary mutable attributes from lambdas
These lambdas were marked mutable as they captured a Ptr wrapper
class by value, which then only returned const-qualified references
to the value they point from the previous const pointer operators.

Nothing is actually mutating in the lambdas state here, and now
that the Ptr operators don't add extra const qualifiers these
can be removed.
2022-11-19 14:37:31 +00:00
Tim Schumacher
ce2f1b845f Everywhere: Mark dependencies of most targets as PRIVATE
Otherwise, we end up propagating those dependencies into targets that
link against that library, which creates unnecessary link-time
dependencies.

Also included are changes to readd now missing dependencies to tools
that actually need them.
2022-11-01 14:49:09 +00:00
Ali Mohammad Pur
166a905951 Userland: Properly populate GENERATED_SOURCES
We previously put the generated headers in SOURCES, which did not mark
them as GENERATED (and did not produce a proper dependency).
This commit moves all generated headers into GENERATED_SOURCES, and
removes useless header SOURCES.
2022-10-12 15:55:15 +01:00
Lenny Maiorani
0b7baa7e5a Services: Use default constructors/destructors
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#cother-other-default-operation-rules

"The compiler is more likely to get the default semantics right and
you cannot implement these functions better than the compiler."
2022-03-24 20:09:26 -07:00
Itamar
3a71748e5d Userland: Rename IPC ClientConnection => ConnectionFromClient
This was done with CLion's automatic rename feature and with:
find . -name ClientConnection.h
    | rename 's/ClientConnection\.h/ConnectionFromClient.h/'

find . -name ClientConnection.cpp
    | rename 's/ClientConnection\.cpp/ConnectionFromClient.cpp/'
2022-02-25 22:35:12 +01:00
Timothy Flynn
2397836f8e LibSQL+SQLServer: Introduce and use ResultOr<ValueType>
The result of a SQL statement execution is either:
    1. An error.
    2. The list of rows inserted, deleted, selected, etc.

(2) is currently represented by a combination of the Result class and
the ResultSet list it holds. This worked okay, but issues start to
arise when trying to use Result in non-statement contexts (for example,
when introducing Result to SQL expression execution).

What we really need is for Result to be a thin wrapper that represents
both (1) and (2), and to not have any explicit members like a ResultSet.
So this commit removes ResultSet from Result, and introduces ResultOr,
which is just an alias for AK::ErrorOrr. Statement execution now returns
ResultOr<ResultSet> instead of Result. This further opens the door for
expression execution to return ResultOr<Value> in the future.

Lastly, this moves some other context held by Result over to ResultSet.
This includes the row count (which is really just the size of ResultSet)
and the command for which the result is for.
2022-02-10 23:11:13 +01:00
Timothy Flynn
373b467302 LibSQL+SQLServer: Move LibSQL/SQLResult.[h,cpp] to LibSQL/Result.[h,cpp]
Rename the file to match the new class name.
2022-02-10 12:20:35 +00:00
Timothy Flynn
6620f19979 LibSQL+SQLServer: Return the new Result class from statement executions
We can now TRY anything that returns a SQL::Result or an AK::Error.
2022-02-10 12:20:35 +00:00
Jan de Visser
7fc901d1b3 LibSQL+SQLServer: Implement first cut of SELECT ... ORDER BY foo
Ordering is done by replacing the straight Vector holding the query
result in the SQLResult object with a dedicated Vector subclass that
inserts result rows according to their sort key using a binary search.
This is done in the ResultSet class.

There are limitations:
- "SELECT ... ORDER BY 1" (or 2 or 3 etc) is supposed to sort by the
n-th result column. This doesn't work yet
- "SELECT ... column-expression alias ... ORDER BY alias" is supposed to
sort by the column with the given alias. This doesn't work yet

What does work however is something like
```SELECT foo FROM bar SORT BY quux```
i.e. sorted by a column not in the result set. Once functions are
supported it should be possible to sort by random functions.
2022-01-16 11:17:15 +01:00
sin-ack
2e1bbcb0fa LibCore+LibIPC+Everywhere: Return Stream::LocalSocket from LocalServer
This change unfortunately cannot be atomically made without a single
commit changing everything.

Most of the important changes are in LibIPC/Connection.cpp,
LibIPC/ServerConnection.cpp and LibCore/LocalServer.cpp.

The notable changes are:
- IPCCompiler now generates the decode and decode_message functions such
  that they take a Core::Stream::LocalSocket instead of the socket fd.
- IPC::Decoder now uses the receive_fd method of LocalSocket instead of
  doing system calls directly on the fd.
- IPC::ConnectionBase and related classes now use the Stream API
  functions.
- IPC::ServerConnection no longer constructs the socket itself; instead,
  a convenience macro, IPC_CLIENT_CONNECTION, is used in place of
  C_OBJECT and will generate a static try_create factory function for
  the ServerConnection subclass. The subclass is now responsible for
  passing the socket constructed in this function to its
  ServerConnection base; the socket is passed as the first argument to
  the constructor (as a NonnullOwnPtr<Core::Stream::LocalServer>) before
  any other arguments.
- The functionality regarding taking over sockets from SystemServer has
  been moved to LibIPC/SystemServerTakeover.cpp. The Core::LocalSocket
  implementation of this functionality hasn't been deleted due to my
  intention of removing this class in the near future and to reduce
  noise on this (already quite noisy) PR.
2022-01-15 13:29:48 +03:30
Andreas Kling
6d0f504822 LibIPC: Add IPC::MultiServer convenience class
This encapsulates what our multi-client IPC servers typically do on
startup:

    1. Create a Core::LocalServer
    2. Take over a listening socket file descriptor from SystemServer
    3. Set up an accept handler for incoming connections

IPC::MultiServer does all this for you! All you have to do is provide
the relevant client connection type as a template argument.
2021-12-06 19:22:16 +01:00
Andreas Kling
81047d8f9c LibCore: Make LocalServer::take_over_from_system_server() return ErrorOr
This allows us to use TRY() or MUST() when calling it.
2021-12-06 19:22:16 +01:00
Andreas Kling
229a45ab14 SQLServer: Port to LibMain :^) 2021-12-06 19:22:16 +01:00
Sam Atkins
92f8514a85 Services: Cast unused IPC::new_client_connection() results to void
These ones all manage their storage internally, whereas the WebContent
and ImageDecoder ones require the caller to manage their lifetime. This
distinction is not obvious to the user without looking through the code,
so an API that makes this clearer would be nice.
2021-12-05 15:31:03 +01:00
Jan de Visser
001949d77a LibSQL: Improve error handling
The handling of filesystem level errors was basically non-existing or
consisting of `VERIFY_NOT_REACHED` assertions. Addressed this by
* Adding `open` methods to `Heap` and `Database` which return errors.
* Changing the interface of methods of these classes and clients
downstream to propagate these errors.

The constructors of `Heap` and `Database` don't open the underlying
filesystem file anymore.

The SQL statement handlers return an `SQLErrorCode::InternalError`
error code if an error comes back from the lower levels. Note that some
of these errors are things like duplicate index entry errors that should
be caught before the SQL layer attempts to actually update the database.

Added tests to catch attempts to open weird or non-existent files as
databases.

Finally, in between me writing this patch and submitting the PR the
AK::Result<Foo, Bar> template got deprecated in favour of ErrorOr<Foo>.
This resulted in more busywork.
2021-12-04 20:49:22 +03:30
Andreas Kling
fe00393941 LibCore: Change Core::LocalServer::on_ready_to_accept => on_accept
Everyone used this hook in the same way: immediately accept() on the
socket and then do something with the newly accepted fd.

This patch simplifies the hook by having LocalServer do the accepting
automatically.
2021-11-30 23:34:40 +01:00
Jan de Visser
1c50e9aadc LibSQL: Add current statement to the ExecutionContext
Because SQL is the craptastic language that it is, sometimes expressions
need to know details about the calling statement. For example the tables
in the 'FROM' clause may be needed to determine which columns are
referenced in 'WHERE' expressions. So the current statement is added
to the ExecutionContext and a new 'execute' overload on Statement is
created which takes the Database and the Statement and builds an
ExecutionContaxt from those.
2021-11-10 14:47:49 +01:00
Ben Wiederhake
0d6c8afa4e SQLServer: Remove unnecessary magic number 2021-11-05 00:17:01 +03:30
Ben Wiederhake
4e55d649d7 Services: Fix visibility of Object-derivative constructors
Derivatives of Core::Object should be constructed through
ClassName::construct(), to avoid handling ref-counted objects with
refcount zero. Fixing the visibility means that misuses like this are
more difficult.
2021-11-02 22:56:53 +01:00
Jan de Visser
e923cb3739 SQLServer+SQL+LibSQL: Allow sql client to specify the database name
The database the sql client connected to was 'hardcoded' to the login
name of the calling user.
- Extended the IPC API to be more expressive when connecting, by
returning the name of the database the client connected to in the
'connected' callback.
- Gave the sql client a command line argument (-d/--database) allowing
an alternative database name to be specified

A subsequent commit will have a dot command allowing the user to
connect to different databases from the same sql session.
2021-10-05 02:22:19 +02:00
Jan de Visser
c5c7a9d198 SQLServer: Do not capture stack variables by reference in lambdas
If you capture a stack variable by reference in a lamdba definition,
and this lambda outlives the scope of the stack variable, this reference
may point to garbage when the lambda is executed. Therefore capture as
little as possible (typically only ``this``), and what is captured is
captured by value
2021-10-05 02:22:19 +02:00
sin-ack
8ea22121ac Userland: Migrate to argument-less deferred_invoke
Only one place used this argument and it was to hold on to a strong ref
for the object. Since we already do that now, there's no need to keep
this argument around since this can be easily captured.

This commit contains no changes.
2021-09-02 03:47:47 +04:30
Andreas Kling
4c8fe01bff SQLServer: Don't stat()-then-mkdir() when mkdir() alone is enough
Closes a TOCTOU race that SonarCloud complained about.

SonarCloud: https://sonarcloud.io/project/issues?id=SerenityOS_serenity&issues=AXuVO_uKk92xXUF3qSVc&open=AXuVO_uKk92xXUF3qSVc
2021-08-30 18:35:36 +02:00
Robert Stefanic
e4f040147f SQLServer: Use m_client_id instead of client_id in callback
In the DatabaseConnection constructor, there's a deferred_invoke
callback that references the client_id. But depending on when the
callback occurs, the reference of the client_id can change. This created
a problem when connecting to SQLServer using the SQL utility because
depending on when the callback was invoked, the client_id could change.

m_client_id is set in the constructor and that reference will not change
depending on when the callback is invoked.
2021-08-22 15:32:09 +02:00
Jan de Visser
d074a601df LibSQL+SQLServer: Bare bones INSERT and SELECT statements
This patch provides very basic, bare bones implementations of the
INSERT and SELECT statements. They are *very* limited:
- The only variant of the INSERT statement that currently works is
   SELECT INTO schema.table (column1, column2, ....) VALUES
      (value11, value21, ...), (value12, value22, ...), ...
   where the values are literals.
- The SELECT statement is even more limited, and is only provided to
  allow verification of the INSERT statement. The only form implemented
  is: SELECT * FROM schema.table

These statements required a bit of change in the Statement::execute
API. Originally execute only received a Database object as parameter.
This is not enough; we now pass an ExecutionContext object which
contains the Database, the current result set, and the last Tuple read
from the database. This object will undoubtedly evolve over time.

This API change dragged SQLServer::SQLStatement into the patch.

Another API addition is Expression::evaluate. This method is,
unsurprisingly, used to evaluate expressions, like the values in the
INSERT statement.

Finally, a new test file is added: TestSqlStatementExecution, which
tests the currently implemented statements. As the number and flavour of
implemented statements grows, this test file will probably have to be
restructured.
2021-08-21 22:03:30 +02:00
Jan de Visser
a034774e3a 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.
2021-07-08 17:55:59 +04:30