Don't attempt to set an INTEGER PRIMARY KEY field to an empty string as
it will always result in a 'datatype mismatch' error by SQLite. Instead
set it to '0'.
See issue #859.
Add two new keyboard shortcuts for switching the currently selected
table in the Browse Data tab. These work as long as the table widget is
active. For now I have set them to Ctrl+PageUp and Ctrl+PageDown.
See issue #536.
This fixes the execution of those SQL scripts that by some way or
another are either containing or leading to empty commands. Most notably
this includes two consecurity semicolons and completely empty scripts.
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 fixes a crash that would happen if you click the Create Index
button while having opened an empty database file, i.e. without any
table to create an index on yet.
DB4S comes with its own default implementation for the REGEXP function.
This function, however, needs to be registered in order for SQLite to
use it. We did that when opening a database file but not when creating a
new database file, so regular expressions wouldn't work for newly
created databases like they did for existing ones. This is fixed by this
commit.
When exporting a database to an SQL file, output the CREATE statements
in a standardised format, including line breaks, indentation and proper
quoting. This requires our grammar parser to fully understand the schema
of a database object in order to make sure no information is lost during
the export. Because of this we fall back to the old way of doing this
for all database objects that couldn't be fully parsed.
See issue #629.
This fixes issues that assigning the main representation of the database
in DBBrowserDB::objectMap is modified when playing around with the
database in the Edit Table and Edit Index dialogs.
These bugs were caused by my refactoring. Let's hope there's not much
more fallout from this refactoring...
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.
In the SQL export don't use the base table name of a table when you
should actually use the table name itself. The way SQLite reports its
data these just happen to be the same for tables.
This doesn't change anything when it comes to functionality but is
semantically more correct.
Parsing views or generating a CREATE VIEW statement isn't implemented
yet.
Also unify the process by which it's possible to retrieve information on
the fields of a database object.
Simplify the code by storing the flag that indicates if the parsing was
successful in the parsed object itself instead of handing around pairs
of parsed objects and bools.
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.
When renaming a column of a table it might be necessary to recreate any
triggers nd indices referencing this column. There are several reasons
why this might fail and which are difficult to catch for us. For this
reason we just show an error message to the user in these cases so they
can fix the statements and run them manually. Previously to this commit
this error message contained a list of all SQL statements which were
tried to execute. So if you had 10 references to the table (not the
column!) and 7 of them could be recreated, the error message would still
have shown all 10 SQL statements. With this commit it only shows the
remaining 3 statements. This should make the dialog much easier to print
for large databases and makes it much easier for the user to grasp.
Suppose you have this database:
CREATE TABLE a(
x INTEGER,
y INTEGER
);
CREATE INDEX i ON a(x ASC);
Now, when trying to rename column x of table a to some other name using
the Edit Table dialog will work but index i will be lost during the
process. This is because it needs to be recreated after having modified
the table, however its create statement isn't valid anymore because the
column name x doesn't exist anymore. This is changed by this commit to
significantly increase the chance that renaming a column won't throw an
error, thus making the Edit Table dialog a lot safer to use.
Just like the Edit Table dialog, this dialog handles both creating and
editing. For consistency's sake this dialog is therefore renamed to Edit
Index dialog.
Improve the Create Index dialog so that it allows creating as well as
editing indices.
Chenge the code for the main window to allow editing existing indices.
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.
This adds a new class for indices, similar to the one for tables. This
class is supposed to make creating and editing indices a lot easier,
making all manual string concatenation unnecessary.
For now this is only used for simplifying the index creation procedure
in the Create Index dialog.