Commit Graph

111 Commits

Author SHA1 Message Date
Martin Kleusberg
43107ea773 Refactor data structures for table constraints
This is a long overdue continuation of some previous refactoring effort.
Before this we used to store the columns a table constraint belongs to
within the constraint object itself. So for example, a foreign key
constraint object would store the referencing as well as the referenced
column names. While initially simple, this approach has the downside of
duplicating certain data, thus breaking ownership and complicating
matters later on. This becomes obvious when renaming the referencing
column. The column name clearly is a feature of the table but in the
previous approach it also needs to be changed in the foreign key object
as well as in any other constraint for this field even though the
constraint itself has not been touched. This illustrates how a
constraint is not only a property of a table but the field names (a
property of the table) are also a property of the constraint, creating a
circular ownership. This makes the code hard to maintain. It also
invalidates references to constraints in the program needlessly, e.g.
when only changing a column name.

With this commit the column names are removed from the constraint types.
Instead they are now solely a property of the table. This, however,
raised another issue. For unique constraints and primary keys it is
possible to use expressions and/or sorted keys whereas for foreign keys
this is not possible. Additionally check constraints have no columns at
all. So when not storing the used columns inside the constraint objects
we need to have different storage types for each of them. So in a second
step this commit moves the code from a single data structure for storing
all table constraints to three data structures, one for PK and unique,
one for foreign keys, and one for check constraints.

By doing all this, this commit also changes the interface for handling
quite a bit. The new interface tends to use more explicit types which
makes the usage code easier to read.

Please note that this is still far from finished. But future development
on this should be a lot easier now.
2022-03-24 21:37:43 +01:00
Martin Kleusberg
42b7a37192 parser: Add support for strict tables to the SQL parser
See issue #2926.
2021-12-24 21:51:34 +01:00
Martin Kleusberg
a302128d2e Simplify dependencies and remove unneeded dependencies from tests
This moves the code to remove comments from SQL statements from the
SqliteTableModel class to Data.cpp making it a free function. This
removes some dependencies from the SqliteTableModel class with all its
dependencies.

Also simplify the CMakeLists.txt file for the tests by removing all the
dependencies which are not really required.
2021-08-22 10:31:31 +02:00
Martin Kleusberg
060e925074 build: Make CMakeLists.txt easier to use
This adds the moc header files to the dependencies of the executable in
the cmake project so they show up in their proper location in QtCreator.
This makes it more pleasant to use the cmake files as a QtCreator
project file.

Also rework the CMakeLists.txt file a bit by fixing whitespace issues,
rearranging some blocks and unifying the code style a bit.
2021-08-13 14:47:06 +02:00
Martin Kleusberg
af3c0f8239 tests: Add test for c5853727b7 2021-07-10 14:32:43 +02:00
Martin Kleusberg
66e8a5ec84 tests: Fix crash in regex tests 2020-08-17 18:30:23 +02:00
Martin Kleusberg
85e1d0863c tests: Clean up test cases 2020-06-23 16:36:53 +02:00
Martin Kleusberg
9481bd8ef6 tests: Activate more parser tests
Now that we have parser support for named constraints we can activate a
couple more tests.
2020-06-19 16:02:08 +02:00
Martin Kleusberg
091273869d tests: Simplify code 2019-09-26 15:30:37 +02:00
Martin Kleusberg
402ea9f359 tests: Add more test cases for the SQLite parser 2019-09-13 14:22:12 +02:00
Martin Kleusberg
ce66c1da20 Remove the Antlr parser and the Antlr runtime library
Both are fully replaced by our new parser and are no longer needed.

See issue #1990.
2019-09-13 14:22:12 +02:00
Martin Kleusberg
ec0ebed697 grammar: Replace Antlr parser for CREATE TABLE statements by new parser
This extends our new Bison-generated parser to also parse CREATE TABLE
statements and replaces the last parts of the Antlr-generated parser by
doing so.

Also adjust the unit tests to match the new style of parsed expressions.
They have better formatting now and identifiers are always correctly
quoted. This could not be done before and so the tests expected the old
look of expression statements.

See issue #1990.
2019-09-13 14:22:04 +02:00
Martin Kleusberg
9e8cb6e2fb grammar: Replace the Antlr parser for CREATE INDEX statements
Replace the Antlr lexer and parser for CREATE INDEX statements a new
lexer and parser generated with flex and bison. This commit is a first
step towards replacing all Antlr-realted parts of the parser. Until then
the new bison-generated parser is only used for CREATE INDEX statements
and the old Antlr-generated parser is used for CREATE TABLE statements.

These are the main reasons for replacing all of the Antlr parser:
- Getting rid of the Antlr runtime library as a dependency.
- Not depending on an old piece of sotware (we are depending on Antlr2
  while Antlr4 is available at the moment. However, migrating to Antlr4
  is as bad as migrating to bison).
- Better handling of expressions in statements. This proved to be a
  consistent source of problems over the last couple of years.
- Somewhat better Unicode support.
- Reentrant code / multithreading support.
- I can finally uninstall Java from my computer.

See #1990.
2019-09-12 11:25:41 +02:00
Martin Kleusberg
3237e9d2f5 grammar: Rework how PK and unique constraints work
This commit changes the class hierarchy to make primary key constraints
a type of unique constraints. This fits nicely with reality because
primary key columns do not allow duplicate values. It also makes our
life easier as the other changes which are introduced here add some code
required by both unique and primary key constraints and which now can be
shared.

Move the auto increment flag from the field class to the primary key
class. This changes how auto increment fields work and look and might be
a bit unfamiliar but it simplifies things a lot for us because an auto
increment field is always a primary key. So before we had to maintain
two places: the field with the auto increment flag and the primary key
which belongs to it. Now it is all in one place in the primary key.

Add support for storing and manipulating sort order for columns in
primary key and unique constraints. It does not add support for them to
the grammar parser though.

Finally add a way to store and manipulate on conflict clauses for unique
and primary key constraints. Again, parser support for them is not added.
2019-09-11 15:09:23 +02:00
Martin Kleusberg
2958e5acba Silence some warnings and fix bug with RTL editor
This silences a couple of compiler warnings. The changes in the grammar
parser serve the same purpose: they silence at least some of the
warnings Antlr prints while generating the parser code.

In the Edit Dialog a missing break is added to a switch statement. This
seems like it actually was an unintended fallthrough for once, setting
the focus to the hex editor instead of the RTL editor.
2019-08-28 19:08:27 +02:00
Martin Kleusberg
df291aa286 grammar: Fix whitespace problems
When using a "x IS NOT NULL" expression in a statement our parser was
generating something like "xIS NOTNULL". This was especially a problem
because the table looked like it parsed correctly but actually contained
a faulty expression. So when modifying the table you would get
unexpected error messages, or worse silent errors introduced into your
table.

Also add a test case for this and for commit e7ba79f478.

See issue #1969.
2019-08-20 10:05:03 +02:00
Martin Kleusberg
05181df8b8 grammar: Fix parsing of more complex expressions
See issue #1950.
2019-08-01 11:14:30 +02:00
Martin Kleusberg
263c28e6f4 grammar: Correctly parse the modulo operator
This adds a missing definition for the % character in order to make the
modulo operator work correctly in expressions.

See issue #1950.
2019-08-01 11:06:59 +02:00
Martin Kleusberg
55b3f6378f grammar: Correctly parse subexpressions in parentheses
This fixes parsing for table definitions like this:

CREATE TABLE a(
    x INT DEFAULT(5 + (1))
);

See issue #1950.
2019-08-01 11:06:08 +02:00
Martin Kleusberg
cb694dd2c6 grammar: Change the way the table constraints are stored
This changes the way we store the constraints associated with a table
from using a map to using a set. The map was mapping from the list of
field names to the constraint applied on these fields. Now the field
list is stored inside the constraint and we can store the constraints in
a simple set. This turns out to simplify the code noticeably.
2019-07-28 14:52:03 +02:00
Martin Kleusberg
189652d350 Remove some unnecessary includes 2019-04-29 20:54:26 +02:00
Martin Kleusberg
15c23bb0d3 Use some more SQL containers instead of their Qt equivalents 2019-04-29 18:11:19 +02:00
Martin Kleusberg
f59a2453a2 Fix some warning and other code style changes 2019-04-26 14:48:24 +02:00
Martin Kleusberg
fcac61da64 Simplify the WITHOUT ROWID code a bit
In the Table class we need to store whether this is a WITHOUT ROWID
table or now. Instead of just storing a boolean flag for that we were
storing a list of the rowid column(s). This is not just more complicated
to handle than a simple flag but also more error-prone because the list
must always be kept equal to the list of primary key columns. Failing to
keep them equal would result in an invalid SQL statement.
2019-04-03 12:19:53 +02:00
Martin Kleusberg
d1adac0a3b Activate one more test
Looks like we forgot about this when closing #1270.
2019-04-01 21:56:29 +02:00
Martin Kleusberg
e42b1e0716 Fix tests 2019-04-01 21:54:14 +02:00
Martin Kleusberg
7468bb2139 tests: Add test case for ee70a34ead
Add a test case for the bug which motivated disabling the window
function rules in ee70a34ead.

See issue #1733.
2019-02-09 13:33:56 +01:00
Martin Kleusberg
ed06c0289e Move query generation from SqliteTableModel into a separate class 2018-11-08 16:20:34 +01:00
Martin Kleusberg
35a5b43ce0 Move SQL object classes into a separate directory 2018-11-08 16:20:33 +01:00
Manuel
abb6f686a3 Initial implementation of "conditional formatting" (#1503)
After setting a filter, the user can select from the context menu in the
filter line a new option "Use for Conditional Format", that assigns
automatically a colour to the background of cells fulfilling that
condition.

The formatting is preserved after the user has removed the filter. Several
conditional formats can be successively added to a column using different
filters.

The conditional formats of a column can be cleared when the filter is empty
selecting "Clear All Conditional Formats" from the filter line context
menu.

The conditional formats are saved and loaded in project files as other
browse table settings.

A new class Palette has been added for reusing the automatic colour
assignment of the Plot Dock. It takes into account the theme kind of the
application (dark, light) for the colour selection.

A new class CondFormat for using the conditional formatting settings from
several classes. The conversion of a filter string from our format to an
SQL condition has been moved here for reuse in filters and conditional
formatting.

Whether the conditional format applies is resolved by SQLite, so filters
and conditional formats give the same exact results.

Code for getting a pragma value has been reused for getting the condition
result, and consequently renamed to selectSingleCell.

Possible future improvement:
- New dialog for editing the conditional formatting (at least colour and
application order of conditions, but maybe too: adding new conditions and
editing the condition itself).
2018-10-30 21:22:14 +01:00
Martin Kleusberg
3f8fc34394 tests: Remove broken test
SQLite doesn't even allow the statement we're checking for, so let's
remove it.
2018-09-28 17:25:39 +02:00
Martin Kleusberg
918248acaa Simplify code 2018-09-26 15:54:39 +02:00
Martin Kleusberg
bf505edf66 Code refactoring
This commit refactors vast parts of the sqlitetypes.h interface. Its
main goals are: less code, easier code, a more modern interface, reduced
likelihood for strange errors and more flexibility for future
extensions.

The main reason why the sqlitetypes.h functions were working so well in
DB4S was not because they were that stable but because they were
extremely interlinked with the rest of the code. This is fine because we
do not plan to ship them as a separate library. But it makes it hard to
find the obvious spot to fix an issue or to put a new function. It can
always be done in the sqlitetypes function or in the rest of the DB4S
code because it is just not clear what the interface between the two
should look like. This is supposed to be improved by this commit. One
main thing here is to make ownership of objects a bit clearer.

In theory the new code should be faster too but that difference will be
neglectable from a user POV.

This commit also fixes a hidden bug which caused all table constraints
to be removed in the Edit Table dialog when a single field was removed
from the table.

This is all still WIP and more work is needed to be done here.
2018-09-05 22:24:46 +02:00
Martin Kleusberg
9d4c20e603 Try to fix building the tests on older Qt versions 2018-07-14 15:55:49 +02:00
Martin Kleusberg
dbd2d648d8 tests: Better error messages
Show better error messages for failing tests.
2018-07-13 17:05:54 +02:00
Martin Kleusberg
c150d1a766 grammar: Fix row value parsing, improve whitespace handling, fix tests
This commit fixes a regression which was introduced in commit
788134eee6 which broke the parsing of row
values.

It also makes sure CHECK expressions are parsed in exactly the same way,
no matter whether they are a column or a table constraint. Before spaces
were added to the query in a different way. The way it was done for
column constaints had also an error were the minus sign of a negative
number was separated from the first digit by a space. This is fixed,
too.

Because of all the changes this commit also adjusts the tests to expect
the new layout of the check expressions. It also adds some new tests for
row values and for complex expressions to make sure both work. Finally,
it also removes all QScintilla dependencies from the tests which don't
seem to be necessary.
2018-07-13 16:54:43 +02:00
Iulian Onofrei
961141ec36 Replace deprecated qt5_use_modules function (#1419)
* Replace deprecated qt5_use_modules function

* Fix includes that fall under a larger module

* Bump minimum Cmake version to use newer features and properly use libs

* Replace deprecated qt5_use_modules function and bump minimum CMake version to 3.1.0 for 3rd party libraries
2018-07-10 20:57:55 +02:00
Iulian Onofrei
3cdc65a63f Add automatic crypted databases open via dotenvs (#1404)
* Rename confusing variables

* Fix some project warnings

* Fix code style

* Add constant for the default page size

* Move KeyFormats enum to CipherSettings

* Fix code style

* Fix memory leak

* Stop relying on CipherDialog for encryption settings management

* Fix code style

* Add .env format for QSettings

* Add automatic crypted databases open via dotenvs

This adds support for `.env` files next to the crypted databases that
are to be opened that contains the needed cipher settings.

The only required one is the plain-text password as a value for the key
with the name of the database like this:

    myCryptedDatabase.sqlite = MyPassword

This way, databases with a different extension are supported too:

    myCryptedDatabase.db = MyPassword

You can also specify a custom page size adding a different line
(anywhere in the file) like this:

    myCryptedDatabase.db_pageSize = 2048

If not specified, `1024` is used.

You can also specify the format of the specified key using the
associated integer id:

    anotherCryptedDatabase.sqlite = 0xCAFEBABE
    anotherCryptedDatabase.sqlite_keyFormat = 1

where `1` means a Raw key. If not specified, `0` is used, which means a
simple text Passphrase.

Dotenv files (`.env`) are already used on other platforms and by
different tools to manage environment variables, and it's recommended
to be ignored from version control systems, so they won't leak.

* Add new files to CMakeLists

* Move DotenvFormat include to the implementation

* Fix build error

* Remove superfluous method

(related to ac51c23)

* Remove superfluous checks

* Fix memory leaks

(introduced by 94bbb46)

* Fix code style

* Make dotenv related variable and comment clearer

* Remove duplicated code

* Remove unused forward declaration

(introduced by e5a0293)
2018-07-10 20:46:17 +02:00
mgrojo
2803e163e0 New tests for the new standard quoting and for the other quoting styles
Modified some tests for taking into account the new standard quoting and
added some more for testing the quoting configuration and for correct
parsing of different quoting styles.

Default branch in escapeIdentifier() for trying to avoid warning.
2018-06-23 17:57:18 +02:00
Martin Kleusberg
3da520cdd1 Clean up multi threading patch, fix build and some bugs
Make strings translatable, remove some more debug code, fix tests,
reduce size of patch slightly, remove weird tooltip, don't crash when
closing database, simplify code, fix filters, don't link agains pthread
on Windows.
2018-06-08 22:46:47 +02:00
Martin Kleusberg
51dbe72e23 Multi-threading patch
This was done by Michael Krause.
https://lists.sqlitebrowser.org/pipermail/db4s-dev/2018-February/000305.html

In this commit I only fixed two compiler warnings, some whitespace
issues and removed some debug messages.
2018-06-08 22:46:47 +02:00
Martin Kleusberg
652637232d Add tests 2018-01-05 18:20:28 +01:00
Martin Kleusberg
8f0312487f Fix cmake build 2018-01-01 15:17:22 +01:00
Jiří Techet
18bcbf138f Fix extra spaces in type definitions with parentheses
At the moment space is inserted between all tokens from which a type
consists. This adds extra spaces to types like VARCHAR(5) which become
"VARCHAR ( 5 )" which causes problems in some applications.

This patch modifies the way tokens are concatenated for a type. It makes
sure that the extra space isn't inserted before "(" and ")" and also
after "(".
2017-09-22 20:10:09 +02:00
Martin Kleusberg
659f38ebef Increase CSV parser performance 2017-09-18 15:10:43 +02:00
Martin Kleusberg
0eb1f65798 Optimise the CSV import performance
This commit bundles a number of smaller optimisations in the CSV parser
and import code. They do add up to a noticible speed gain though (at
least on some systems and configurations).
2017-09-13 15:03:13 +02:00
Martin Kleusberg
6ed8080fdb Don't parse entire CSV file before inserting the first row
We were separating the CSV import into two steps: parsing the CSV file
and inserting the parsed data. This had the advantages that it keeps the
parsing code and the database code nicely separated and that we have
full knowledge of the CSV file when we start inserting the data into the
database. However, this made it necessary to keep the entire parser
results in RAM. For large CSV files this uses enormous amounts of
memory.

This commit changes the import to parse the first 20 lines and analyse
them. This should give us a good impression of what to expect from the
rest of the file. Based on that information we then parse the file row
by row and insert each row into the database as soon as it is parsed.
This means we only have to keep one row at a time in memory while more
or less keeping the possibility to analyse the file before inserting
data.

On my system this does seem to change the runtime for small files which
take a little longer now (<5%), though these measurements aren't
conclusive. For large files it, however, it changes memory consumption
from using all memory and starting to swap within seconds to almost no
memory consumption at all. And not having to swap speeds things up a
lot.
2017-09-12 10:37:28 +02:00
Martin Kleusberg
b7a00d301a Don't track column count when parsing CSV files
When parsing a CSV file we used to check the column count for each row
and track the highest number of columns that we found. This information
then could be used to create an INSERT statement large enough for all
the data.

This column number tracking code is removed by this commit. Instead it
analyses the first 20 rows only. It does that while generating the field
list.

Performance-wise this should take a (very) little longer but makes it
easier to improve the performance in other ways later which should more
than compensate this commit.

Feature-wise this should fix some (technically invalid) corner-case CSV
files with fewer fields in the title row than in the other rows. It
should also break some other (technically invalid) corner-case CSV files
if they are imported into an existing table and have less columns than
the existing table in their first 20 rows but later on the exact same
number. Both cases, I think, don't matter too much.
2017-09-10 11:07:02 +02:00
Martin Kleusberg
1becee77ee tests: Add more regex tests 2017-08-10 21:39:51 +02:00
Martin Kleusberg
715074e0c6 Revert "tests: Fix build"
This reverts commit a436901d12.
2017-05-05 15:12:33 +02:00