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.
Keep all the table and field information in a sqlb::Table object (which
itself is stored in DBBrowserObject) rather than storing field
information in DBBrowserObject and sqlb::Table objects at the same time.
Get rid of the dependency to the MainWindow class in the DBBrowserDB
class. It was only used for calling the log SQL and set database state
functions anyway. The same result can be achieved emitting Qt slots.
When closing the database, either by using the menu item or by closing
the window, the user is asked whether the changes he made shall be
saved or not. Add a third button to this message box which makes it
possible to cancel the action.
Add two buttons to move the currently selected field up or down to allow
changing the field order of a table.
Extend the DBBrowserDB::renameColumn() method to support changing the
position of a field.
Delete the getTableSQL() method in DBBrowserDB. Because we reload and
store the SQL statements for tables after every change to the DB layout
we can just use these strings instead of having an extra function doing
an extra DB query. This simplifies the code a bit and also reduces the
number of SQL statements executed by the application.