Commit Graph

73 Commits

Author SHA1 Message Date
Martin Kleusberg
37a5645bf5 Fix some shadow warnings 2018-11-15 15:24:00 +01:00
Martin Kleusberg
5a1d338647 Allow specifying an ON CONFLICT strategy in the Import CSV dialog
Add a new dropdown box to the Import CSV dialog to set an ON CONFLICT
strategy when importing into an existing table. You can now choose
between the old and still default behaviour of aborting the import in
case of a conflict, ignoring the conflicting row from the CSV file, and
replacing the existing row in the table.

See issue #1585.
2018-10-24 13:38:28 +02:00
Martin Kleusberg
f11b1a0445 Better error handling in import CSV dialog
Make sure to show the correct error message when there is an error
during CSV import.

Make sure to release the DB handle used for the import before rolling
back to the last savepoint in case of an error in the CSV import. This
avoids a deadlock situation.

See issue #1590.
2018-10-23 19:52:34 +02:00
Martin Kleusberg
130afb1c08 Clean up code 2018-09-06 00:08:32 +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
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
3995ad2442 Add option to disable automatic type detection in CSV import
Because there are some circumstances under which the automatic type
detection can cause problems with the imported data and because it is
not accurate when the data changes a lot after the first couple of rows,
we need an option to disable it.

See issue #1382.
2018-05-25 22:11:43 +02:00
Martin Kleusberg
e851c161d6 Implement better default behaviour for CSV import
This changes the default behaviour for the CSV import to follow a set of
rules which hopefully makes most people happy.

It also add an "Advanced" section to the settings bits of the dialog to
modify this new default behaviour.

See issue #1395.
2018-05-25 21:06:16 +02:00
Remi Rampin
17f1eabb65 Import CSV: Add option to insert missing values as NULL (#1349)
* Add a combo box for missing values in import ui

* Add ui pieces to .cpp file

* Insert NULL values if requested

* Allow inserting NULLs in new table also
2018-05-22 20:56:11 +02:00
Martin Kleusberg
60ce9c869b Fix progress dialog for imports of very large CSV files
QProgressDialog only takes an int as the maximum value and the current
value. So using the number of bytes parsed so far isn't going to work
for very large files when an int will overflow. This commit changes this
by precalculating a progress indicator and handing that over to the
QProgressDialog object.

See issue #1212.
2017-11-02 22:56:39 +01:00
Martin Kleusberg
fae7235548 Fix regression introduced by 1ca92cdde3
Turns out this doesn work as expected. So we have to convert the
QVariant to int and then case it to char instead.
2017-11-02 22:39:31 +01:00
Martin Kleusberg
8ad34abb06 Simplify code 2017-10-31 12:14:29 +01:00
Martin Kleusberg
1ca92cdde3 Use our Settings class everywhere
Don't use the QSettings class directly. This keeps the code more
consistent and makes it a bit easier to read. It also means that all
parts of the code profit from the settings cache that we have
implemented in the Settings class.
2017-10-30 13:37:34 +01:00
Martin Kleusberg
3bd2dc3bc1 Replace 'foreach' by range-based for loop from C++11 2017-10-30 13:10:08 +01:00
Martin Kleusberg
1666bb5606 Improve speed of preview table for large fields in Import CSV dialog
See issue #720.
2017-09-29 23:21:39 +02:00
Martin Kleusberg
bbc4ad5b19 Don't reset the table name as easily in the Import CSV dialog
See issue #1072.
2017-09-29 23:08:39 +02:00
Martin Kleusberg
cbd5d15cf5 Add a way to cancel the entire CSV import
See issue #1121.
2017-09-27 20:59:30 +02:00
Martin Kleusberg
425bfa1e75 Improve 'Yes for all' button in CSV import dialog
See issue #1121.
2017-09-27 15:52:34 +02:00
Martin Kleusberg
d2185d234b csv: Don't ask whether to import into existing table every time
Add a 'Yes for all' button to the "There is already a table of
that name..." message box in the Import CSV dialog.

See issue #1121.
2017-09-27 14:18:38 +02:00
Martin Kleusberg
8f82f26d4f Visual optimisation for the CSV import process
When importing multiple CSV files at once, remove each entry from the
list of CSV files as its import completes. This way people can see the
list shrink visibly onscreen.

Also don't close the window if there are still files left to be
imported. This allows the user to import unchecked files, too, probably
using different settings.

See issue #1072.
2017-09-19 21:43:30 +02:00
Martin Kleusberg
2f304e0957 Add automatic data type detection to the CSV import
When importing a CSV file into a table that doesn't exist yet (i.e. that
is created during the import), try to guess the data type of each column
based on the first couple of rows. If it is all floats or mixed floats
and integers, set the data type to REAL; if it is all integers, set the
data type to INTEGER; if it is anything else, set the data type to TEXT.

See issue #1003.
2017-09-18 21:44:34 +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
8c47c6d668 Add very basic performance measurement to the Import CSV dialog 2017-09-07 22:26:32 +02:00
Martin Kleusberg
6432517805 Use a prepared statement for all records during the CSV import
Don't build a separate SQL statement per row to insert during CSV import
but use a single prepared statement which can be reused for each row.
This should speed up the CSV import noticeably.
2017-09-06 20:38:24 +02:00
Martin Kleusberg
532fcd3f6b Add initial support for multiple database 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.
2017-09-03 13:22:21 +02:00
Martin Kleusberg
abd7d4e689 When importing CSV data into existing tables, don't insert empty strings
When importing a CSV file into an existing table (i.e. a table where we
have a table schema), check the data type of a field before inserting
empty values. If it is an integer field, don't insert empty string like
we did before but 0 or NULL depending on the NOT NULL flag.

See issue #195.

Please note that this isn't perfect. The preview in the dialog doesn't
reflect these changes yet, it just show you the contents of the file as
is. It's a little tricky to change this and I somehow think it's better
the way it is now anyway. Also the import doesn't check for other
constraints like UNIQUE or CHECK which might cause trouble. But then
again it didn't do that before either.
2017-06-29 22:22:57 +02:00
Martin Kleusberg
a92a32157a Fix two problems in the CSV import
When importing a CSV file and using the first row as the field names,
the row would be imported as the first data row again. It's now skipped
when the checkbox is set.

When importing a single CSV file the checkbox asking whether to import
into a single table or separate tables is hidden. However, the last set
values are loaded anyway when the dialog is opened. This means the
checkbox could be set, even though it's invisible. If it's set, however,
and we're importing a single CSV file this would mean that it's
impossible to manually set the table name to import into. This is fixed,
too.

Also this simplifies the code a bit and removed a large loop from the
import dialog code.
2017-06-29 00:19:08 +02:00
iKlsR
357faeed04 Allow specifying unique table names for separate imports 2017-06-16 17:35:36 +02:00
iKlsR
97b4261190 Cleanup logic, code reuse, faster header picking 2017-06-16 17:35:36 +02:00
iKlsR
b5a2411eb6 Append Separate Tables state to import settings 2017-06-16 17:35:36 +02:00
iKlsR
225eb5ab5f Allow matching similar csv files for batch import 2017-06-16 17:35:36 +02:00
iKlsR
b0eb9acae2 Allow for interactive CSV file import
- Tweak input checker
- Preserve old file import as not to cause any unforeseen breaks
- Allow ignoring file name when importing multiple files to tables
- Mass toggle several files for import
2017-06-16 17:35:36 +02:00
Martin Kleusberg
c68303478a Unify and (hopefully) simplify generation of savepoint names
This shouldn't change anything for the user.
2017-01-31 19:35:35 +01:00
Martin Kleusberg
38144bbcad Finish main part of the recent refactoring effort
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.
2017-01-23 20:59:12 +01:00
Martin Kleusberg
ebc3869627 Rename sqlb::Object::ObjectTypes enum to sqlb::Object::Types
The 'Object' parts seemed a little redundant before.
2017-01-23 13:44:36 +01:00
Martin Kleusberg
e5a79ec0fa Code refactoring
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.
2017-01-20 17:42:15 +01:00
Martin Kleusberg
d868f4c85d Make last database error message private
It's not supposed to be edited by anyone else.
2017-01-16 15:52:37 +01:00
Martin Kleusberg
85934dee77 Simplify code
This simplifies some of the super long iterator declarations by using
the auto keyword from C++11.
2016-10-18 20:07:48 +02:00
GeorgijK
9d7efcacfa Fixed bug issue #390 ("crash then correct table").
Some functions renamed for better readability.

See pull request #401.
2015-10-14 22:22:07 +02:00
Martin Kleusberg
631979c330 Improve escpaing support
When generating SQL statements properly escape all identifiers, even
those containing backticks which apparently are allowed inside
identifiers in SQLite.

See issue #387.
2015-08-17 00:17:48 +02:00
Martin Kleusberg
743bdf9941 Fix a few warnings 2015-07-06 22:48:18 +02:00
Martin Kleusberg
b08cead7c8 csvimport: Set filename as default table name
See issue #376.
2015-07-03 21:42:46 +02:00
Samir Aguiar
ca38995013 csvparser: Add support for old Mac OS line endings
In order to detect the CR characters, the file
must be opened in binary mode, otherwise QFile just
removes them all.

See issue #212.
2015-03-04 21:28:38 +01:00
Martin Kleusberg
3c243978e7 importcsv: Improve error messages a bit
Slightly improve the error messages shown when there is a problem during
the CSV import.

See issue #213.
2015-03-03 14:23:34 +01:00
Martin Kleusberg
d9da5dcd7f csvimport: Make default settings in code a little easier to understand 2014-11-08 12:17:56 +01:00
Martin Kleusberg
9ba36d02b2 Add initial SQLCipher support
Add some basic initial support for SQLCipher. Note that this is more of
a POC than a final implementation.

This commit adds an option called 'sqlcipher' to the cmake and qmake
projects which - when enabled - replaces the default SQLite3 include and
library files by their SQLCipher counter-parts. Especially on MacOS X
there might be some more work required in finding the correct include
paths. The SQLCipher library supports unencrypted databases, too, so
even if the option is enabled the program behaves like before. You can
see the difference, though, in the About Dialog where the SQLite version
string will say 'SQLCipher version xy'.

When the sqlcipher option is enabled and you try to open a file which is
neither a project file nor a normal SQLite3 database it is assumed now
that the file is an encypted database. There is no way to tell between
an invalid file and an encypted file, so in both cases a password dialog
pops up. When the correct password and page size are entered the file is
opened and can be edited like any other database before.

Creating encrypted databases isn't supported yet. So for testing you
need to fall back to the sqlcipher command line tool.

See issue #12.
2014-11-01 12:56:53 +01:00