"The official project language is American English […]."
5d2e915623/CONTRIBUTING.md (L30)
Here's a short statistic of the occurrences of the word "behavio(u)r":
$ git grep -IPioh 'behaviou?r' | sort | uniq -c | sort -n
2 BEHAVIOR
24 Behaviour
32 behaviour
407 Behavior
992 behavior
Therefore, it is clear that "behaviour" (56 occurrences) should be
regarded a typo, and "behavior" (1401 occurrences) should be preferred.
Note that The occurrences in LibJS are intentionally NOT changed,
because there are taken verbatim from the specification. Hence:
$ git grep -IPioh 'behaviou?r' | sort | uniq -c | sort -n
2 BEHAVIOR
10 behaviour
24 Behaviour
407 Behavior
1014 behavior
SQLClient exists as a wrapper around SQL IPC to provide a bit friendlier
interface for clients to deal with. Though right now, it mostly forwards
values as-is from IPC to the clients. This makes it a bit verbose to add
values to IPC responses, as we then have to add it to the callbacks used
by all clients. It's also a bit confusing seeing a sea of "auto" as the
parameter types for these callbacks.
This patch moves these response values to named structures instead. This
will allow adding values without needing to simultaneously update all
clients. We can then separately handle the new values in interested
clients only.
Use the new get_paths_for_helper_process method in Ladybird to query
Qt for the runtime path of the current executable as well as the build
directory paths.
Having an alias function that only wraps another one is silly, and
keeping the more obvious name should flush out more uses of deprecated
strings.
No behavior change.
In both applications, display the SQL statement that failed to parse.
For the REPL, ensure the REPL prompts the user for another statement.
For SQLStudio, we don't continue executing the script as it likely does
not make sense to run statements that come after a failed statement.
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.
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.
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.
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.
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.
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.
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 :^)
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.
Each of these strings would previously rely on StringView's char const*
constructor overload, which would call __builtin_strlen on the string.
Since we now have operator ""sv, we can replace these with much simpler
versions. This opens the door to being able to remove
StringView(char const*).
No functional changes.
This fixes a bug in the SQL REPL where after a user enters an
unrecognized command, the REPL would not print another "> " prompt and
would not accept any more input.
Previously, if a user pressed Enter without typing a command at
the SQL REPL, the next line would be automatically indented. This
change makes it so we check if there were any tokens in the command
before applying the indentation logic.
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.
Add a number of command line switches:
- '-r/--read': Read a SQL file and quit the REPL when done
- '-s/--source': Read a SQL file and return to a SQL prompt when done
- '--no-sqlrc': Do not read ~/.sqlrc on startup (see below)
Add a dot-command:
.read <filename>: Read a SQL file and return to a SQL prompt when done
In addition, the sql REPL will source the ~/.sqlrc file on startup if
it exists, unless the --no-sqlrc flag is set on startup.
Note the slight asymmetry between the --read command line flag (which
results in the program quitting when the file is read) and the .read
command (which doesn't cause a quit).
Also fix merge conflict with #10091
The existing input loop called the `read_sql` method recursively. This
lead to strange behaviour in the event loop. This is solved by
encapsulating the REPL in an object and ensuring the `read_sql` method
is not called recursively. The method now returns after the first
recognized SQL statement or command.
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.
Previously, a String literal token like 'hello' had every char
highlighted but for the last 'o' and the closing single quote. This is
because the token start is at the opening single quote but the `length`
variable only accounted for the value length without the single quotes.
Command used:
grep -Pirn '(out|warn)ln\((?!["\)]|format,|stderr,|stdout,|output, ")' \
AK Kernel/ Tests/ Userland/
(Plus some manual reviewing.)
Let's pick ArgsParser as an example:
outln(file, m_general_help);
This will fail at runtime if the general help happens to contain braces.
Even if this transformation turns out to be unnecessary in a place or
two, this way the code is "more obviously" correct.
We already do this in most places, so the style should be consistent.
Also, Clang does not like it, as this could cause an unexpected compile
error if some statements are added to the default label or a new label
is added above it.
SQL was standardized before there was consensus on sane language syntax
constructs had evolved. The language is mostly case-insensitive, with
unquoted text converted to upper case. Identifiers can include lower
case characters and other 'special' characters by enclosing the
identifier with double quotes. A double quote is escaped by doubling it.
Likewise, a single quote in a literal string is escaped by doubling it.
All this means that the strategy used in the lexer, where a token's
value is a StringView 'window' on the source string, does not work,
because the value needs to be massaged before being handed to the
parser. Therefore a token now has a String containing its value. Given
the limited lifetime of a token, this is acceptable overhead.
Not doing this means that for example quote removal and double quote
escaping would need to be done in the parser or in AST node
construction, which would spread lexing basically all over the place.
Which would be suboptimal.
There was some impact on the sql utility and SyntaxHighlighter component
which was addressed by storing the token's end position together with
the start position in order to properly highlight it.
Finally, reviewing the tests for parsing numeric literals revealed an
inconsistency in which tokens we accept or reject: `1a` is accepted but
`1e` is rejected. Related to this is the fate of `0x`. Added a FIXME
reminding us to address this.
SPDX License Identifiers are a more compact / standardized
way of representing file license information.
See: https://spdx.dev/resources/use/#identifiers
This was done with the `ambr` search and replace tool.
ambr --no-parent-ignore --key-from-file --rep-from-file key.txt rep.txt *
This adds a simple REPL command line utility for (eventually) executing
SQL statements / files. Currently, it just validates statements from
stdin and prints any errors.