When exporting a database to an SQL file we used to export it like this:
- Table 1 schema
- Table 1 data
- Table 2 schema
- Table 2 data
With this commit that is changed like this:
- Table 1 schema
- Table 2 schema
- Table 1 data
- Table 2 data
This makes the resulting SQL file more robust for import because it
avoids any foreign key errors as long as foreign keys are deferred.
Fix our default collation which we install when an unknown collation is
requested to (more or less) support UTF16 strings as well. Before this
UTF16 strings wouldn't compare correctly because they might contain null
bytes which would lead to only the first (few) byte(s) getting compared.
See issue #1172.
The no collate function warning is triggered in a thread which is used
for loading data. However, the warning is a message box and GUI elements
can only be drawn in the main thread. So the old code would crash. This
is fixed here by jumping to the main thread for showing the message box.
This improves the Edit Table dialog to better handle moving tables from
one schema to another, though the UI currently only knows about the main
and the temp schema.
This also simplifies the grammar code by removing the temporary flag
from all classes because it's redundant now that we support multiple
schemata.
This adds initial basic support for handling different database schemata
at once to the backend code. This is still far from working properly but
shouldn't break much either - mostly because it's not really used yet in
the user interface code.
This adds a new context menu option that allows unlocking views for
updating. This requires appropriate triggers to be in place and the user
to type in a column name that can be used as a 'primary key' for the
view. By default views are still locked from editing.
Inserting into and deleting from views isn't supported yet.
See issue #141.
When possible, don't write 'CREATE TABLE/VIEW/... `name`' but 'CREATE
TABLE/VIEW/... IF NOT EXISTS `name`' to the file.
Add an option to add DROP TABLE statements before each create statement.
This needs to be enhanced to apply to views, indices, and triggers as
well. See issue #629.
Clean up code.
This improves the error handling when executing multiple SQL commands at
once in a couple of ways.
We didn't detect any sort of possible error. For example syntax error
were reported and execution stopped but constraint errors were just
silently ignored. This is fixed now so that no silent errors should
occur.
Also we would execute the statements one after another until hitting an
error and then just stop, even if a savepoint was created before. With
this commit we're now reverting back to this savepoint and telling the
user about this. This should bring the database back to a consistent
state.
We have to remove any transaction statements from the SQL statements
because we're always already in a transactions and they can't be nested.
However, when removing a BEGIN TRANSACTION statement this would happen
silently and not in all cases a savepoint would be created instead. This
is fixed as well by making sure a savepoint is always created by this
function when a transaction was in the original list of commands.
See issues #955 and #957.
This finally gets rid of the DBBrowserObject class entirely and moves
all its functionality to the newer classes in the sqlb namespace.
I'm still not entirely happy with this but at least things should be a
little more consistent now.
This changes the class structure in the sqlb namespace as well as the
DBBrowserObject class. The rest of the commit are changes that are
required by the modifications in sqlb and DBBrowserObject.
The idea behind this refactoring is this: we currently have the
DBBrowserObject class which holds some basic information about the
database object (name, type, SQL string, etc.). It also contains a
sqlb::Table and a sqlb::Index object. Those are used if the type of
the object is table or index and they contain a whole lot more
information on the object than the DBBrowserObject class, including the
name, the type, the SQL string, etc.
So we have a duplication here. There are two class structures for
storing the same information. This has historic reasons but other than
that there is no point in keeping it this way. With this commit I start
the work of consolidating the sqlb classes in order to get rid of the
DBBrowserObject class entirely.
This commit only starts this task, it doesn't finish it. This is why it
is a little messy here and there, but then again the old structure was a
little messy, too. We will need at least a very basic trigger and view
parser before finishing this is even possible. When this is done, I hope
the ode will be much easier to read and understand. But even in the
current state there already is some progress: we save a little bit of
memory, don't copy big objects all the time anymore, and replace a lot
of unnecessary string comparisons with integer comparisons.
This commit adds support for CREATE INDEX statements to our grammar
parser. The new parser is called for each index when reloading the
database schema. However, the resulting index representation isn't used
yet. Also note that this duplicates some code, though not much. The idea
is to consolidate this later in a way that includes triggers and views
as well.
You can create temporary table using CREATE TEMPORARY TABLE xxx
statements. DB4S shows them as ordinary tables which is fine most of the
time. However, it wouldn't remember the temporary status when editing
them via the Edit Table dialog. This means that editing them would
create a normal, non-temporary table. This is fixed by this commit.
Renaming a table always happens *after* editing all table columns (at
least that's the order we're doing it currently). So for all
renameColumn() names we'll need to use the table name as it is in the
database, *not* as it is in the table name widget because that might
have been changed in the meantime.
We used to reload the database schema whenever it might have been
changed and the latest version was required. For example: when the user
switches to the Structure tab we need the current schema; so we just
reloaded it to be safe - it might have been changed in the Execute SQL
tab or wherever.
With this commit we don't reload the database schema anymore when an
up-to-date version is needed but instead when it was changed by the
application. So in the example above it's not reloaded at all anymore.
Only if and when the user would execute some structure changing SQL it
would be reloaded.
Benefits:
- Better performance
- State of the structure tree view isn't lost as frequently
- Structure tree view gets updated when changing the structure in the
Execute SQL tab
Downsides:
- Less error proof (testing!)
- No 'automatic' updates when the db is changed by an external
application.
Any suggestions welcome!
When opening a read only database file show a 'Read only' note in the
status bar of the main window and disable all editing buttons in the UI.
See issue #402.
Add support for non-integer primary keys, especially on table without
rowid column. The previous code often assumed that the rowid column or
its equivalent was a 64bit integer but SQLite allows any data, including
text, to be stored in there.
See issue #240.
Remove the DBBrowserDB::tableColumns() method which queries the database
for the column names of a given table and which is used for the SQL
export only. This function isn't needed at all because it generates a
whole bunch of queries for data which is already hold in memory...
This improves commit c20c58595a to
definitely make sure the primary key values are stored and handled
correctly by simply using the same data type as SQLite itself does.
Primary keys in SQLite are 64bit in size. We, however, used the int
datatype which often is 32bit only. Also the conversion from QString and
other Qt datatypes to numbers was done by the toInt() method which fails
on these large numbers. These issues are fixed by this commit, adding
support for databases with big primary key values.
See issue #172.
When attaching another database, SQLCipher assumes that it shares
passphrase and salt with the main database. Usually this isn't the case,
though. With this commit SQLiteBrowser tries to open the database to attach
before actually attaching it and asks for encryption details if needed.
This allows the user to attach unencrypted databases to an encrypted
master database and vice-versa. Note though, that attaching an encrypted
database with a non-default (i.e. <> 1024) cipher page size doesn't seem
to work - this however, is apparently a SQLCipher limitation.
See issue #174.