From 5d9314f134ddd3dc4c853e398ac90ba247fb2e4f Mon Sep 17 00:00:00 2001 From: Unit 193 Date: Mon, 13 Jun 2016 18:42:42 -0400 Subject: Imported Upstream version 3.1.0 --- SQLiteStudio3/Tests/ParserTest/tst_parsertest.cpp | 26 + SQLiteStudio3/Tests/TestUtils/dbattachermock.cpp | 5 + SQLiteStudio3/Tests/TestUtils/dbattachermock.h | 1 + SQLiteStudio3/Tests/TestUtils/dbmanagermock.cpp | 15 + SQLiteStudio3/Tests/TestUtils/dbmanagermock.h | 3 + SQLiteStudio3/coreSQLiteStudio/ChangeLog.txt | 62 + SQLiteStudio3/coreSQLiteStudio/TODO.txt | 21 +- .../coreSQLiteStudio/common/bistrhash.cpp | 213 +++ SQLiteStudio3/coreSQLiteStudio/common/bistrhash.h | 213 +-- SQLiteStudio3/coreSQLiteStudio/common/sortedset.h | 64 + SQLiteStudio3/coreSQLiteStudio/common/strhash.h | 23 +- SQLiteStudio3/coreSQLiteStudio/common/utils.cpp | 43 +- SQLiteStudio3/coreSQLiteStudio/common/utils.h | 40 +- .../coreSQLiteStudio/common/utils_sql.cpp | 62 + SQLiteStudio3/coreSQLiteStudio/common/utils_sql.h | 4 + .../coreSQLiteStudio/coreSQLiteStudio.pro | 10 +- SQLiteStudio3/coreSQLiteStudio/csvserializer.cpp | 251 ++- SQLiteStudio3/coreSQLiteStudio/csvserializer.h | 7 + SQLiteStudio3/coreSQLiteStudio/db/abstractdb2.h | 4 +- SQLiteStudio3/coreSQLiteStudio/db/abstractdb3.h | 23 +- .../coreSQLiteStudio/db/chainexecutor.cpp | 59 +- SQLiteStudio3/coreSQLiteStudio/db/chainexecutor.h | 13 + SQLiteStudio3/coreSQLiteStudio/db/db.cpp | 1 + SQLiteStudio3/coreSQLiteStudio/db/db.h | 3 +- .../coreSQLiteStudio/db/queryexecutor.cpp | 41 +- SQLiteStudio3/coreSQLiteStudio/db/queryexecutor.h | 5 +- .../queryexecutorsteps/queryexecutorcellsize.cpp | 35 +- .../db/queryexecutorsteps/queryexecutorcolumns.cpp | 13 +- .../db/queryexecutorsteps/queryexecutorexecute.cpp | 5 +- SQLiteStudio3/coreSQLiteStudio/dbattacher.h | 11 + .../coreSQLiteStudio/dbobjectorganizer.cpp | 47 +- SQLiteStudio3/coreSQLiteStudio/dbobjectorganizer.h | 1 + .../coreSQLiteStudio/dbversionconverter.cpp | 16 +- .../coreSQLiteStudio/dbversionconverter.h | 16 +- SQLiteStudio3/coreSQLiteStudio/exportworker.cpp | 7 +- .../coreSQLiteStudio/impl/dbattacherimpl.cpp | 19 +- .../coreSQLiteStudio/impl/dbattacherimpl.h | 2 + SQLiteStudio3/coreSQLiteStudio/importworker.cpp | 5 + SQLiteStudio3/coreSQLiteStudio/log.cpp | 28 +- SQLiteStudio3/coreSQLiteStudio/log.h | 5 + .../parser/ast/sqlitecreateindex.cpp | 55 +- .../parser/ast/sqlitecreateindex.h | 13 +- .../parser/ast/sqlitecreatetable.cpp | 22 +- .../parser/ast/sqlitecreatetable.h | 7 +- .../parser/ast/sqlitecreatetrigger.cpp | 10 + .../parser/ast/sqlitecreatetrigger.h | 5 +- .../parser/ast/sqlitecreateview.cpp | 29 +- .../coreSQLiteStudio/parser/ast/sqlitecreateview.h | 9 +- .../parser/ast/sqliteddlwithdbcontext.h | 16 + .../coreSQLiteStudio/parser/ast/sqliteexpr.cpp | 8 +- .../parser/ast/sqliteextendedindexedcolumn.h | 19 + .../parser/ast/sqliteindexedcolumn.cpp | 27 +- .../parser/ast/sqliteindexedcolumn.h | 8 +- .../coreSQLiteStudio/parser/ast/sqliteorderby.cpp | 82 + .../coreSQLiteStudio/parser/ast/sqliteorderby.h | 12 +- .../parser/ast/sqlitetablerelatedddl.h | 1 + .../coreSQLiteStudio/parser/ast/sqlitevacuum.cpp | 3 + SQLiteStudio3/coreSQLiteStudio/parser/lexer.cpp | 33 +- SQLiteStudio3/coreSQLiteStudio/parser/lexer.h | 9 + .../coreSQLiteStudio/parser/sqlite3_parse.cpp | 969 +++++------ .../coreSQLiteStudio/parser/sqlite3_parse.y | 7 +- .../parser/statementtokenbuilder.cpp | 2 +- SQLiteStudio3/coreSQLiteStudio/querygenerator.cpp | 275 +++ SQLiteStudio3/coreSQLiteStudio/querygenerator.h | 75 + SQLiteStudio3/coreSQLiteStudio/schemaresolver.cpp | 124 +- SQLiteStudio3/coreSQLiteStudio/schemaresolver.h | 5 + SQLiteStudio3/coreSQLiteStudio/selectresolver.cpp | 61 +- SQLiteStudio3/coreSQLiteStudio/selectresolver.h | 6 + .../coreSQLiteStudio/services/dbmanager.h | 6 +- .../services/impl/dbmanagerimpl.cpp | 42 +- .../coreSQLiteStudio/services/impl/dbmanagerimpl.h | 7 +- .../services/impl/pluginmanagerimpl.cpp | 15 +- .../services/impl/pluginmanagerimpl.h | 8 + SQLiteStudio3/coreSQLiteStudio/sqlitestudio.cpp | 2 +- SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp | 185 +- SQLiteStudio3/coreSQLiteStudio/tablemodifier.h | 50 +- .../translations/coreSQLiteStudio_de.qm | Bin 23 -> 45651 bytes .../translations/coreSQLiteStudio_de.ts | 112 +- .../translations/coreSQLiteStudio_es.ts | 110 +- .../translations/coreSQLiteStudio_fr.ts | 168 +- .../translations/coreSQLiteStudio_it.qm | Bin 0 -> 23 bytes .../translations/coreSQLiteStudio_it.ts | 110 +- .../translations/coreSQLiteStudio_pl.ts | 114 +- .../translations/coreSQLiteStudio_pt_BR.ts | 110 +- .../translations/coreSQLiteStudio_ru.ts | 110 +- .../translations/coreSQLiteStudio_sk.qm | Bin 4601 -> 6146 bytes .../translations/coreSQLiteStudio_sk.ts | 108 +- .../translations/coreSQLiteStudio_zh_CN.qm | Bin 16 -> 107 bytes .../translations/coreSQLiteStudio_zh_CN.ts | 110 +- SQLiteStudio3/create_macosx_bundle.sh | 31 +- SQLiteStudio3/create_win32_portable.bat | 2 +- .../common/centerediconitemdelegate.cpp | 35 + .../common/centerediconitemdelegate.h | 14 + .../guiSQLiteStudio/common/extlineedit.cpp | 9 +- SQLiteStudio3/guiSQLiteStudio/common/extlineedit.h | 1 + .../guiSQLiteStudio/common/exttableview.cpp | 14 + .../guiSQLiteStudio/common/exttableview.h | 15 + .../guiSQLiteStudio/common/exttablewidget.cpp | 15 + .../guiSQLiteStudio/common/exttablewidget.h | 15 + .../guiSQLiteStudio/common/numericspinbox.cpp | 9 + SQLiteStudio3/guiSQLiteStudio/configmapper.cpp | 112 +- SQLiteStudio3/guiSQLiteStudio/configmapper.h | 16 +- .../constraints/columndefaultpanel.cpp | 3 +- .../guiSQLiteStudio/datagrid/sqlqueryitem.cpp | 4 + .../datagrid/sqlqueryitemdelegate.cpp | 245 ++- .../datagrid/sqlqueryitemdelegate.h | 16 +- .../guiSQLiteStudio/datagrid/sqlquerymodel.cpp | 179 +- .../guiSQLiteStudio/datagrid/sqlquerymodel.h | 48 +- .../guiSQLiteStudio/datagrid/sqlqueryview.cpp | 113 +- .../guiSQLiteStudio/datagrid/sqlqueryview.h | 14 +- .../guiSQLiteStudio/datagrid/sqltablemodel.cpp | 38 + .../guiSQLiteStudio/datagrid/sqltablemodel.h | 5 + .../guiSQLiteStudio/datagrid/sqlviewmodel.cpp | 20 + .../guiSQLiteStudio/datagrid/sqlviewmodel.h | 18 + SQLiteStudio3/guiSQLiteStudio/dataview.cpp | 19 +- SQLiteStudio3/guiSQLiteStudio/dataview.h | 2 + SQLiteStudio3/guiSQLiteStudio/dbobjectdialogs.cpp | 107 ++ SQLiteStudio3/guiSQLiteStudio/dbobjectdialogs.h | 3 + SQLiteStudio3/guiSQLiteStudio/dbtree/dbtree.cpp | 232 ++- SQLiteStudio3/guiSQLiteStudio/dbtree/dbtree.h | 23 +- .../guiSQLiteStudio/dbtree/dbtreemodel.cpp | 36 +- SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.h | 1 + .../guiSQLiteStudio/dialogs/columndialog.cpp | 61 +- .../guiSQLiteStudio/dialogs/columndialog.h | 3 +- .../guiSQLiteStudio/dialogs/configdialog.cpp | 28 +- .../guiSQLiteStudio/dialogs/configdialog.h | 2 + .../guiSQLiteStudio/dialogs/configdialog.ui | 663 ++++--- SQLiteStudio3/guiSQLiteStudio/dialogs/dbdialog.cpp | 52 +- SQLiteStudio3/guiSQLiteStudio/dialogs/dbdialog.h | 2 + .../guiSQLiteStudio/dialogs/exportdialog.ui | 8 +- .../guiSQLiteStudio/dialogs/indexdialog.cpp | 564 +++++- .../guiSQLiteStudio/dialogs/indexdialog.h | 67 +- .../guiSQLiteStudio/dialogs/indexdialog.ui | 149 +- .../dialogs/indexexprcolumndialog.cpp | 151 ++ .../dialogs/indexexprcolumndialog.h | 47 + .../dialogs/indexexprcolumndialog.ui | 83 + SQLiteStudio3/guiSQLiteStudio/guiSQLiteStudio.pro | 17 +- SQLiteStudio3/guiSQLiteStudio/iconmanager.cpp | 1 + SQLiteStudio3/guiSQLiteStudio/iconmanager.h | 8 + SQLiteStudio3/guiSQLiteStudio/icons.qrc | 4 + SQLiteStudio3/guiSQLiteStudio/img/tag_hash_add.png | Bin 0 -> 825 bytes SQLiteStudio3/guiSQLiteStudio/img/tag_hash_del.png | Bin 0 -> 764 bytes .../guiSQLiteStudio/img/tag_hash_edit.png | Bin 0 -> 850 bytes SQLiteStudio3/guiSQLiteStudio/img/wand.png | Bin 0 -> 610 bytes SQLiteStudio3/guiSQLiteStudio/mainwindow.cpp | 29 +- SQLiteStudio3/guiSQLiteStudio/mainwindow.h | 1 + SQLiteStudio3/guiSQLiteStudio/sqleditor.cpp | 101 ++ SQLiteStudio3/guiSQLiteStudio/sqleditor.h | 6 +- SQLiteStudio3/guiSQLiteStudio/statusfield.cpp | 6 +- .../translations/guiSQLiteStudio_de.qm | Bin 23 -> 135940 bytes .../translations/guiSQLiteStudio_de.ts | 1824 ++++++++++++-------- .../translations/guiSQLiteStudio_es.ts | 1502 +++++++++------- .../translations/guiSQLiteStudio_fr.ts | 419 ++--- .../translations/guiSQLiteStudio_it.qm | Bin 0 -> 23 bytes .../translations/guiSQLiteStudio_it.ts | 1502 +++++++++------- .../translations/guiSQLiteStudio_pl.ts | 1581 ++++++++++------- .../translations/guiSQLiteStudio_pt_BR.ts | 1502 +++++++++------- .../translations/guiSQLiteStudio_ru.qm | Bin 148822 -> 147413 bytes .../translations/guiSQLiteStudio_ru.ts | 1506 ++++++++++------ .../translations/guiSQLiteStudio_sk.qm | Bin 95716 -> 101600 bytes .../translations/guiSQLiteStudio_sk.ts | 1633 +++++++++++------- .../translations/guiSQLiteStudio_zh_CN.qm | Bin 33797 -> 53694 bytes .../translations/guiSQLiteStudio_zh_CN.ts | 1516 +++++++++------- SQLiteStudio3/guiSQLiteStudio/uiconfig.h | 65 +- .../windows/tablestructuremodel.cpp | 26 +- .../guiSQLiteStudio/windows/tablewindow.cpp | 145 +- .../guiSQLiteStudio/windows/tablewindow.h | 14 +- .../guiSQLiteStudio/windows/tablewindow.ui | 18 +- .../guiSQLiteStudio/windows/viewwindow.cpp | 311 +++- SQLiteStudio3/guiSQLiteStudio/windows/viewwindow.h | 30 +- .../guiSQLiteStudio/windows/viewwindow.ui | 92 +- SQLiteStudio3/lang.tcl | 31 + SQLiteStudio3/sqlitestudio/main.cpp | 5 +- .../sqlitestudio/translations/sqlitestudio_de.qm | Bin 23 -> 2251 bytes .../sqlitestudio/translations/sqlitestudio_de.ts | 21 +- .../sqlitestudio/translations/sqlitestudio_es.ts | 15 +- .../sqlitestudio/translations/sqlitestudio_fr.ts | 2 +- .../sqlitestudio/translations/sqlitestudio_it.qm | Bin 0 -> 23 bytes .../sqlitestudio/translations/sqlitestudio_it.ts | 15 +- .../sqlitestudio/translations/sqlitestudio_pl.ts | 6 +- .../translations/sqlitestudio_pt_BR.ts | 15 +- .../sqlitestudio/translations/sqlitestudio_ru.ts | 15 +- .../sqlitestudio/translations/sqlitestudio_sk.ts | 15 +- .../translations/sqlitestudio_zh_CN.qm | Bin 16 -> 406 bytes .../translations/sqlitestudio_zh_CN.ts | 15 +- SQLiteStudio3/sqlitestudiocli/cli_config.cpp | 1 + SQLiteStudio3/sqlitestudiocli/climsghandler.cpp | 3 + .../translations/sqlitestudiocli_de.ts | 2 +- .../translations/sqlitestudiocli_es.ts | 2 +- .../translations/sqlitestudiocli_fr.ts | 116 +- .../translations/sqlitestudiocli_it.qm | Bin 0 -> 23 bytes .../translations/sqlitestudiocli_it.ts | 2 +- .../translations/sqlitestudiocli_pl.ts | 22 +- .../translations/sqlitestudiocli_pt_BR.ts | 2 +- .../translations/sqlitestudiocli_ru.qm | Bin 40196 -> 41595 bytes .../translations/sqlitestudiocli_sk.ts | 2 +- .../translations/sqlitestudiocli_zh_CN.qm | Bin 16 -> 1327 bytes .../translations/sqlitestudiocli_zh_CN.ts | 2 +- 198 files changed, 14806 insertions(+), 7337 deletions(-) create mode 100644 SQLiteStudio3/coreSQLiteStudio/common/bistrhash.cpp create mode 100644 SQLiteStudio3/coreSQLiteStudio/common/sortedset.h create mode 100644 SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteddlwithdbcontext.h create mode 100644 SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteextendedindexedcolumn.h create mode 100644 SQLiteStudio3/coreSQLiteStudio/querygenerator.cpp create mode 100644 SQLiteStudio3/coreSQLiteStudio/querygenerator.h create mode 100644 SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_it.qm create mode 100644 SQLiteStudio3/guiSQLiteStudio/common/centerediconitemdelegate.cpp create mode 100644 SQLiteStudio3/guiSQLiteStudio/common/centerediconitemdelegate.h create mode 100644 SQLiteStudio3/guiSQLiteStudio/common/exttableview.cpp create mode 100644 SQLiteStudio3/guiSQLiteStudio/common/exttableview.h create mode 100644 SQLiteStudio3/guiSQLiteStudio/common/exttablewidget.cpp create mode 100644 SQLiteStudio3/guiSQLiteStudio/common/exttablewidget.h create mode 100644 SQLiteStudio3/guiSQLiteStudio/datagrid/sqlviewmodel.cpp create mode 100644 SQLiteStudio3/guiSQLiteStudio/datagrid/sqlviewmodel.h create mode 100644 SQLiteStudio3/guiSQLiteStudio/dialogs/indexexprcolumndialog.cpp create mode 100644 SQLiteStudio3/guiSQLiteStudio/dialogs/indexexprcolumndialog.h create mode 100644 SQLiteStudio3/guiSQLiteStudio/dialogs/indexexprcolumndialog.ui create mode 100644 SQLiteStudio3/guiSQLiteStudio/img/tag_hash_add.png create mode 100644 SQLiteStudio3/guiSQLiteStudio/img/tag_hash_del.png create mode 100644 SQLiteStudio3/guiSQLiteStudio/img/tag_hash_edit.png create mode 100644 SQLiteStudio3/guiSQLiteStudio/img/wand.png create mode 100644 SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_it.qm create mode 100644 SQLiteStudio3/sqlitestudio/translations/sqlitestudio_it.qm create mode 100644 SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_it.qm (limited to 'SQLiteStudio3') diff --git a/SQLiteStudio3/Tests/ParserTest/tst_parsertest.cpp b/SQLiteStudio3/Tests/ParserTest/tst_parsertest.cpp index 4cec515..0dc58b0 100644 --- a/SQLiteStudio3/Tests/ParserTest/tst_parsertest.cpp +++ b/SQLiteStudio3/Tests/ParserTest/tst_parsertest.cpp @@ -20,6 +20,7 @@ class ParserTest : public QObject Parser* parser3 = nullptr; private Q_SLOTS: + void test(); void testUniqConflict(); void testGetTableTokens(); void testGetTableTokens2(); @@ -46,6 +47,31 @@ ParserTest::ParserTest() { } +void ParserTest::test() +{ + QString sql = "CREATE TRIGGER param_insert_chk_enum " + "BEFORE INSERT " + "ON param " + "WHEN new.type = 'enum' AND " + "new.defval IS NOT NULL AND " + "new.defval != '' " + "BEGIN " + "SELECT RAISE(FAIL, 'param_insert_chk_enum failed') " + "WHERE NOT EXISTS ( " + "SELECT val " + "FROM valset " + "WHERE param_id = new.param_id AND " + "val = new.defval " + "); " + "END;"; + + parser3->parse(sql); + QVERIFY(parser3->getErrors().size() == 0); + + SqliteQueryPtr query = parser3->getQueries()[0]; + TokenList tokens = query->getContextTableTokens(); +} + void ParserTest::testGetTableTokens() { QString sql = "select someTable.* FROM someTable;"; diff --git a/SQLiteStudio3/Tests/TestUtils/dbattachermock.cpp b/SQLiteStudio3/Tests/TestUtils/dbattachermock.cpp index 9f61d2d..32bfcaa 100644 --- a/SQLiteStudio3/Tests/TestUtils/dbattachermock.cpp +++ b/SQLiteStudio3/Tests/TestUtils/dbattachermock.cpp @@ -29,6 +29,11 @@ QString DbAttacherMock::getQuery() const return QString(); } +bool DbAttacherMock::getMainDbNameUsed() const +{ + return false; +} + DbAttacher* DbAttacherFactoryMock::create(Db*) { return new DbAttacherMock(); diff --git a/SQLiteStudio3/Tests/TestUtils/dbattachermock.h b/SQLiteStudio3/Tests/TestUtils/dbattachermock.h index b3ab345..c914acf 100644 --- a/SQLiteStudio3/Tests/TestUtils/dbattachermock.h +++ b/SQLiteStudio3/Tests/TestUtils/dbattachermock.h @@ -12,6 +12,7 @@ class DbAttacherMock : public DbAttacher void detachDatabases(); BiStrHash getDbNameToAttach() const; QString getQuery() const; + bool getMainDbNameUsed() const; }; class DbAttacherFactoryMock : public DbAttacherFactory diff --git a/SQLiteStudio3/Tests/TestUtils/dbmanagermock.cpp b/SQLiteStudio3/Tests/TestUtils/dbmanagermock.cpp index 7d286c4..926e57b 100644 --- a/SQLiteStudio3/Tests/TestUtils/dbmanagermock.cpp +++ b/SQLiteStudio3/Tests/TestUtils/dbmanagermock.cpp @@ -67,6 +67,21 @@ bool DbManagerMock::isTemporary(Db*) return false; } +DbPlugin* DbManagerMock::getPluginForDbFile(const QString&) +{ + return nullptr; +} + +QString DbManagerMock::generateUniqueDbName(const QString&) +{ + return QString(); +} + +QString DbManagerMock::generateUniqueDbName(DbPlugin*, const QString&) +{ + return QString(); +} + QString DbManagerMock::quickAddDb(const QString &, const QHash &) { return QString(); diff --git a/SQLiteStudio3/Tests/TestUtils/dbmanagermock.h b/SQLiteStudio3/Tests/TestUtils/dbmanagermock.h index 045991e..ce7eb51 100644 --- a/SQLiteStudio3/Tests/TestUtils/dbmanagermock.h +++ b/SQLiteStudio3/Tests/TestUtils/dbmanagermock.h @@ -21,6 +21,9 @@ class DbManagerMock : public DbManager Db*createInMemDb(); bool isTemporary(Db*); QString quickAddDb(const QString &path, const QHash &); + DbPlugin* getPluginForDbFile(const QString&); + QString generateUniqueDbName(const QString&); + QString generateUniqueDbName(DbPlugin*, const QString&); public slots: void notifyDatabasesAreLoaded(); diff --git a/SQLiteStudio3/coreSQLiteStudio/ChangeLog.txt b/SQLiteStudio3/coreSQLiteStudio/ChangeLog.txt index 38c2289..a477b8c 100644 --- a/SQLiteStudio3/coreSQLiteStudio/ChangeLog.txt +++ b/SQLiteStudio3/coreSQLiteStudio/ChangeLog.txt @@ -1,3 +1,65 @@ +[3.1.0] + * [ADDED]: SQLCipher plugin is now free, open source and distributed together with other standard plugins. + * [ADDED]: #2963 Indexed expressions for CREATE INDEX statements (introduced in SQLite 3.9) are now supported and can be edited in Index Dialog. + * [ADDED]: View window now supports explicit column names for the view (introduced in SQLite 3.9). + * [ADDED]: #3056 #3063 Implemented index column ordering in index dialog. + * [ADDED]: Added shortcut (Ctrl+/ by default) to toggle comment of current line or selected block of code (if any) in SQL editor. + * [ADDED]: #3040 Added new entry in context menu of data grid to generate SELECT/INSERT/UPDATE/DELETE statement together with WHERE clause containing IN conditions for selected cells. + * [ADDED]: Added new entry in context menu of database list to generate queries like in #3040 for selected table. + * [ADDED]: #2975 Information message after successful table/view change. + * [ADDED]: Introduced "loadByDefault" property for plugin descriptor files. + * [ADDED]: Added options to have "Data" tab placed as a first tab for Table windows and for View windows. By default option is disabled, so by default nothing changes. + * [ADDED]: Added option in configuration dialog to avoid reopening status panel for each message printed there. + * [ADDED]: Added option in configuration dialog to prevent displaying tooltips over data view when user holds mouse over it. + * [ADDED]: #3070 Added option in configuration dialog to have new databases marked as not permanent by default. + * [ADDED]: #3070 Added option in configuration dialog to bypass database dialog completely when dropping file from file manager onto database list. + * [ADDED]: #3013 When double clicking on empty space in list of indexes or tables (in table or view window) the action is not ignored, but a dialog opens for adding new item. + * [CHANGE]: DbAndroid plugin has now JAR file embedded and you can get it from Tools menu. + * [CHANGE]: SQLite version updated to 3.13.0. + * [CHANGE]: Qt version updated to 5.6.0. Should still compile with 5.3, but binary distributions on homepage will be made with 5.6. + * [CHANGE]: Foreign key dropdown (when editing FK cell) uses now more readable set of columns and column headers can be resized. + * [CHANGE]: Column dialog validates scale and precision fields (against INTEGER PRIMARY KEY and against each other). + * [CHANGE]: Structure tab in table window has now fully named headers in column list. + * [CHANGE]: Table and View window options moved from Look & Feel configuration page to Data Browsing page. + * [CHANGE]: All database list options moved to a separate Database List configuration page. + * [CHANGE]: Window list in main menu -> "View" -> "Window list" is not sorted alphabetically. + * [BUGFIX]: Not loading Android plugin by default (needs manual load from configuration dialog), which stops the "ADB" error for people not using the plugin. + * [BUGFIX]: #2927 Several critical bugs fixed and enhancements to table modification algorithm related to foreign keys. + * [BUGFIX]: #2954 #2803 #2937 Fixed incorrect recreation of foreign keys chain. + * [BUGFIX]: #3008 Editing foreign key cell with more than 10 000 possible values will now use simple text editor, not dropdown. It also loads values asynchronously. + * [BUGFIX]: Fixed importing from CSV with some of lines containing less fields than defined in header (or in first data row). + * [BUGFIX]: #2989 Fixed multiline value handling in CSV import plugin. + * [BUGFIX]: #2921 Fixed empty values as NULL handling in CSV import plugin. + * [BUGFIX]: #3034 Fixed handling empty string as value for DEFAULT constraint. + * [BUGFIX]: #3064 Fixed locking database executions when counting rows in huge tables. + * [BUGFIX]: DbAndroid plugin has fix for null pointer in the JAR when client has disconnected + * [BUGFIX]: Error message details were missing in some cases (when smart execution method failed at parsing stage). This is fixed now. + * [BUGFIX]: #3026 #3027 #3043 Fixed RAISE() function formatting in enterprise formatter (used to produce invalid SQL). + * [BUGFIX]: #3015 Fixed error with DEFAULT constraint containing datetime('now', 'localtime'). + * [BUGFIX]: #3000 Fixed compilation errors for Qt >= 5.5. + * [BUGFIX]: #2956 Fixed unexpected data refresh when clicking in the right side of value filter field in table window. + * [BUGFIX]: #2991 #2928 #2929 #2941 #2960 Fixed executing "garbage" query, causing application crash. + * [BUGFIX]: #2920 Fixed removing several databases. + * [BUGFIX]: #3068 #3066 Fixed database removal confirmation dialog so the message asks about removing it from the list, not deleting it. + * [BUGFIX]: #3073 Fixed crash when unloading plugin with its own configuration subpage and saving config dialog. + * [BUGFIX]: #2931 #2962 Fixed incorrect results when executing 2-level queries with an expression and an alias combination as a result column definition. + * [BUGFIX]: #2942 Fixed deleting multiple tables/indexes/... when selected them and picked "Delete table/index/..." from context menu. + * [BUGFIX]: #2945 Fixed manual reordering of database objects with Drag&Drop. + * [BUGFIX]: #3055 Fixed crash when exporting on MacOS using plugin that requires column value length information (such as PDF export plugin). + * [BUGFIX]: #3047 Fixed copying/moving tables together with indexes or triggers with Drag&Drop across same SQLite version databases. + * [BUGFIX]: #3012 SQL simple formatter plugin does not load by default from now on. It is still available, but won't load until manually loaded. + * [BUGFIX]: Table window for new table (just created) will now properly close when that table gets deleted immediately by the user. + * [BUGFIX]: #2998 Fixed reading decimal values from database when using simple execution method (a fallback in case of some problems). + * [BUGFIX]: #2999 Fixed working on objects from database that on the list is named "main". + * [BUGFIX]: Fixed error detection when selecting column from incorrect table alias (http://forum.sqlitestudio.pl/viewtopic.php?f=11&t=1051). + * [BUGFIX]: #3046 Fixed scale & precision fields in column dialog so it's possible to delete their values from the column. + * [BUGFIX]: Vacuum invoked from context menu on database list is now executed in SQL editor and is asynchronous. + * [BUGFIX]: #3001 Order of objects exported by Export Dialog is now alphabetical (in object type groups). + * [BUGFIX]: #3022 Fixed parsing of some expressions, resulting in this particular bug report in being unable to browse view results. + * [BUGFIX]: Enhanced floating point numbers handling. + * [BUGFIX]: Fixed formatting of INSERT and UPDATE statements. + * [BUGFIX]: Enterprise formatter no longer puts new lines when formating list of elements in "IN" clause. + [3.0.7] * [ADDED]: #2951 Implemented dropdown value picking for foreign key columns in grid view. * [ADDED]: Context menu entry to go to row in referenced table by current foreign key cell value. diff --git a/SQLiteStudio3/coreSQLiteStudio/TODO.txt b/SQLiteStudio3/coreSQLiteStudio/TODO.txt index 5c0f35c..4faac9d 100644 --- a/SQLiteStudio3/coreSQLiteStudio/TODO.txt +++ b/SQLiteStudio3/coreSQLiteStudio/TODO.txt @@ -1,16 +1,11 @@ -Thread 5 Crashed:: Thread (pooled) -0 libcoreSQLiteStudio.1.0.0.dylib 0x0000000101f24ba7 QHash::value(QString const&) const + 23 -1 libcoreSQLiteStudio.1.0.0.dylib 0x0000000101f24ad4 QHash::operator[](QString const&) const + 36 -2 libcoreSQLiteStudio.1.0.0.dylib 0x0000000101f24936 SqlResultsRow::value(QString const&) const + 54 -3 libcoreSQLiteStudio.1.0.0.dylib 0x0000000101f06c1a SchemaResolver::getAllObjects(QString const&) + 1178 -4 libcoreSQLiteStudio.1.0.0.dylib 0x0000000101f06746 SchemaResolver::getAllObjects() + 70 -5 libguiSQLiteStudio.1.0.0.dylib 0x000000010252f428 SqlEditor::refreshValidObjects()::$_0::operator()() const + 456 (sqleditor.cpp:529) -6 libguiSQLiteStudio.1.0.0.dylib 0x000000010252f1ec QtConcurrent::StoredFunctorCall0::runFunctor() + 28 (qtconcurrentstoredfunctioncall.h:72) -7 libguiSQLiteStudio.1.0.0.dylib 0x0000000102534ca1 QtConcurrent::RunFunctionTask::run() + 81 (qtconcurrentrunbase.h:132) -8 libguiSQLiteStudio.1.0.0.dylib 0x0000000102534dbc non-virtual thunk to QtConcurrent::RunFunctionTask::run() + 28 (qtconcurrentrśunbase.h:141) +cannot reproduce: +2922 / 2926 / 2925 +2940 +3009 - db w emailu od goretux@gmail.com +3052 +3062 - -* Outstanding features for 3.1: +* Outstanding features for 3.2: - migrate updates engine to Qt Install Framework - loadable extensions full support - BLOB preview engine based on plugins @@ -51,6 +46,8 @@ Thread 5 Crashed:: Thread (pooled) - executing queries with bind parameters - completer: when suggesting table in FROM clause, look at columns after SELECT to give related tables first. - constraints tab in table window should have toolbar for adding/editing/deleting constraints +- add menu mnemonics support (underlined shortcut letters) +- per column filtering field when clicked on column header(?) CLI: - plugin management commands diff --git a/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.cpp b/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.cpp new file mode 100644 index 0000000..091121c --- /dev/null +++ b/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.cpp @@ -0,0 +1,213 @@ +#include "bistrhash.h" + +BiStrHash::BiStrHash(std::initializer_list > list) +{ + hash = QHash(list); + initInvertedAndLower(); +} + +BiStrHash::BiStrHash(const QHash& other) +{ + unite(other); +} + +BiStrHash::BiStrHash(const BiStrHash& other) : hash(other.hash), inverted(other.inverted), + lowerHash(other.lowerHash), lowerInverted(other.lowerInverted) +{ +} + +void BiStrHash::insert(const QString& left, const QString& right) +{ + if (lowerHash.contains(left.toLower())) + removeLeft(left, Qt::CaseInsensitive); + + if (lowerInverted.contains(right.toLower())) + removeRight(right, Qt::CaseInsensitive); + + inverted.insert(right, left); + hash.insert(left, right); + lowerHash.insert(left.toLower(), left); + lowerInverted.insert(right.toLower(), right); +} + +bool BiStrHash::containsLeft(const QString& left, Qt::CaseSensitivity cs) +{ + if (cs == Qt::CaseSensitive) + return hash.contains(left); + else + return lowerHash.contains(left.toLower()); +} + +bool BiStrHash::containsRight(const QString& right, Qt::CaseSensitivity cs) +{ + if (cs == Qt::CaseSensitive) + return inverted.contains(right); + else + return lowerInverted.contains(right.toLower()); +} + +int BiStrHash::removeLeft(const QString& left, Qt::CaseSensitivity cs) +{ + if (cs == Qt::CaseSensitive) + { + if (!hash.contains(left)) + return 0; + + inverted.remove(hash.value(left)); + hash.remove(left); + + return 1; + } + else + { + QString lowerLeft = left.toLower(); + if (!lowerHash.contains(lowerLeft)) + return 0; + + QString right = hash.value(lowerHash.value(lowerLeft)); + + hash.remove(inverted.value(right)); + inverted.remove(right); + lowerHash.remove(lowerLeft); + lowerInverted.remove(right.toLower()); + + return 1; + } +} + +int BiStrHash::removeRight(const QString& right, Qt::CaseSensitivity cs) +{ + if (cs == Qt::CaseSensitive) + { + if (!inverted.contains(right)) + return 0; + + hash.remove(inverted.value(right)); + inverted.remove(right); + + return 1; + } + else + { + QString lowerRight = right.toLower(); + if (!lowerInverted.contains(lowerRight)) + return 0; + + QString left = inverted.value(lowerInverted.value(lowerRight)); + + inverted.remove(hash.value(left)); + hash.remove(left); + lowerHash.remove(left.toLower()); + lowerInverted.remove(lowerRight); + + return 1; + } +} + +QString BiStrHash::takeLeft(const QString& left, Qt::CaseSensitivity cs) +{ + if (cs == Qt::CaseSensitive) + { + QString right = hash.take(left); + inverted.remove(right); + return right; + } + else + { + QString right = hash.take(lowerHash.take(left.toLower())); + inverted.remove(lowerInverted.take(right.toLower())); + return right; + } +} + +QString BiStrHash::takeRight(const QString& right, Qt::CaseSensitivity cs) +{ + if (cs == Qt::CaseSensitive) + { + QString left = inverted.take(right); + hash.remove(left); + return left; + } + else + { + QString left = inverted.take(lowerInverted.take(right.toLower())); + hash.remove(lowerHash.take(left.toLower())); + return left; + } +} + +BiStrHash& BiStrHash::unite(const BiStrHash& other) +{ + unite(other.hash); + return *this; +} + +BiStrHash& BiStrHash::unite(const QHash& other) +{ + QHashIterator it(other); + while (it.hasNext()) + insert(it.next().key(), it.value()); + + return *this; +} + +QString BiStrHash::valueByLeft(const QString& left, Qt::CaseSensitivity cs) const +{ + if (cs == Qt::CaseSensitive) + return hash.value(left); + else + return hash.value(lowerHash.value(left.toLower())); +} + +QString BiStrHash::valueByRight(const QString& right, Qt::CaseSensitivity cs) const +{ + if (cs == Qt::CaseSensitive) + return inverted.value(right); + else + return inverted.value(lowerInverted.value(right.toLower())); +} + +QStringList BiStrHash::leftValues() const +{ + return hash.keys(); +} + +QStringList BiStrHash::rightValues() const +{ + return inverted.keys(); +} + +QHashIterator BiStrHash::iterator() const +{ + return QHashIterator(hash); +} + +void BiStrHash::clear() +{ + hash.clear(); + inverted.clear(); + lowerHash.clear(); + lowerInverted.clear(); +} + +int BiStrHash::count() const +{ + return hash.count(); +} + +bool BiStrHash::isEmpty() const +{ + return hash.isEmpty(); +} + +void BiStrHash::initInvertedAndLower() +{ + QHashIterator it(hash); + while (it.hasNext()) + { + it.next(); + inverted[it.value()] = it.key(); + lowerHash[it.key().toLower()] = it.key(); + lowerInverted[it.value().toLower()] = it.value(); + } +} diff --git a/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.h b/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.h index 65c907b..2089010 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.h +++ b/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.h @@ -2,6 +2,7 @@ #define BISTRHASH_H #include "bihash.h" +#include "coreSQLiteStudio_global.h" #include #include @@ -14,7 +15,7 @@ * * Just like BiHash, the BiStrHash doesn't provide operator[]. For more details see BiHash. */ -class BiStrHash +class API_EXPORT BiStrHash { public: /** @@ -26,11 +27,7 @@ class BiStrHash * @brief Creates pre-initialized hash. * @param list C++11 style initializer list, like: {{"x"="y"}, {"a"="b"}} */ - BiStrHash(std::initializer_list> list) - { - hash = QHash(list); - initInvertedAndLower(); - } + BiStrHash(std::initializer_list> list); /** * @brief Creates BiStrHash basing on QHash. @@ -39,17 +36,13 @@ class BiStrHash * Any conflicting values from the \p other hash will overwrite * current values in the hash. */ - BiStrHash(const QHash & other) - { - unite(other); - } + BiStrHash(const QHash & other); /** * @brief Copy constructor. * @param other Other hash to copy. */ - BiStrHash(const BiStrHash& other) : hash(other.hash), inverted(other.inverted), - lowerHash(other.lowerHash), lowerInverted(other.lowerInverted) {} + BiStrHash(const BiStrHash& other); /** * @brief Inserts entry into the hash. @@ -59,19 +52,7 @@ class BiStrHash * Inserting to the hash is done in case-insensitive manner, hence any conflicting * values matched with case insensitive method will be replaced with the new entry. */ - void insert(const QString& left, const QString& right) - { - if (lowerHash.contains(left.toLower())) - removeLeft(left, Qt::CaseInsensitive); - - if (lowerInverted.contains(right.toLower())) - removeRight(right, Qt::CaseInsensitive); - - inverted.insert(right, left); - hash.insert(left, right); - lowerHash.insert(left.toLower(), left); - lowerInverted.insert(right.toLower(), right); - } + void insert(const QString& left, const QString& right); /** * @brief Tests if given value is in the left values of the hash. @@ -79,13 +60,7 @@ class BiStrHash * @param cs Case sensitivity flag. * @return true if the key was matched in left side values, or false otherwise. */ - bool containsLeft(const QString& left, Qt::CaseSensitivity cs = Qt::CaseSensitive) - { - if (cs == Qt::CaseSensitive) - return hash.contains(left); - else - return lowerHash.contains(left.toLower()); - } + bool containsLeft(const QString& left, Qt::CaseSensitivity cs = Qt::CaseSensitive); /** * @brief Tests if given value is in the right values of the hash. @@ -93,13 +68,7 @@ class BiStrHash * @param cs Case sensitivity flag. * @return true if the key was matched in right side values, or false otherwise. */ - bool containsRight(const QString& right, Qt::CaseSensitivity cs = Qt::CaseSensitive) - { - if (cs == Qt::CaseSensitive) - return inverted.contains(right); - else - return lowerInverted.contains(right.toLower()); - } + bool containsRight(const QString& right, Qt::CaseSensitivity cs = Qt::CaseSensitive); /** * @brief Removes entry matching given value in left-side values. @@ -107,34 +76,7 @@ class BiStrHash * @param cs Case sensitivity flag. * @return Number of entries removed. */ - int removeLeft(const QString& left, Qt::CaseSensitivity cs = Qt::CaseSensitive) - { - if (cs == Qt::CaseSensitive) - { - if (!hash.contains(left)) - return 0; - - inverted.remove(hash.value(left)); - hash.remove(left); - - return 1; - } - else - { - QString lowerLeft = left.toLower(); - if (!lowerHash.contains(lowerLeft)) - return 0; - - QString right = hash.value(lowerHash.value(lowerLeft)); - - hash.remove(inverted.value(right)); - inverted.remove(right); - lowerHash.remove(lowerLeft); - lowerInverted.remove(right.toLower()); - - return 1; - } - } + int removeLeft(const QString& left, Qt::CaseSensitivity cs = Qt::CaseSensitive); /** * @brief Removes entry matching given value in right-side values. @@ -142,34 +84,7 @@ class BiStrHash * @param cs Case sensitivity flag. * @return Number of entries removed. */ - int removeRight(const QString& right, Qt::CaseSensitivity cs = Qt::CaseSensitive) - { - if (cs == Qt::CaseSensitive) - { - if (!inverted.contains(right)) - return 0; - - hash.remove(inverted.value(right)); - inverted.remove(right); - - return 1; - } - else - { - QString lowerRight = right.toLower(); - if (!lowerInverted.contains(lowerRight)) - return 0; - - QString left = inverted.value(lowerInverted.value(lowerRight)); - - inverted.remove(hash.value(left)); - hash.remove(left); - lowerHash.remove(left.toLower()); - lowerInverted.remove(lowerRight); - - return 1; - } - } + int removeRight(const QString& right, Qt::CaseSensitivity cs = Qt::CaseSensitive); /** * @brief Removes entry from hash and returns it. @@ -177,21 +92,7 @@ class BiStrHash * @param cs Case sensitivity flag. * @return Right side value, or null string if the \p left was not matched. */ - QString takeLeft(const QString& left, Qt::CaseSensitivity cs = Qt::CaseSensitive) - { - if (cs == Qt::CaseSensitive) - { - QString right = hash.take(left); - inverted.remove(right); - return right; - } - else - { - QString right = hash.take(lowerHash.take(left.toLower())); - inverted.remove(lowerInverted.take(right.toLower())); - return right; - } - } + QString takeLeft(const QString& left, Qt::CaseSensitivity cs = Qt::CaseSensitive); /** * @brief Removes entry from hash and returns it. @@ -199,44 +100,19 @@ class BiStrHash * @param cs Case sensitivity flag. * @return Left side value, or null string if the \p left was not matched. */ - QString takeRight(const QString& right, Qt::CaseSensitivity cs = Qt::CaseSensitive) - { - if (cs == Qt::CaseSensitive) - { - QString left = inverted.take(right); - hash.remove(left); - return left; - } - else - { - QString left = inverted.take(lowerInverted.take(right.toLower())); - hash.remove(lowerHash.take(left.toLower())); - return left; - } - } + QString takeRight(const QString& right, Qt::CaseSensitivity cs = Qt::CaseSensitive); /** * @brief Copies all entries from the other hash to this hash. * @param other Other hash to copy values from. * @return Reference to this hash, after update. */ - BiStrHash& unite(const BiStrHash& other) - { - unite(other.hash); - return *this; - } + BiStrHash& unite(const BiStrHash& other); /** * @overload */ - BiStrHash& unite(const QHash& other) - { - QHashIterator it(other); - while (it.hasNext()) - insert(it.next().key(), it.value()); - - return *this; - } + BiStrHash& unite(const QHash& other); /** * @brief Finds right-side value by matching the left-side value. @@ -244,13 +120,7 @@ class BiStrHash * @param cs Case sensitivity flag. * @return Right-side value, or null string if left-side value was not matched. */ - QString valueByLeft(const QString& left, Qt::CaseSensitivity cs = Qt::CaseSensitive) const - { - if (cs == Qt::CaseSensitive) - return hash.value(left); - else - return hash.value(lowerHash.value(left.toLower())); - } + QString valueByLeft(const QString& left, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; /** * @brief Finds left-side value by matching the right-side value. @@ -258,85 +128,48 @@ class BiStrHash * @param cs Case sensitivity flag. * @return Left-side value, or null string if right-side value was not matched. */ - QString valueByRight(const QString& right, Qt::CaseSensitivity cs = Qt::CaseSensitive) const - { - if (cs == Qt::CaseSensitive) - return inverted.value(right); - else - return inverted.value(lowerInverted.value(right.toLower())); - } + QString valueByRight(const QString& right, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; /** * @brief Gives all left-side values. * @return List of values. */ - QStringList leftValues() const - { - return hash.keys(); - } + QStringList leftValues() const; /** * @brief Gives all right-side values. * @return List of values. */ - QStringList rightValues() const - { - return inverted.keys(); - } + QStringList rightValues() const; /** * @brief Provides java-style iterator for this hash. * @return Iterator object. */ - QHashIterator iterator() const - { - return QHashIterator(hash); - } + QHashIterator iterator() const; /** * @brief Removes all entries from the hash. */ - void clear() - { - hash.clear(); - inverted.clear(); - lowerHash.clear(); - lowerInverted.clear(); - } + void clear(); /** * @brief Counts all entries in the hash. * @return Number of entries in the hash. */ - int count() const - { - return hash.count(); - } + int count() const; /** * @brief Tests whether the hash is empty or not. * @return true if the hash is empty, false otherwise. */ - bool isEmpty() const - { - return hash.isEmpty(); - } + bool isEmpty() const; private: /** * @brief Fills inverted and lower internal hashes basing on the main hash class member. */ - void initInvertedAndLower() - { - QHashIterator it(hash); - while (it.hasNext()) - { - it.next(); - inverted[it.value()] = it.key(); - lowerHash[it.key().toLower()] = it.key(); - lowerInverted[it.value().toLower()] = it.value(); - } - } + void initInvertedAndLower(); /** * @brief Standard mapping - left to right. diff --git a/SQLiteStudio3/coreSQLiteStudio/common/sortedset.h b/SQLiteStudio3/coreSQLiteStudio/common/sortedset.h new file mode 100644 index 0000000..266e409 --- /dev/null +++ b/SQLiteStudio3/coreSQLiteStudio/common/sortedset.h @@ -0,0 +1,64 @@ +#ifndef SORTEDSET_H +#define SORTEDSET_H + +#include "common/sortedhash.h" + +template +class SortedSet : private SortedHash +{ + public: + bool contains(const T &value) const + { + return QHash::containsKey(value); + } + + int count() const + { + return size(); + } + + bool isEmpty() const + { + return SortedHash::isEmpty(); + } + + bool remove(const T& value) + { + return SortedHash::remove(value); + } + + int size() const + { + return QHash::size(); + } + + void swap(SortedSet& other) + { + return SortedHash::swap(other); + } + + SortedSet& operator+=(const T& value) + { + SortedHash::insert(value, true); + return *this; + } + + SortedSet& operator-=(const T& value) + { + SortedHash::remove(value); + return *this; + } + + QSet& operator<<(const T &value) + { + SortedHash::insert(value, true); + return *this; + } + + QList toList() + { + return SortedHash::keys(); + } +}; + +#endif // SORTEDSET_H diff --git a/SQLiteStudio3/coreSQLiteStudio/common/strhash.h b/SQLiteStudio3/coreSQLiteStudio/common/strhash.h index 4fb7bb3..41b3d11 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/strhash.h +++ b/SQLiteStudio3/coreSQLiteStudio/common/strhash.h @@ -11,12 +11,12 @@ class StrHash { public: StrHash() {} - StrHash(std::initializer_list> list) : hash(QHash(list)) + StrHash(std::initializer_list> list) : hash(QHash(list)) { initLower(); } - StrHash(const QHash& other) : hash(QHash(other)) + StrHash(const QHash& other) : hash(QHash(other)) { initLower(); } @@ -87,9 +87,9 @@ class StrHash return *this; } - StrHash& unite(const QHash& other) + StrHash& unite(const QHash& other) { - QHashIterator it(other); + QHashIterator it(other); while (it.hasNext()) { it.next(); @@ -117,9 +117,9 @@ class StrHash return hash.keys(); } - QHashIterator iterator() const + QHashIterator iterator() const { - return QHashIterator(hash); + return QHashIterator(hash); } void clear() @@ -146,6 +146,11 @@ class StrHash return hash.isEmpty(); } + QHash toQHash() const + { + return hash; + } + T& operator[](const QString& key) { if (lowerCaseHash.contains(key.toLower()) && !hash.contains(key)) @@ -167,7 +172,7 @@ class StrHash private: void initLower() { - QHashIterator it(hash); + QHashIterator it(hash); while (it.hasNext()) { it.next(); @@ -175,8 +180,8 @@ class StrHash } } - QHash lowerCaseHash; - QHash hash; + QHash lowerCaseHash; + QHash hash; }; #endif // STRHASH_H diff --git a/SQLiteStudio3/coreSQLiteStudio/common/utils.cpp b/SQLiteStudio3/coreSQLiteStudio/common/utils.cpp index f2b3d1c..6cf1892 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/utils.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/common/utils.cpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include #ifdef Q_OS_LINUX #include @@ -214,12 +216,12 @@ qint64 Range::length() const return to - from + 1; } -QString generateUniqueName(const QString &baseName, const QStringList &existingNames) +QString generateUniqueName(const QString& baseName, const QStringList& existingNames, Qt::CaseSensitivity cs) { QString name = baseName; int i = 0; - while (existingNames.contains(name)) - name = baseName+QString::number(i++); + while (existingNames.contains(name, cs)) + name = baseName + QString::number(i++); return name; } @@ -887,3 +889,38 @@ QString decryptRsa(const QString& input, const QString& modulus, const QString& std::string result = RSA::Decrypt(inputStdStr, key); return QString::fromStdString(result); } + +QStringList concat(const QList& list) +{ + QStringList result; + for (const QStringList& item : list) + result.append(item); + + return result; +} + +QString doubleToString(double val) +{ + return QString::number(val, 'g', 16); +} + +void sortWithReferenceList(QList& listToSort, const QList& referenceList, Qt::CaseSensitivity cs) +{ + qSort(listToSort.begin(), listToSort.end(), [referenceList, cs](const QString& s1, const QString& s2) -> bool + { + int idx1 = indexOf(referenceList, s1, cs); + int idx2 = indexOf(referenceList, s2, cs); + if (idx1 == -1 || idx2 == -1) + { + if (idx1 == -1 && idx2 == -1) + return false; + + return (idx1 == -1); + } + + if (idx1 == idx2) + return false; + + return (idx1 > idx2); + }); +} diff --git a/SQLiteStudio3/coreSQLiteStudio/common/utils.h b/SQLiteStudio3/coreSQLiteStudio/common/utils.h index 90d2d62..934e70a 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/utils.h +++ b/SQLiteStudio3/coreSQLiteStudio/common/utils.h @@ -57,7 +57,7 @@ API_EXPORT QString randStr(int length, bool numChars = true, bool whiteSpaces = API_EXPORT QString randStr(int length, const QString& charCollection); API_EXPORT QString randBinStr(int length); API_EXPORT QString randStrNotIn(int length, const QSet set, bool numChars = true, bool whiteSpaces = false); -API_EXPORT QString generateUniqueName(const QString& prefix, const QStringList& existingNames); +API_EXPORT QString generateUniqueName(const QString& prefix, const QStringList& existingNames, Qt::CaseSensitivity cs = Qt::CaseSensitive); API_EXPORT bool isNumeric(const QVariant& value); API_EXPORT QString rStrip(const QString& str); API_EXPORT QStringList tokenizeArgs(const QString& str); @@ -73,6 +73,20 @@ API_EXPORT QHash bytesToHash(const QByteArray& bytes); API_EXPORT int indexOf(const QStringList& list, const QString& value, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive); API_EXPORT int indexOf(const QStringList& list, const QString& value, Qt::CaseSensitivity cs = Qt::CaseSensitive); +template +int indexOf(const QList& list, std::function predicate) +{ + int i = 0; + for (const T& item : list) + { + if (predicate(item)) + return i; + + ++i; + } + return -1; +} + /** * @brief Returns only those elements from the list, which passed the filter. * @tparam T type for which the filter will be applied for. It should match the type in the list and in the function argument. @@ -103,6 +117,18 @@ bool contains(const QList& list, std::function testFunc return false; } +template +QList concat(const QList>& list) +{ + QList result; + for (const QList& item : list) + result.append(item); + + return result; +} + +API_EXPORT QStringList concat(const QList& list); + /** * @brief Appends or prepends characters to the string to make it of specified length. * @param str Input string to work with. @@ -205,6 +231,18 @@ API_EXPORT bool renameBetweenPartitions(const QString& src, const QString& dst); API_EXPORT bool isWritableRecursively(const QString& dir); API_EXPORT QString encryptRsa(const QString& input, const QString& modulus, const QString& exponent); API_EXPORT QString decryptRsa(const QString& input, const QString& modulus, const QString& exponent); +API_EXPORT QString doubleToString(double val); + +/** + * @brief Sorts string list using reference list for ordering. + * @param listToSort This list will be sorted. + * @param referenceList Should contain all elements from list to sort - it tells the order. + * @param cs Case sensitivity of the string comparision. + * + * Sorts \p listToSort using \p referenceList as a reference of what is the order. + * If any element from \p listToSort is not on the list of \p referenceList, then the element will be placed at the end. + */ +API_EXPORT void sortWithReferenceList(QList& listToSort, const QList& referenceList, Qt::CaseSensitivity cs = Qt::CaseSensitive); enum class DistributionType { diff --git a/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.cpp b/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.cpp index eba10fa..5c7e7e9 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.cpp @@ -77,6 +77,16 @@ QString wrapObjIfNeeded(const QString& obj, Dialect dialect, NameWrapper favWrap return obj; } +QString wrapObjIfNeeded(const QString& obj, Dialect dialect, bool useDoubleQuoteForEmptyValue, NameWrapper favWrapper) +{ + return wrapObjIfNeeded(obj, dialect, ((useDoubleQuoteForEmptyValue && obj.isEmpty()) ? NameWrapper::DOUBLE_QUOTE : favWrapper)); +} + +QString wrapObjName(const QString& obj, Dialect dialect, bool useDoubleQuoteForEmptyValue, NameWrapper favWrapper) +{ + return wrapObjName(obj, dialect, ((useDoubleQuoteForEmptyValue && obj.isEmpty()) ? NameWrapper::DOUBLE_QUOTE : favWrapper)); +} + QString wrapObjName(const QString& obj, Dialect dialect, NameWrapper favWrapper) { QString result = obj; @@ -573,6 +583,8 @@ QueryAccessMode getQueryAccessMode(const QString& query, Dialect dialect, bool* TokenList tokens = Lexer::tokenize(query, dialect); int keywordIdx = tokens.indexOf(Token::KEYWORD); + if (keywordIdx < 0) + return QueryAccessMode::WRITE; int cmdIdx = readOnlyCommands.indexOf(tokens[keywordIdx]->value.toUpper()); if (keywordIdx > -1 && cmdIdx > -1) @@ -632,3 +644,53 @@ QueryAccessMode getQueryAccessMode(const QString& query, Dialect dialect, bool* return QueryAccessMode::WRITE; } + +QStringList valueListToSqlList(const QVariantList& values, Dialect dialect) +{ + QStringList argList; + for (const QVariant& value : values) + { + if (!value.isValid() || value.isNull()) + { + argList << "NULL"; + continue; + } + + switch (value.userType()) + { + case QVariant::Int: + case QVariant::UInt: + case QVariant::LongLong: + case QVariant::ULongLong: + argList << value.toString(); + break; + case QVariant::Double: + argList << doubleToString(value.toDouble()); + break; + case QVariant::Bool: + argList << QString::number(value.toInt()); + break; + case QVariant::ByteArray: + { + if (dialect == Dialect::Sqlite3) // version 2 will go to the regular string processing + { + argList << "X'" + value.toByteArray().toHex().toUpper() + "'"; + break; + } + } + default: + argList << wrapString(escapeString(value.toString())); + break; + } + } + return argList; +} + +QStringList wrapStrings(const QStringList& strList) +{ + QStringList list; + for (const QString& str : strList) + list << wrapString(str); + + return list; +} diff --git a/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.h b/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.h index 038c146..ceccea0 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.h +++ b/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.h @@ -36,7 +36,9 @@ API_EXPORT bool isObjectWrapped(const QChar& c); API_EXPORT bool doesStringNeedWrapping(const QString& str); API_EXPORT bool isStringWrapped(const QString& str); API_EXPORT QString wrapObjIfNeeded(const QString& obj, Dialect dialect, NameWrapper favWrapper = NameWrapper::null); +API_EXPORT QString wrapObjIfNeeded(const QString& obj, Dialect dialect, bool useDoubleQuoteForEmptyValue, NameWrapper favWrapper = NameWrapper::null); API_EXPORT QString wrapObjName(const QString& obj, Dialect dialect, NameWrapper favWrapper = NameWrapper::null); +API_EXPORT QString wrapObjName(const QString& obj, Dialect dialect, bool useDoubleQuoteForEmptyValue, NameWrapper favWrapper = NameWrapper::null); API_EXPORT QString wrapObjName(const QString& obj, NameWrapper wrapper); API_EXPORT TokenPtr stripObjName(TokenPtr token, Dialect dialect); API_EXPORT QString stripObjName(const QString &str, Dialect dialect); @@ -45,6 +47,7 @@ API_EXPORT bool isObjWrapped(const QString& str, Dialect dialect); API_EXPORT NameWrapper getObjWrapper(const QString& str, Dialect dialect); API_EXPORT bool isWrapperChar(const QChar& c, Dialect dialect); API_EXPORT QString wrapString(const QString& str); +API_EXPORT QStringList wrapStrings(const QStringList& strList); API_EXPORT QString wrapStringIfNeeded(const QString& str); API_EXPORT QString escapeString(QString &str); API_EXPORT QString escapeString(const QString& str); @@ -75,6 +78,7 @@ API_EXPORT QString trimBindParamPrefix(const QString& param); API_EXPORT QString commentAllSqlLines(const QString& sql); API_EXPORT QString getBindTokenName(const TokenPtr& token); API_EXPORT QueryAccessMode getQueryAccessMode(const QString& query, Dialect dialect, bool* isSelect = nullptr); +API_EXPORT QStringList valueListToSqlList(const QList& values, Dialect dialect); #endif // UTILS_SQL_H diff --git a/SQLiteStudio3/coreSQLiteStudio/coreSQLiteStudio.pro b/SQLiteStudio3/coreSQLiteStudio/coreSQLiteStudio.pro index 886678d..59da902 100644 --- a/SQLiteStudio3/coreSQLiteStudio/coreSQLiteStudio.pro +++ b/SQLiteStudio3/coreSQLiteStudio/coreSQLiteStudio.pro @@ -221,7 +221,9 @@ SOURCES += sqlitestudio.cpp \ common/signalwait.cpp \ common/blockingsocket.cpp \ common/threadwitheventloop.cpp \ - common/private/blockingsocketprivate.cpp + common/private/blockingsocketprivate.cpp \ + querygenerator.cpp \ + common/bistrhash.cpp HEADERS += sqlitestudio.h\ coreSQLiteStudio_global.h \ @@ -413,7 +415,11 @@ HEADERS += sqlitestudio.h\ common/blockingsocket.h \ common/threadwitheventloop.h \ common/private/blockingsocketprivate.h \ - common/expiringcache.h + common/expiringcache.h \ + parser/ast/sqliteddlwithdbcontext.h \ + parser/ast/sqliteextendedindexedcolumn.h \ + querygenerator.h \ + common/sortedset.h unix: { target.path = $$LIBDIR diff --git a/SQLiteStudio3/coreSQLiteStudio/csvserializer.cpp b/SQLiteStudio3/coreSQLiteStudio/csvserializer.cpp index c89074f..15bf4e8 100644 --- a/SQLiteStudio3/coreSQLiteStudio/csvserializer.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/csvserializer.cpp @@ -3,103 +3,85 @@ // TODO write unit tests for CsvSerializer -QString CsvSerializer::serialize(const QList& data, const CsvFormat& format) -{ - QStringList outputRows; - - foreach (const QStringList& dataRow, data) - outputRows << serialize(dataRow, format); - - return outputRows.join(format.rowSeparator); -} - -QString CsvSerializer::serialize(const QStringList& data, const CsvFormat& format) -{ - QString value; - bool hasQuote; - QStringList outputCells; - foreach (const QString& rowValue, data) - { - value = rowValue; - - hasQuote = value.contains("\""); - if (hasQuote) - value.replace("\"", "\"\""); - - if (hasQuote || value.contains(format.columnSeparator) || value.contains(format.rowSeparator)) - value = "\""+value+"\""; - - outputCells << value; - } - - return outputCells.join(format.columnSeparator); -} - -template -bool isCsvColumnSeparator(const T& data, int pos, const CsvFormat& format) +template +bool isCsvColumnSeparator(QTextStream& data, const C& theChar, const CsvFormat& format) { - if (!format.strictColumnSeparator && format.columnSeparator.contains(data[pos])) - return true; + if (!format.strictColumnSeparator) + return format.columnSeparator.contains(theChar); + // Strict checking (characters in defined order make a separator) + qint64 origPos = data.pos(); + data.seek(origPos - 1); + C nextChar; for (const QChar& c : format.columnSeparator) { - if (c != data[pos++]) + data >> nextChar; + if (c != nextChar) + { + data.seek(origPos); return false; + } } return true; } -template -bool isCsvRowSeparator(const T& data, int& pos, const CsvFormat& format) +template +bool isCsvRowSeparator(QTextStream& data, const C& theChar, const CsvFormat& format) { - if (!format.strictRowSeparator && format.rowSeparator.contains(data[pos])) - return true; + if (!format.strictRowSeparator) + return format.rowSeparator.contains(theChar); - int localPos = pos; + // Strict checking (characters in defined order make a separator) + qint64 origPos = data.pos(); + data.seek(origPos - 1); + C nextChar; for (const QChar& c : format.rowSeparator) { - if (localPos >= data.size() || c != data[localPos++]) + data >> nextChar; + if (data.atEnd() || c != nextChar) + { + data.seek(origPos); return false; + } } - pos = localPos - 1; return true; } -template -QList> typedDeserialize(const T& data, const CsvFormat& format) +template +QList> typedDeserialize(QTextStream& data, const CsvFormat& format, bool oneEntry) { QList> rows; QList cells; - int pos = 0; - int lgt = data.length(); bool quotes = false; bool sepAsLast = false; T field = ""; - QChar c; + C c0; + C c1; - while (pos < lgt) + while (!data.atEnd()) { - c = data[pos]; + data >> c0; sepAsLast = false; - if (!quotes && c == '"' ) + if (!quotes && c0 == '"' ) { quotes = true; } - else if (quotes && c == '"' ) + else if (quotes && c0 == '"' ) { - if (pos + 1 < data.length()) + if (!data.atEnd()) { - if (data[pos+1] == '"' ) + data >> c1; + if (c1 == '"' ) { - field += c; - pos++; + field += c0; } else { quotes = false; + data.seek(data.pos() - 1); } } else @@ -110,24 +92,32 @@ QList> typedDeserialize(const T& data, const CsvFormat& format) quotes = false; } } - else if (!quotes && isCsvColumnSeparator(data, pos, format)) + else if (!quotes) { - cells << field; - field.clear(); - sepAsLast = true; - } - else if (!quotes && isCsvRowSeparator(data, pos, format)) - { - cells << field; - rows << cells; - cells.clear(); - field.clear(); + if (isCsvColumnSeparator(data, c0, format)) + { + cells << field; + field = ""; + sepAsLast = true; + } + else if (isCsvRowSeparator(data, c0, format)) + { + cells << field; + rows << cells; + cells.clear(); + field = ""; + if (oneEntry) + break; + } + else + { + field += c0; + } } else { - field += c; + field += c0; } - pos++; } if (field.size() > 0 || sepAsLast) @@ -139,14 +129,61 @@ QList> typedDeserialize(const T& data, const CsvFormat& format) return rows; } -QList > CsvSerializer::deserialize(const QByteArray& data, const CsvFormat& format) +QString CsvSerializer::serialize(const QList& data, const CsvFormat& format) { - return typedDeserialize(data, format); + QStringList outputRows; + + foreach (const QStringList& dataRow, data) + outputRows << serialize(dataRow, format); + + return outputRows.join(format.rowSeparator); } -QList CsvSerializer::deserialize(const QString& data, const CsvFormat& format) +QString CsvSerializer::serialize(const QStringList& data, const CsvFormat& format) +{ + QString value; + bool hasQuote; + QStringList outputCells; + foreach (const QString& rowValue, data) + { + value = rowValue; + + hasQuote = value.contains("\""); + if (hasQuote) + value.replace("\"", "\"\""); + + if (hasQuote || value.contains(format.columnSeparator) || value.contains(format.rowSeparator)) + value = "\""+value+"\""; + + outputCells << value; + } + + return outputCells.join(format.columnSeparator); +} + +QStringList CsvSerializer::deserializeOneEntry(QTextStream& data, const CsvFormat& format) +{ + QList deserialized = CsvSerializer::deserialize(data, format, true); + if (deserialized.size() > 0) + return deserialized.first(); + + return QStringList(); +} + +QList CsvSerializer::deserialize(QTextStream& data, const CsvFormat& format) +{ + return CsvSerializer::deserialize(data, format, false); +} + +QList> CsvSerializer::deserialize(const QByteArray& data, const CsvFormat& format) { - QList> deserialized = typedDeserialize(data, format); + QTextStream stream(data, QIODevice::ReadWrite); + return typedDeserialize(stream, format, false); +} + +QList CsvSerializer::deserialize(QTextStream& data, const CsvFormat& format, bool oneEntry) +{ + QList> deserialized = typedDeserialize(data, format, oneEntry); QList finalList; for (const QList& resPart : deserialized) @@ -155,64 +192,10 @@ QList CsvSerializer::deserialize(const QString& data, const CsvForm return finalList; } +QList CsvSerializer::deserialize(const QString& data, const CsvFormat& format) +{ + QString dataString = data; + QTextStream stream(&dataString, QIODevice::ReadWrite); + return deserialize(stream, format, false); +} -//QList CsvSerializer::deserialize(const QByteArray& data, const CsvFormat& format) -//{ -// QList rows; -// QStringList cells; - -// int pos = 0; -// int lgt = data.length(); -// bool quotes = false; -// bool sepAsLast = false; -// QString field = ""; -// QChar c; - -// while (pos < lgt) -// { -// c = data[pos]; -// sepAsLast = false; -// if (!quotes && c == '"' ) -// { -// quotes = true; -// } -// else if (quotes && c == '"' ) -// { -// if (pos + 1 < data.length() && data[pos+1] == '"' ) -// { -// field += c; -// pos++; -// } -// else -// { -// quotes = false; -// } -// } -// else if (!quotes && format.columnSeparator.contains(c)) -// { -// cells << field; -// field.clear(); -// sepAsLast = true; -// } -// else if (!quotes && format.rowSeparator.contains(c)) -// { -// cells << field; -// rows << cells; -// cells.clear(); -// field.clear(); -// } -// else -// { -// field += c; -// } -// pos++; -// } - -// if (field.size() > 0 || sepAsLast) -// cells << field; - -// if (cells.size() > 0) -// rows << cells; - -// return rows; -//} diff --git a/SQLiteStudio3/coreSQLiteStudio/csvserializer.h b/SQLiteStudio3/coreSQLiteStudio/csvserializer.h index 1ff6ee9..0b7e095 100644 --- a/SQLiteStudio3/coreSQLiteStudio/csvserializer.h +++ b/SQLiteStudio3/coreSQLiteStudio/csvserializer.h @@ -4,6 +4,8 @@ #include "coreSQLiteStudio_global.h" #include "csvformat.h" +#include + class API_EXPORT CsvSerializer { public: @@ -11,6 +13,11 @@ class API_EXPORT CsvSerializer static QString serialize(const QStringList& data, const CsvFormat& format); static QList deserialize(const QString& data, const CsvFormat& format); static QList> deserialize(const QByteArray& data, const CsvFormat& format); + static QList deserialize(QTextStream& data, const CsvFormat& format); + static QStringList deserializeOneEntry(QTextStream& data, const CsvFormat& format); + + private: + static QList deserialize(QTextStream& data, const CsvFormat& format, bool oneEntry); }; #endif // CSVSERIALIZER_H diff --git a/SQLiteStudio3/coreSQLiteStudio/db/abstractdb2.h b/SQLiteStudio3/coreSQLiteStudio/db/abstractdb2.h index 5b95f61..7419f8c 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/abstractdb2.h +++ b/SQLiteStudio3/coreSQLiteStudio/db/abstractdb2.h @@ -600,7 +600,7 @@ bool AbstractDb2::Query::execInternal(const QList& args) } bool ok = (fetchFirst() == SQLITE_OK); - if (ok) + if (ok && !flags.testFlag(Db::Flag::SKIP_DROP_DETECTION)) db->checkForDroppedObject(query); return ok; @@ -643,7 +643,7 @@ bool AbstractDb2::Query::execInternal(const QHash& args) } bool ok = (fetchFirst() == SQLITE_OK); - if (ok) + if (ok && !flags.testFlag(Db::Flag::SKIP_DROP_DETECTION)) db->checkForDroppedObject(query); return ok; diff --git a/SQLiteStudio3/coreSQLiteStudio/db/abstractdb3.h b/SQLiteStudio3/coreSQLiteStudio/db/abstractdb3.h index e7b0a4b..db9bc02 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/abstractdb3.h +++ b/SQLiteStudio3/coreSQLiteStudio/db/abstractdb3.h @@ -68,10 +68,10 @@ class AbstractDb3 : public AbstractDb class Row : public SqlResultsRow { public: - int init(const QStringList& columns, typename T::stmt* stmt); + int init(const QStringList& columns, typename T::stmt* stmt, Db::Flags flags); private: - int getValue(typename T::stmt* stmt, int col, QVariant& value); + int getValue(typename T::stmt* stmt, int col, QVariant& value, Db::Flags flags); }; Query(AbstractDb3* db, const QString& query); @@ -888,7 +888,7 @@ bool AbstractDb3::Query::execInternal(const QList& args) } bool ok = (fetchFirst() == T::OK); - if (ok) + if (ok && !flags.testFlag(Db::Flag::SKIP_DROP_DETECTION)) db->checkForDroppedObject(query); return ok; @@ -942,7 +942,7 @@ bool AbstractDb3::Query::execInternal(const QHash& args) } bool ok = (fetchFirst() == T::OK); - if (ok) + if (ok && !flags.testFlag(Db::Flag::SKIP_DROP_DETECTION)) db->checkForDroppedObject(query); return ok; @@ -1044,7 +1044,7 @@ template SqlResultsRowPtr AbstractDb3::Query::nextInternal() { Row* row = new Row; - int res = row->init(colNames, stmt); + int res = row->init(colNames, stmt, flags); if (res != T::OK) { delete row; @@ -1131,13 +1131,13 @@ int AbstractDb3::Query::fetchNext() //------------------------------------------------------------------------------------ template -int AbstractDb3::Query::Row::init(const QStringList& columns, typename T::stmt* stmt) +int AbstractDb3::Query::Row::init(const QStringList& columns, typename T::stmt* stmt, Db::Flags flags) { int res = T::OK; QVariant value; for (int i = 0; i < columns.size(); i++) { - res = getValue(stmt, i, value); + res = getValue(stmt, i, value, flags); if (res != T::OK) return res; @@ -1148,8 +1148,9 @@ int AbstractDb3::Query::Row::init(const QStringList& columns, typename T::stm } template -int AbstractDb3::Query::Row::getValue(typename T::stmt* stmt, int col, QVariant& value) +int AbstractDb3::Query::Row::getValue(typename T::stmt* stmt, int col, QVariant& value, Db::Flags flags) { + UNUSED(flags); int dataType = T::column_type(stmt, col); switch (dataType) { @@ -1162,12 +1163,12 @@ int AbstractDb3::Query::Row::getValue(typename T::stmt* stmt, int col, QVaria T::column_bytes(stmt, col) ); break; - case T::FLOAT: - value = T::column_double(stmt, col); - break; case T::NULL_TYPE: value = QVariant(QVariant::String); break; + case T::FLOAT: + value = T::column_double(stmt, col); + break; default: value = QString( reinterpret_cast(T::column_text16(stmt, col)), diff --git a/SQLiteStudio3/coreSQLiteStudio/db/chainexecutor.cpp b/SQLiteStudio3/coreSQLiteStudio/db/chainexecutor.cpp index f36a3bd..a35856b 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/chainexecutor.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/db/chainexecutor.cpp @@ -42,6 +42,16 @@ void ChainExecutor::exec() return; } + if (disableForeignKeys && db->getDialect() == Dialect::Sqlite3) + { + SqlQueryPtr result = db->exec("PRAGMA foreign_keys = 0;"); + if (result->isError()) + { + emit failure(db->getErrorCode(), tr("Could not disable foreign keys in the database. Details: %1", "chain executor").arg(db->getErrorText())); + return; + } + } + if (transaction && !db->begin()) { emit failure(db->getErrorCode(), tr("Could not start a database transaction. Details: %1", "chain executor").arg(db->getErrorText())); @@ -75,7 +85,7 @@ void ChainExecutor::executeCurrentSql() return; } - asyncId = db->asyncExec(sqls[currentSqlIndex], queryParams); + asyncId = db->asyncExec(sqls[currentSqlIndex], queryParams, getExecFlags()); } QList ChainExecutor::getMandatoryQueries() const @@ -122,6 +132,7 @@ void ChainExecutor::executionFailure(int errorCode, const QString& errorText) if (transaction) db->rollback(); + restoreFk(); successfulExecution = false; executionErrors << ExecutionError(errorCode, errorText); emit failure(errorCode, errorText); @@ -135,16 +146,18 @@ void ChainExecutor::executionSuccessful() return; } + restoreFk(); successfulExecution = true; emit success(); } void ChainExecutor::executeSync() { + Db::Flags flags = getExecFlags(); SqlQueryPtr results; - foreach (const QString& sql, sqls) + for (const QString& sql : sqls) { - results = db->exec(sql, queryParams); + results = db->exec(sql, queryParams, flags); if (!handleResults(results)) return; @@ -165,6 +178,46 @@ bool ChainExecutor::handleResults(SqlQueryPtr results) } return true; } + +Db::Flags ChainExecutor::getExecFlags() const +{ + Db::Flags flags; + if (disableObjectDropsDetection) + flags |= Db::Flag::SKIP_DROP_DETECTION; + + return flags; +} + +void ChainExecutor::restoreFk() +{ + if (disableForeignKeys && db->getDialect() == Dialect::Sqlite3) + { + SqlQueryPtr result = db->exec("PRAGMA foreign_keys = 1;"); + if (result->isError()) + qCritical() << "Could not restore foreign keys in the database after chain execution. Details:" << db->getErrorText(); + } +} + +bool ChainExecutor::getDisableObjectDropsDetection() const +{ + return disableObjectDropsDetection; +} + +void ChainExecutor::setDisableObjectDropsDetection(bool value) +{ + disableObjectDropsDetection = value; +} + +bool ChainExecutor::getDisableForeignKeys() const +{ + return disableForeignKeys; +} + +void ChainExecutor::setDisableForeignKeys(bool value) +{ + disableForeignKeys = value; +} + bool ChainExecutor::getSuccessfulExecution() const { return successfulExecution; diff --git a/SQLiteStudio3/coreSQLiteStudio/db/chainexecutor.h b/SQLiteStudio3/coreSQLiteStudio/db/chainexecutor.h index 2d3e3d3..0afbdb8 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/chainexecutor.h +++ b/SQLiteStudio3/coreSQLiteStudio/db/chainexecutor.h @@ -198,6 +198,12 @@ class API_EXPORT ChainExecutor : public QObject */ void setParam(const QString& paramName, const QVariant& value); + bool getDisableForeignKeys() const; + void setDisableForeignKeys(bool value); + + bool getDisableObjectDropsDetection() const; + void setDisableObjectDropsDetection(bool value); + private: /** * @brief Executes query defines as the current one. @@ -241,6 +247,10 @@ class API_EXPORT ChainExecutor : public QObject */ bool handleResults(SqlQueryPtr results); + Db::Flags getExecFlags() const; + + void restoreFk(); + /** * @brief Database for execution. */ @@ -315,6 +325,9 @@ class API_EXPORT ChainExecutor : public QObject */ QHash queryParams; + bool disableForeignKeys = false; + bool disableObjectDropsDetection = false; + public slots: /** * @brief Interrupts query execution. diff --git a/SQLiteStudio3/coreSQLiteStudio/db/db.cpp b/SQLiteStudio3/coreSQLiteStudio/db/db.cpp index 7676f30..977812a 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/db.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/db/db.cpp @@ -1,6 +1,7 @@ #include "db.h" #include #include +#include Db::Db() { diff --git a/SQLiteStudio3/coreSQLiteStudio/db/db.h b/SQLiteStudio3/coreSQLiteStudio/db/db.h index efadd41..4a9e80a 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/db.h +++ b/SQLiteStudio3/coreSQLiteStudio/db/db.h @@ -140,7 +140,7 @@ class API_EXPORT Db : public QObject, public Interruptable { NONE = 0x0, /**< No flags. This is default. */ PRELOAD = 0x1, /**< Preloads all execution results into the results object. Useful for asynchronous execution. */ - NO_LOCK = 0x2 /**< + NO_LOCK = 0x2, /**< * Prevents SQLiteStudio from setting the lock for execution on this base (not the SQLite lock, * just a Db internal lock for multi-threading access to the Db::exec()). This should be used * only in justified circumstances. That is when the Db call has to be done from within the part @@ -148,6 +148,7 @@ class API_EXPORT Db : public QObject, public Interruptable * threads. Justified situation is when you implement Db::initialDbSetup() in the derived class, * or when you implement SqlFunctionPlugin. Don't use it for the usual cases. */ + SKIP_DROP_DETECTION = 0x4, /**< Query execution will not notify about any detected objects dropped by the query. */ }; Q_DECLARE_FLAGS(Flags, Flag) diff --git a/SQLiteStudio3/coreSQLiteStudio/db/queryexecutor.cpp b/SQLiteStudio3/coreSQLiteStudio/db/queryexecutor.cpp index f8d7fd2..d2e7072 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/queryexecutor.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/db/queryexecutor.cpp @@ -20,6 +20,7 @@ #include "queryexecutorsteps/queryexecutordetectschemaalter.h" #include "queryexecutorsteps/queryexecutorvaluesmode.h" #include "common/unused.h" +#include "log.h" #include #include #include @@ -94,13 +95,16 @@ void QueryExecutor::executeChain() bool result; foreach (QueryExecutorStep* currentStep, executionChain) { - if (interrupted) + if (isInterrupted()) { stepFailed(currentStep); return; } + logExecutorStep(currentStep); result = currentStep->exec(); + logExecutorAfterStep(context->processedQuery); + if (!result) { stepFailed(currentStep); @@ -127,7 +131,7 @@ void QueryExecutor::stepFailed(QueryExecutorStep* currentStep) clearChain(); - if (interrupted) + if (isInterrupted()) { executionInProgress = false; emit executionFailed(SqlErrorCode::INTERRUPTED, tr("Execution interrupted.")); @@ -240,6 +244,7 @@ void QueryExecutor::interrupt() return; } + QMutexLocker lock(&interruptionMutex); interrupted = true; db->asyncInterrupt(); } @@ -255,11 +260,11 @@ bool QueryExecutor::countResults() if (asyncMode) { // Start asynchronous results counting query - resultsCountingAsyncId = db->asyncExec(context->countingQuery, context->queryParameters); + resultsCountingAsyncId = db->asyncExec(context->countingQuery, context->queryParameters, Db::Flag::NO_LOCK); } else { - SqlQueryPtr results = db->exec(context->countingQuery, context->queryParameters); + SqlQueryPtr results = db->exec(context->countingQuery, context->queryParameters, Db::Flag::NO_LOCK); context->totalRowsReturned = results->getSingleCell().toLongLong(); context->totalPages = (int)qCeil(((double)(context->totalRowsReturned)) / ((double)getResultsPerPage())); @@ -568,6 +573,11 @@ void QueryExecutor::setForceSimpleMode(bool value) forceSimpleMode = value; } +bool QueryExecutor::isInterrupted() const +{ + QMutexLocker lock(&interruptionMutex); + return interrupted; +} const QStringList& QueryExecutor::getRequiredDbAttaches() const { @@ -586,24 +596,29 @@ void QueryExecutor::setNoMetaColumns(bool value) void QueryExecutor::handleErrorsFromSmartAndSimpleMethods(SqlQueryPtr results) { - UNUSED(results); // It turns out that currently smart execution error has more sense to be displayed to user than the simple execution error, // so we're ignoring error from simple method, because it's usually misleading. - // The case when simple method error is more true than smart method error is very rare nowdays. + // The case when simple method error is more true than smart method error is very rare nowdays (but happens sometimes, + // therefore we need to check code from smart execution, before deciding which one to use). // Just rename attach names in the message. - QString msg = context->errorMessageFromSmartExecution; + bool useSmartError = context->errorCodeFromSmartExecution != 0; + QString msg = useSmartError ? context->errorMessageFromSmartExecution : results->getErrorText(); + int code = useSmartError ? context->errorCodeFromSmartExecution : results->getErrorCode(); QString match; QString replaceName; Dialect dialect = db->getDialect(); - for (const QString& attachName : context->dbNameToAttach.rightValues()) + if (useSmartError) { - match = attachName + "."; - replaceName = wrapObjIfNeeded(context->dbNameToAttach.valueByRight(attachName), dialect) + "."; - while (msg.contains(match)) - msg.replace(match, replaceName); + for (const QString& attachName : context->dbNameToAttach.rightValues()) + { + match = attachName + "."; + replaceName = wrapObjIfNeeded(context->dbNameToAttach.valueByRight(attachName), dialect) + "."; + while (msg.contains(match)) + msg.replace(match, replaceName); + } } - error(context->errorCodeFromSmartExecution, msg); + error(code, msg); } void QueryExecutor::releaseResultsAndCleanup() diff --git a/SQLiteStudio3/coreSQLiteStudio/db/queryexecutor.h b/SQLiteStudio3/coreSQLiteStudio/db/queryexecutor.h index 95c6a0c..eddbe8c 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/queryexecutor.h +++ b/SQLiteStudio3/coreSQLiteStudio/db/queryexecutor.h @@ -1032,6 +1032,8 @@ class API_EXPORT QueryExecutor : public QObject, public QRunnable bool getForceSimpleMode() const; void setForceSimpleMode(bool value); + bool isInterrupted() const; + private: /** * @brief Executes query. @@ -1161,7 +1163,8 @@ class API_EXPORT QueryExecutor : public QObject, public QRunnable * The state of "execution in progress" is the only value synchronized between threads. * It makes sure that single QueryExecutor will execute only one query at the time. */ - QMutex executionMutex; + mutable QMutex executionMutex; + mutable QMutex interruptionMutex; /** * @brief Query to execute as defined by the user. diff --git a/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorcellsize.cpp b/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorcellsize.cpp index fceea3f..934a20d 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorcellsize.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorcellsize.cpp @@ -57,8 +57,39 @@ bool QueryExecutorCellSize::applyDataLimit(SqliteSelect* select, SqliteSelect::C TokenList QueryExecutorCellSize::getLimitTokens(const QueryExecutor::ResultColumnPtr& resCol) { + // CASE WHEN typeof(alias) IN ('real', 'integer', 'numeric', 'null') THEN alias ELSE substr(alias, 1, limit) END TokenList newTokens; - newTokens << TokenPtr::create(Token::OTHER, "substr") + newTokens << TokenPtr::create(Token::KEYWORD, "CASE") + << TokenPtr::create(Token::SPACE, " ") + << TokenPtr::create(Token::KEYWORD, "WHEN") + << TokenPtr::create(Token::SPACE, " ") + << TokenPtr::create(Token::OTHER, "typeof") + << TokenPtr::create(Token::PAR_LEFT, "(") + << TokenPtr::create(Token::OTHER, resCol->queryExecutorAlias) + << TokenPtr::create(Token::PAR_RIGHT, ")") + << TokenPtr::create(Token::SPACE, " ") + << TokenPtr::create(Token::KEYWORD, "IN") + << TokenPtr::create(Token::SPACE, " ") + << TokenPtr::create(Token::PAR_LEFT, "(") + << TokenPtr::create(Token::STRING, "'real'") + << TokenPtr::create(Token::OPERATOR, ",") + << TokenPtr::create(Token::SPACE, " ") + << TokenPtr::create(Token::STRING, "'integer'") + << TokenPtr::create(Token::OPERATOR, ",") + << TokenPtr::create(Token::SPACE, " ") + << TokenPtr::create(Token::STRING, "'numeric'") + << TokenPtr::create(Token::OPERATOR, ",") + << TokenPtr::create(Token::SPACE, " ") + << TokenPtr::create(Token::STRING, "'null'") + << TokenPtr::create(Token::PAR_RIGHT, ")") + << TokenPtr::create(Token::SPACE, " ") + << TokenPtr::create(Token::KEYWORD, "THEN") + << TokenPtr::create(Token::SPACE, " ") + << TokenPtr::create(Token::OTHER, resCol->queryExecutorAlias) + << TokenPtr::create(Token::SPACE, " ") + << TokenPtr::create(Token::KEYWORD, "ELSE") + << TokenPtr::create(Token::SPACE, " ") + << TokenPtr::create(Token::OTHER, "substr") << TokenPtr::create(Token::PAR_LEFT, "(") << TokenPtr::create(Token::OTHER, resCol->queryExecutorAlias) << TokenPtr::create(Token::OPERATOR, ",") @@ -69,6 +100,8 @@ TokenList QueryExecutorCellSize::getLimitTokens(const QueryExecutor::ResultColum << TokenPtr::create(Token::INTEGER, QString::number(queryExecutor->getDataLengthLimit())) << TokenPtr::create(Token::PAR_RIGHT, ")") << TokenPtr::create(Token::SPACE, " ") + << TokenPtr::create(Token::KEYWORD, "END") + << TokenPtr::create(Token::SPACE, " ") << TokenPtr::create(Token::KEYWORD, "AS") << TokenPtr::create(Token::SPACE, " ") << TokenPtr::create(Token::OTHER, resCol->queryExecutorAlias); diff --git a/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorcolumns.cpp b/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorcolumns.cpp index 287a8ce..344f2e5 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorcolumns.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorcolumns.cpp @@ -71,12 +71,13 @@ bool QueryExecutorColumns::exec() i++; } +// qDebug() << "before: " << context->processedQuery; // Update query select->rebuildTokens(); wrapWithAliasedColumns(select.data()); updateQueries(); -// qDebug() << context->processedQuery; +// qDebug() << "after: " << context->processedQuery; return true; } @@ -130,6 +131,9 @@ SqliteSelect::Core::ResultColumn* QueryExecutorColumns::getResultColumnForSelect SqliteSelect::Core::ResultColumn* selectResultColumn = new SqliteSelect::Core::ResultColumn(); QString colString = resultColumn->column; + if (col.aliasDefinedInSubQuery) // #2931 + colString = col.alias; + if (!resultColumn->expression) colString = wrapObjIfNeeded(colString, dialect); @@ -167,16 +171,11 @@ SqliteSelect::Core::ResultColumn* QueryExecutorColumns::getResultColumnForSelect } } + selectResultColumn->asKw = true; if (!col.alias.isNull()) - { - selectResultColumn->asKw = true; selectResultColumn->alias = col.alias; - } else - { - selectResultColumn->asKw = true; selectResultColumn->alias = resultColumn->queryExecutorAlias; - } return selectResultColumn; } diff --git a/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorexecute.cpp b/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorexecute.cpp index a954da7..3036796 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorexecute.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorexecute.cpp @@ -41,11 +41,13 @@ bool QueryExecutorExecute::executeQueries() if (context->preloadResults) flags |= Db::Flag::PRELOAD; + QString queryStr; int queryCount = context->parsedQueries.size(); for (const SqliteQueryPtr& query : context->parsedQueries) { + queryStr = query->detokenize(); bindParamsForQuery = getBindParamsForQuery(query); - results = db->prepare(query->detokenize()); + results = db->prepare(queryStr); results->setArgs(bindParamsForQuery); results->setFlags(flags); @@ -56,6 +58,7 @@ bool QueryExecutorExecute::executeQueries() if (isBeginTransaction(query->queryType)) rowsAffectedBeforeTransaction.push(context->rowsAffected); +// qDebug() << "Executing query:" << queryStr; results->execute(); if (results->isError()) diff --git a/SQLiteStudio3/coreSQLiteStudio/dbattacher.h b/SQLiteStudio3/coreSQLiteStudio/dbattacher.h index 5b94832..0e849a5 100644 --- a/SQLiteStudio3/coreSQLiteStudio/dbattacher.h +++ b/SQLiteStudio3/coreSQLiteStudio/dbattacher.h @@ -73,6 +73,17 @@ class API_EXPORT DbAttacher * @return Query string. */ virtual QString getQuery() const = 0; + + /** + * @brief Tells if "main" database name was used in the query and was ommited. + * @return true when "main" db token was in the query, or false otherwise. + * + * The "main" database will not be attached and this getter tells wheter such situation occured. + * This is to assert situation when user has database on the list which name is actually "main". + * Table window always uses "main." prefix when reading data and this caused attacher to step in, + * which then caused some execution error. + */ + virtual bool getMainDbNameUsed() const = 0; }; /** diff --git a/SQLiteStudio3/coreSQLiteStudio/dbobjectorganizer.cpp b/SQLiteStudio3/coreSQLiteStudio/dbobjectorganizer.cpp index f8c51dc..542668b 100644 --- a/SQLiteStudio3/coreSQLiteStudio/dbobjectorganizer.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/dbobjectorganizer.cpp @@ -559,7 +559,21 @@ bool DbObjectOrganizer::copySimpleObjectToDb(const QString& name, const QString& if (convertedDdl.trimmed() == ";") // empty query, result of ignored errors in UI return true; - SqlQueryPtr result = dstDb->exec(convertedDdl); + SqlQueryPtr result; + + if (!attachName.isNull()) + { + convertedDdl = prefixSimpleObjectWithAttachName(name, convertedDdl); + if (convertedDdl.isNull()) + return false; + + result = srcDb->exec(convertedDdl); + } + else + { + result = dstDb->exec(convertedDdl); + } + if (result->isError()) { notifyError(errorMessage.arg(result->getErrorText())); @@ -750,6 +764,37 @@ bool DbObjectOrganizer::execConfirmFunctionInMainThread(const QStringList& table return res; } +QString DbObjectOrganizer::prefixSimpleObjectWithAttachName(const QString& objName, const QString& ddl) +{ + Parser parser(srcDb->getDialect()); + if (!parser.parse(ddl)) + { + qDebug() << "Parsing error while copying or moving object:" << objName << ", details:" << parser.getErrorString(); + notifyError(tr("Could not parse object '%1' in order to move or copy it.").arg(objName)); + return QString(); + } + + if (parser.getQueries().isEmpty()) + { + qDebug() << "Empty queries from parser while copying or moving object:" << objName; + notifyError(tr("Could not parse object '%1' in order to move or copy it.").arg(objName)); + return QString(); + } + + SqliteQueryPtr query = parser.getQueries().first(); + SqliteDdlWithDbContextPtr ddlWithDb = query.dynamicCast(); + if (!ddlWithDb) + { + qDebug() << "Not instance of SqliteDdlWithDbContext while copying or moving object:" << objName << ", it's type is:" << (int)query->queryType; + notifyError(tr("Could not parse object '%1' in order to move or copy it.").arg(objName)); + return QString(); + } + + ddlWithDb->setTargetDatabase(attachName); + query->rebuildTokens(); + return query->tokens.detokenize(); +} + void DbObjectOrganizer::processPreparationFinished() { if (errorsToConfirm.size() > 0 && !conversionErrorsConfimFunction(errorsToConfirm)) diff --git a/SQLiteStudio3/coreSQLiteStudio/dbobjectorganizer.h b/SQLiteStudio3/coreSQLiteStudio/dbobjectorganizer.h index 8a7e7a9..42b258a 100644 --- a/SQLiteStudio3/coreSQLiteStudio/dbobjectorganizer.h +++ b/SQLiteStudio3/coreSQLiteStudio/dbobjectorganizer.h @@ -109,6 +109,7 @@ class API_EXPORT DbObjectOrganizer : public QObject, public QRunnable, public In bool rollback(); void emitFinished(bool success); bool execConfirmFunctionInMainThread(const QStringList& tables); + QString prefixSimpleObjectWithAttachName(const QString& objName, const QString& ddl); ReferencedTablesConfimFunction confirmFunction; NameConflictResolveFunction nameConflictResolveFunction; diff --git a/SQLiteStudio3/coreSQLiteStudio/dbversionconverter.cpp b/SQLiteStudio3/coreSQLiteStudio/dbversionconverter.cpp index 676009a..9e4c664 100644 --- a/SQLiteStudio3/coreSQLiteStudio/dbversionconverter.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/dbversionconverter.cpp @@ -793,20 +793,10 @@ bool DbVersionConverter::modifyAllIndexedColumnsForVersion2(SqliteStatement* stm } -bool DbVersionConverter::modifyAllIndexedColumnsForVersion2(const QList columns) +bool DbVersionConverter::modifySingleIndexedColumnForVersion2(SqliteExtendedIndexedColumn* idxCol) { - for (SqliteIndexedColumn* idxCol : columns) - { - if (!modifySingleIndexedColumnForVersion2(idxCol)) - return false; - } - return true; -} - -bool DbVersionConverter::modifySingleIndexedColumnForVersion2(SqliteIndexedColumn* idxCol) -{ - if (!idxCol->collate.isNull()) - idxCol->collate = QString::null; + if (!idxCol->getCollation().isNull()) + idxCol->clearCollation(); return true; } diff --git a/SQLiteStudio3/coreSQLiteStudio/dbversionconverter.h b/SQLiteStudio3/coreSQLiteStudio/dbversionconverter.h index 8343c2f..9486f1b 100644 --- a/SQLiteStudio3/coreSQLiteStudio/dbversionconverter.h +++ b/SQLiteStudio3/coreSQLiteStudio/dbversionconverter.h @@ -2,6 +2,7 @@ #define DBVERSIONCONVERTER_H #include "parser/ast/sqlitequery.h" +#include "parser/ast/sqliteorderby.h" #include #include #include @@ -85,8 +86,7 @@ class API_EXPORT DbVersionConverter : public QObject bool modifyAllExprsForVersion2(SqliteStatement* stmt); bool modifySingleExprForVersion2(SqliteExpr* expr); bool modifyAllIndexedColumnsForVersion2(SqliteStatement* stmt); - bool modifyAllIndexedColumnsForVersion2(const QList columns); - bool modifySingleIndexedColumnForVersion2(SqliteIndexedColumn* idxCol); + bool modifySingleIndexedColumnForVersion2(SqliteExtendedIndexedColumn* idxCol); bool modifyBeginTransForVersion3(SqliteBeginTrans* begin); bool modifyCreateTableForVersion3(SqliteCreateTable* createTable); QString getSqlForDiff(SqliteStatement* stmt); @@ -99,6 +99,18 @@ class API_EXPORT DbVersionConverter : public QObject bool isInterrupted(); void conversionInterrupted(Db* db, bool rollback); + template + bool modifyAllIndexedColumnsForVersion2(const QList columns) + { + for (T* idxCol : columns) + { + if (!modifySingleIndexedColumnForVersion2(idxCol)) + return false; + } + return true; + } + + template QSharedPointer copyQuery(SqliteQueryPtr query) { diff --git a/SQLiteStudio3/coreSQLiteStudio/exportworker.cpp b/SQLiteStudio3/coreSQLiteStudio/exportworker.cpp index ffecd4d..6427138 100644 --- a/SQLiteStudio3/coreSQLiteStudio/exportworker.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/exportworker.cpp @@ -4,6 +4,7 @@ #include "services/notifymanager.h" #include "common/utils_sql.h" #include "common/utils.h" +#include "db/sqlresultsrow.h" #include #include @@ -590,6 +591,9 @@ QList ExportWorker::collectDbObjects(QString* er qSort(objectsToExport.begin(), objectsToExport.end(), [](ExportManager::ExportObjectPtr obj1, ExportManager::ExportObjectPtr obj2) -> bool { + if (obj1->type == obj2->type) + return obj1->name.compare(obj2->name, Qt::CaseInsensitive) < 0; + return (obj1->type < obj2->type); }); @@ -638,7 +642,8 @@ void ExportWorker::queryTableDataToExport(Db* db, const QString& table, SqlQuery else { QList colWidths; - for (const QVariant& value : colLengthQuery->next()->valueList()) + SqlResultsRowPtr row = colLengthQuery->next(); + for (const QVariant& value : row->valueList()) colWidths << value.toInt(); providerData[ExportManager::DATA_LENGTHS] = QVariant::fromValue(colWidths); diff --git a/SQLiteStudio3/coreSQLiteStudio/impl/dbattacherimpl.cpp b/SQLiteStudio3/coreSQLiteStudio/impl/dbattacherimpl.cpp index 75d94eb..7d9c1ba 100644 --- a/SQLiteStudio3/coreSQLiteStudio/impl/dbattacherimpl.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/impl/dbattacherimpl.cpp @@ -69,7 +69,7 @@ TokenList DbAttacherImpl::getDbTokens() void DbAttacherImpl::detachAttached() { - foreach (const QString& dbName, dbNameToAttach.leftValues()) + for (const QString& dbName : dbNameToAttach.leftValues()) db->detach(nameToDbMap[dbName]); dbNameToAttach.clear(); @@ -87,7 +87,7 @@ QHash DbAttacherImpl::groupDbTokens(const TokenList& dbToken // Filter out tokens of unknown databases and group results by name QHash groupedDbTokens; QString strippedName; - foreach (TokenPtr token, dbTokens) + for (TokenPtr token : dbTokens) { strippedName = stripObjName(token->value, dialect); if (!nameToDbMap.contains(strippedName, Qt::CaseInsensitive)) @@ -101,8 +101,14 @@ QHash DbAttacherImpl::groupDbTokens(const TokenList& dbToken bool DbAttacherImpl::attachAllDbs(const QHash& groupedDbTokens) { QString attachName; - foreach (const QString& dbName, groupedDbTokens.keys()) + for (const QString& dbName : groupedDbTokens.keys()) { + if (dbName.toLower() == "main") + { + mainDbNameUsed = true; + continue; + } + attachName = db->attach(nameToDbMap[dbName]); if (attachName.isNull()) { @@ -121,7 +127,7 @@ QHash DbAttacherImpl::getTokenMapping(const TokenList& dbTok QHash tokenMapping; QString strippedName; TokenPtr dstToken; - foreach (TokenPtr srcToken, dbTokens) + for (TokenPtr srcToken : dbTokens) { strippedName = stripObjName(srcToken->value, dialect); if (strippedName.compare("main", Qt::CaseInsensitive) == 0 || @@ -158,6 +164,11 @@ void DbAttacherImpl::replaceTokensInQueries(const QHash& tok } } +bool DbAttacherImpl::getMainDbNameUsed() const +{ + return mainDbNameUsed; +} + BiStrHash DbAttacherImpl::getDbNameToAttach() const { return dbNameToAttach; diff --git a/SQLiteStudio3/coreSQLiteStudio/impl/dbattacherimpl.h b/SQLiteStudio3/coreSQLiteStudio/impl/dbattacherimpl.h index 49307c6..6fbe6c8 100644 --- a/SQLiteStudio3/coreSQLiteStudio/impl/dbattacherimpl.h +++ b/SQLiteStudio3/coreSQLiteStudio/impl/dbattacherimpl.h @@ -18,6 +18,7 @@ class DbAttacherImpl : public DbAttacher void detachDatabases(); BiStrHash getDbNameToAttach() const; QString getQuery() const; + bool getMainDbNameUsed() const; private: /** @@ -83,6 +84,7 @@ class DbAttacherImpl : public DbAttacher Dialect dialect; BiStrHash dbNameToAttach; StrHash nameToDbMap; + bool mainDbNameUsed = false; }; class DbAttacherDefaultFactory : public DbAttacherFactory diff --git a/SQLiteStudio3/coreSQLiteStudio/importworker.cpp b/SQLiteStudio3/coreSQLiteStudio/importworker.cpp index b8d5a5a..a8ca8f7 100644 --- a/SQLiteStudio3/coreSQLiteStudio/importworker.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/importworker.cpp @@ -147,6 +147,11 @@ bool ImportWorker::importData() QList row; while ((row = plugin->next()).size() > 0) { + // Fill up missing values in the line + for (int i = row.size(); i < colCount; i++) + row << QVariant(QVariant::String); + + // Assign argument values query->setArgs(row.mid(0, colCount)); if (!query->execute()) { diff --git a/SQLiteStudio3/coreSQLiteStudio/log.cpp b/SQLiteStudio3/coreSQLiteStudio/log.cpp index d54abdb..d45f1aa 100644 --- a/SQLiteStudio3/coreSQLiteStudio/log.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/log.cpp @@ -1,9 +1,11 @@ #include "log.h" +#include "db/queryexecutorsteps/queryexecutorstep.h" #include #include -bool SQL_DEBUG = false; -QString SQL_DEBUG_FILTER = ""; +static bool SQL_DEBUG = false; +static bool EXECUTOR_DEBUG = false; +static QString SQL_DEBUG_FILTER = ""; void setSqlLoggingEnabled(bool enabled) { @@ -45,3 +47,25 @@ void logSql(Db* db, const QString& str, const QList& args, Db::Flags f foreach (const QVariant& arg, args) qDebug() << " SQL arg>" << i++ << "=" << arg; } + +void setExecutorLoggingEnabled(bool enabled) +{ + EXECUTOR_DEBUG = enabled; +} + +void logExecutorStep(QueryExecutorStep* step) +{ + if (!EXECUTOR_DEBUG) + return; + + qDebug() << "Executing step:" << step->metaObject()->className() << step->objectName(); +} + + +void logExecutorAfterStep(const QString& str) +{ + if (!EXECUTOR_DEBUG) + return; + + qDebug() << str; +} diff --git a/SQLiteStudio3/coreSQLiteStudio/log.h b/SQLiteStudio3/coreSQLiteStudio/log.h index dddb513..1cf8dc5 100644 --- a/SQLiteStudio3/coreSQLiteStudio/log.h +++ b/SQLiteStudio3/coreSQLiteStudio/log.h @@ -8,9 +8,14 @@ #include #include +class QueryExecutorStep; + API_EXPORT void logSql(Db* db, const QString& str, const QHash& args, Db::Flags flags); API_EXPORT void logSql(Db* db, const QString& str, const QList& args, Db::Flags flags); +API_EXPORT void logExecutorStep(QueryExecutorStep* step); +API_EXPORT void logExecutorAfterStep(const QString& str); API_EXPORT void setSqlLoggingEnabled(bool enabled); API_EXPORT void setSqlLoggingFilter(const QString& filter); +API_EXPORT void setExecutorLoggingEnabled(bool enabled); #endif // LOG_H diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.cpp index 16cec8f..fdbadf8 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.cpp @@ -14,11 +14,10 @@ SqliteCreateIndex::SqliteCreateIndex(const SqliteCreateIndex& other) : SqliteQuery(other), uniqueKw(other.uniqueKw), ifNotExistsKw(other.ifNotExistsKw), database(other.database), index(other.index), table(other.table) { - DEEP_COPY_COLLECTION(SqliteIndexedColumn, indexedColumns); + DEEP_COPY_COLLECTION(SqliteOrderBy, indexedColumns); } -SqliteCreateIndex::SqliteCreateIndex(bool unique, bool ifNotExists, const QString &name1, const QString &name2, const QString &name3, - const QList &columns, SqliteConflictAlgo onConflict) +SqliteCreateIndex::SqliteCreateIndex(bool unique, bool ifNotExists, const QString& name1, const QString& name2, const QString& name3, const QList& columns, SqliteConflictAlgo onConflict) : SqliteCreateIndex() { // Constructor for SQLite 2 @@ -36,14 +35,11 @@ SqliteCreateIndex::SqliteCreateIndex(bool unique, bool ifNotExists, const QStrin table = name2; this->onConflict = onConflict; - this->indexedColumns = columns; - - foreach (SqliteIndexedColumn* idxCol, columns) - idxCol->setParent(this); + this->indexedColumns = toOrderColumns(columns); } SqliteCreateIndex::SqliteCreateIndex(bool unique, bool ifNotExists, const QString& name1, const QString& name2, const QString& name3, - const QList& columns, SqliteExpr* where) + const QList& columns, SqliteExpr* where) : SqliteCreateIndex() { // Constructor for SQLite 3 @@ -61,7 +57,7 @@ SqliteCreateIndex::SqliteCreateIndex(bool unique, bool ifNotExists, const QStrin table = name3; this->indexedColumns = columns; - foreach (SqliteIndexedColumn* idxCol, columns) + foreach (SqliteOrderBy* idxCol, columns) idxCol->setParent(this); this->where = where; @@ -189,3 +185,44 @@ TokenList SqliteCreateIndex::rebuildTokensFromContents() return builder.build(); } + +QList SqliteCreateIndex::toOrderColumns(const QList& columns) +{ + QList result; + SqliteOrderBy* orderBy = nullptr; + SqliteExpr* expr = nullptr; + for (SqliteIndexedColumn* idxCol : columns) + { + orderBy = new SqliteOrderBy(); + orderBy->setParent(this); + orderBy->expr = new SqliteExpr(); + orderBy->expr->setParent(orderBy); + + if (!idxCol->collate.isNull()) + { + expr = new SqliteExpr(); + expr->initId(idxCol->name); + expr->setParent(orderBy->expr); + + orderBy->expr->initCollate(expr, idxCol->collate); + } + else + { + orderBy->expr->initId(idxCol->name); + } + + result << orderBy; + delete idxCol; + } + return result; +} + +QString SqliteCreateIndex::getTargetDatabase() const +{ + return database; +} + +void SqliteCreateIndex::setTargetDatabase(const QString& database) +{ + this->database = database; +} diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.h index 9251b18..033a663 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.h +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.h @@ -5,12 +5,14 @@ #include "sqlitetablerelatedddl.h" #include "sqliteconflictalgo.h" #include "sqliteexpr.h" +#include "sqliteddlwithdbcontext.h" +#include "sqliteorderby.h" #include #include class SqliteIndexedColumn; -class API_EXPORT SqliteCreateIndex : public SqliteQuery, public SqliteTableRelatedDdl +class API_EXPORT SqliteCreateIndex : public SqliteQuery, public SqliteTableRelatedDdl, public SqliteDdlWithDbContext { public: SqliteCreateIndex(); @@ -19,16 +21,18 @@ class API_EXPORT SqliteCreateIndex : public SqliteQuery, public SqliteTableRelat const QString& name3, const QList& columns, SqliteConflictAlgo onConflict = SqliteConflictAlgo::null); SqliteCreateIndex(bool unique, bool ifNotExists, const QString& name1, const QString& name2, - const QString& name3, const QList& columns, + const QString& name3, const QList& columns, SqliteExpr* where); ~SqliteCreateIndex(); SqliteStatement* clone(); QString getTargetTable() const; + QString getTargetDatabase() const; + void setTargetDatabase(const QString& database); bool uniqueKw = false; bool ifNotExistsKw = false; - QList indexedColumns; + QList indexedColumns; // The database refers to index name in Sqlite3, but in Sqlite2 it refers to the table. QString database = QString::null; QString index = QString::null; @@ -43,6 +47,9 @@ class API_EXPORT SqliteCreateIndex : public SqliteQuery, public SqliteTableRelat TokenList getDatabaseTokensInStatement(); QList getFullObjectsInStatement(); TokenList rebuildTokensFromContents(); + + private: + QList toOrderColumns(const QList& columns); }; typedef QSharedPointer SqliteCreateIndexPtr; diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.cpp index d21578e..2ac6c04 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.cpp @@ -669,13 +669,23 @@ bool SqliteCreateTable::Column::hasConstraint(SqliteCreateTable::Column::Constra SqliteCreateTable::Column::Constraint* SqliteCreateTable::Column::getConstraint(SqliteCreateTable::Column::Constraint::Type type) const { - foreach (Constraint* constr, constraints) + for (Constraint* constr : constraints) if (constr->type == type) return constr; return nullptr; } +QList SqliteCreateTable::Column::getConstraints(SqliteCreateTable::Column::Constraint::Type type) const +{ + QList list; + for (Constraint* constr : constraints) + if (constr->type == type) + list << constr; + + return list; +} + QList SqliteCreateTable::Column::getForeignKeysByTable(const QString& foreignTable) const { QList results; @@ -768,3 +778,13 @@ TokenList SqliteCreateTable::Column::Constraint::rebuildTokensFromContents() return builder.build(); } + +QString SqliteCreateTable::getTargetDatabase() const +{ + return database; +} + +void SqliteCreateTable::setTargetDatabase(const QString& database) +{ + this->database = database; +} diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.h index 877d0fa..74f4fce 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.h +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.h @@ -10,10 +10,11 @@ #include "sqlitecolumntype.h" #include "sqlitesortorder.h" #include "sqlitedeferrable.h" +#include "sqliteddlwithdbcontext.h" #include #include -class API_EXPORT SqliteCreateTable : public SqliteQuery +class API_EXPORT SqliteCreateTable : public SqliteQuery, public SqliteDdlWithDbContext { public: class API_EXPORT Column : public SqliteStatement @@ -93,6 +94,7 @@ class API_EXPORT SqliteCreateTable : public SqliteQuery bool hasConstraint(Constraint::Type type) const; Constraint* getConstraint(Constraint::Type type) const; + QList getConstraints(Constraint::Type type) const; QList getForeignKeysByTable(const QString& foreignTable) const; QString name = QString::null; @@ -181,6 +183,8 @@ class API_EXPORT SqliteCreateTable : public SqliteQuery QList getColumnForeignKeysByTable(const QString& foreignTable) const; QStringList getColumnNames() const; QHash getModifiedColumnsMap(bool lowercaseKeys = false, Qt::CaseSensitivity cs = Qt::CaseInsensitive) const; + QString getTargetDatabase() const; + void setTargetDatabase(const QString& database); bool ifNotExistsKw = false; bool tempKw = false; @@ -202,7 +206,6 @@ class API_EXPORT SqliteCreateTable : public SqliteQuery private: void init(bool ifNotExistsKw, int temp, const QString& name1, const QString& name2); - }; typedef QSharedPointer SqliteCreateTablePtr; diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.cpp index 8f67aea..e15ddd6 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.cpp @@ -379,3 +379,13 @@ TokenList SqliteCreateTrigger::rebuildTokensFromContents() return builder.build(); } + +QString SqliteCreateTrigger::getTargetDatabase() const +{ + return database; +} + +void SqliteCreateTrigger::setTargetDatabase(const QString& database) +{ + this->database = database; +} diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.h index 2fb8ae4..2ccf876 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.h +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.h @@ -1,6 +1,7 @@ #ifndef SQLITECREATETRIGGER_H #define SQLITECREATETRIGGER_H +#include "sqliteddlwithdbcontext.h" #include "sqlitequery.h" #include "sqlitetablerelatedddl.h" @@ -9,7 +10,7 @@ class SqliteExpr; -class API_EXPORT SqliteCreateTrigger : public SqliteQuery, public SqliteTableRelatedDdl +class API_EXPORT SqliteCreateTrigger : public SqliteQuery, public SqliteTableRelatedDdl, public SqliteDdlWithDbContext { public: enum class Time @@ -63,6 +64,8 @@ class API_EXPORT SqliteCreateTrigger : public SqliteQuery, public SqliteTableRel SqliteStatement* clone(); QString getTargetTable() const; + QString getTargetDatabase() const; + void setTargetDatabase(const QString& database); bool tempKw = false; bool temporaryKw = false; diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.cpp index d1a8961..fe638db 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.cpp @@ -3,6 +3,7 @@ #include "sqlitequerytype.h" #include "parser/statementtokenbuilder.h" #include "common/global.h" +#include "sqliteindexedcolumn.h" SqliteCreateView::SqliteCreateView() { @@ -14,7 +15,7 @@ SqliteCreateView::SqliteCreateView(const SqliteCreateView& other) : database(other.database), view(other.view) { DEEP_COPY_FIELD(SqliteSelect, select); - + DEEP_COPY_COLLECTION(SqliteIndexedColumn, columns); } SqliteCreateView::SqliteCreateView(int temp, bool ifNotExists, const QString &name1, const QString &name2, SqliteSelect *select) : @@ -41,6 +42,15 @@ SqliteCreateView::SqliteCreateView(int temp, bool ifNotExists, const QString &na select->setParent(this); } +SqliteCreateView::SqliteCreateView(int temp, bool ifNotExists, const QString& name1, const QString& name2, SqliteSelect* select, const QList& columns) + : SqliteCreateView(temp, ifNotExists, name1, name2, select) +{ + this->columns = columns; + + for (SqliteIndexedColumn* col : columns) + col->setParent(this); +} + SqliteCreateView::~SqliteCreateView() { } @@ -112,9 +122,24 @@ TokenList SqliteCreateView::rebuildTokensFromContents() if (dialect == Dialect::Sqlite3 && !database.isNull()) builder.withOther(database, dialect).withOperator("."); - builder.withOther(view, dialect).withSpace().withKeyword("AS").withStatement(select); + builder.withOther(view, dialect).withSpace(); + + if (columns.size() > 0) + builder.withParLeft().withStatementList(columns).withParRight().withSpace(); + + builder.withKeyword("AS").withStatement(select); builder.withOperator(";"); return builder.build(); } + +QString SqliteCreateView::getTargetDatabase() const +{ + return database; +} + +void SqliteCreateView::setTargetDatabase(const QString& database) +{ + this->database = database; +} diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.h index 4858227..1f46d5e 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.h +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.h @@ -1,20 +1,26 @@ #ifndef SQLITECREATEVIEW_H #define SQLITECREATEVIEW_H +#include "sqliteddlwithdbcontext.h" #include "sqlitequery.h" +#include #include class SqliteSelect; +class SqliteIndexedColumn; -class API_EXPORT SqliteCreateView : public SqliteQuery +class API_EXPORT SqliteCreateView : public SqliteQuery, public SqliteDdlWithDbContext { public: SqliteCreateView(); SqliteCreateView(const SqliteCreateView& other); SqliteCreateView(int temp, bool ifNotExists, const QString& name1, const QString& name2, SqliteSelect* select); + SqliteCreateView(int temp, bool ifNotExists, const QString& name1, const QString& name2, SqliteSelect* select, const QList& columns); ~SqliteCreateView(); SqliteStatement* clone(); + QString getTargetDatabase() const; + void setTargetDatabase(const QString& database); bool tempKw = false; bool temporaryKw = false; @@ -22,6 +28,7 @@ class API_EXPORT SqliteCreateView : public SqliteQuery QString database = QString::null; QString view = QString::null; SqliteSelect* select = nullptr; + QList columns; protected: QStringList getDatabasesInStatement(); diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteddlwithdbcontext.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteddlwithdbcontext.h new file mode 100644 index 0000000..cb64986 --- /dev/null +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteddlwithdbcontext.h @@ -0,0 +1,16 @@ +#ifndef SQLITEDDLWITHDBCONTEXT_H +#define SQLITEDDLWITHDBCONTEXT_H + +#include "coreSQLiteStudio_global.h" +#include + +class API_EXPORT SqliteDdlWithDbContext +{ + public: + virtual QString getTargetDatabase() const = 0; + virtual void setTargetDatabase(const QString& database) = 0; +}; + +typedef QSharedPointer SqliteDdlWithDbContextPtr; + +#endif // SQLITEDDLWITHDBCONTEXT_H diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.cpp index b84a818..3009b4b 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteexpr.cpp @@ -91,7 +91,7 @@ QString SqliteExpr::notNullOp(SqliteExpr::NotNull value) } } -SqliteStatement*SqliteExpr::clone() +SqliteStatement* SqliteExpr::clone() { return new SqliteExpr(*this); } @@ -462,7 +462,11 @@ TokenList SqliteExpr::rebuildTokensFromContents() if (distinctKw) builder.withKeyword("DISTINCT"); - builder.withStatementList(exprList).withParRight(); + if (star) + builder.withOperator("*").withParRight(); + else + builder.withStatementList(exprList).withParRight(); + break; case SqliteExpr::Mode::SUB_EXPR: builder.withParLeft().withStatement(expr1).withParRight(); diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteextendedindexedcolumn.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteextendedindexedcolumn.h new file mode 100644 index 0000000..1ea6119 --- /dev/null +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteextendedindexedcolumn.h @@ -0,0 +1,19 @@ +#ifndef SQLITEEXTENDEDINDEXEDCOLUMN_H +#define SQLITEEXTENDEDINDEXEDCOLUMN_H + +#include "coreSQLiteStudio_global.h" +#include + +class API_EXPORT SqliteExtendedIndexedColumn +{ + public: + virtual QString getColumnName() const = 0; + virtual void setColumnName(const QString& name) = 0; + virtual QString getCollation() const = 0; + virtual void setCollation(const QString& name) = 0; + virtual void clearCollation() = 0; +}; + +typedef QSharedPointer SqliteExtendedIndexedColumnPtr; + +#endif // SQLITEEXTENDEDINDEXEDCOLUMN_H diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteindexedcolumn.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteindexedcolumn.cpp index 5e65eab..142af06 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteindexedcolumn.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteindexedcolumn.cpp @@ -24,11 +24,26 @@ SqliteIndexedColumn::SqliteIndexedColumn(const QString& name) this->name = name; } -SqliteStatement*SqliteIndexedColumn::clone() +SqliteStatement* SqliteIndexedColumn::clone() { return new SqliteIndexedColumn(*this); } +QString SqliteIndexedColumn::getColumnName() const +{ + return name; +} + +void SqliteIndexedColumn::setColumnName(const QString& name) +{ + this->name = name; +} + +void SqliteIndexedColumn::setCollation(const QString& name) +{ + this->collate = name; +} + QStringList SqliteIndexedColumn::getColumnsInStatement() { return getStrListFromValue(name); @@ -50,3 +65,13 @@ TokenList SqliteIndexedColumn::rebuildTokensFromContents() builder.withSortOrder(sortOrder); return builder.build(); } + +QString SqliteIndexedColumn::getCollation() const +{ + return collate; +} + +void SqliteIndexedColumn::clearCollation() +{ + collate.clear(); +} diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteindexedcolumn.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteindexedcolumn.h index c013d17..c0fe680 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteindexedcolumn.h +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteindexedcolumn.h @@ -3,9 +3,10 @@ #include "sqlitestatement.h" #include "sqlitesortorder.h" +#include "sqliteextendedindexedcolumn.h" #include -class API_EXPORT SqliteIndexedColumn : public SqliteStatement +class API_EXPORT SqliteIndexedColumn : public SqliteStatement, public SqliteExtendedIndexedColumn { public: SqliteIndexedColumn(); @@ -14,6 +15,11 @@ class API_EXPORT SqliteIndexedColumn : public SqliteStatement explicit SqliteIndexedColumn(const QString& name); SqliteStatement* clone(); + QString getColumnName() const; + void setColumnName(const QString& name); + void setCollation(const QString& name); + QString getCollation() const; + void clearCollation(); QString name = QString::null; SqliteSortOrder sortOrder = SqliteSortOrder::null; diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteorderby.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteorderby.cpp index 3bb1b44..8eb7b46 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteorderby.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteorderby.cpp @@ -30,6 +30,76 @@ SqliteStatement*SqliteOrderBy::clone() return new SqliteOrderBy(*this); } +bool SqliteOrderBy::isSimpleColumn() const +{ + return !getColumnName().isEmpty(); +} + +QString SqliteOrderBy::getColumnName() const +{ + if (!expr) + return QString(); + + if (expr->mode == SqliteExpr::Mode::ID) + return expr->column; + + if (expr->mode == SqliteExpr::Mode::COLLATE && expr->expr1 && expr->expr1->mode == SqliteExpr::Mode::ID) + return expr->expr1->literalValue.toString(); + + return QString(); +} + +QString SqliteOrderBy::getCollation() const +{ + if (expr->mode == SqliteExpr::Mode::COLLATE) + return expr->collation; + + return QString(); +} + +QString SqliteOrderBy::getColumnString() const +{ + QString res = getColumnName(); + if (res.isNull()) + return expr->detokenize(); + + return res; +} + +void SqliteOrderBy::setColumnName(const QString& name) +{ + if (expr && expr->mode == SqliteExpr::Mode::COLLATE) + { + safe_delete(expr->expr1); + expr->expr1 = new SqliteExpr(); + expr->expr1->setParent(expr); + expr->expr1->initId(name); + } + else + { + safe_delete(expr); + expr = new SqliteExpr(); + expr->setParent(this); + expr->initId(name); + } +} + +void SqliteOrderBy::setCollation(const QString& name) +{ + if (expr && expr->mode == SqliteExpr::Mode::COLLATE) + { + expr->collation = name; + } + else + { + SqliteExpr* theExpr = expr; + SqliteExpr* collationExpr = new SqliteExpr(); + collationExpr->initCollate(theExpr, name); + theExpr->setParent(collationExpr); + collationExpr->setParent(this); + } +} + TokenList SqliteOrderBy::rebuildTokensFromContents() { StatementTokenBuilder builder; @@ -39,3 +109,15 @@ TokenList SqliteOrderBy::rebuildTokensFromContents() return builder.build(); } + + +void SqliteOrderBy::clearCollation() +{ + if (expr->mode != SqliteExpr::Mode::COLLATE) + return; + + SqliteExpr* tmpExpr = expr; + expr = tmpExpr->expr1; + expr->setParent(this); + delete tmpExpr; +} diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteorderby.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteorderby.h index 598423d..4f75c78 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteorderby.h +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteorderby.h @@ -3,10 +3,11 @@ #include "sqlitestatement.h" #include "sqlitesortorder.h" +#include "sqliteextendedindexedcolumn.h" class SqliteExpr; -class API_EXPORT SqliteOrderBy : public SqliteStatement +class API_EXPORT SqliteOrderBy : public SqliteStatement, public SqliteExtendedIndexedColumn { public: SqliteOrderBy(); @@ -15,9 +16,16 @@ class API_EXPORT SqliteOrderBy : public SqliteStatement ~SqliteOrderBy(); SqliteStatement* clone(); + bool isSimpleColumn() const; + QString getColumnName() const; + QString getCollation() const; + QString getColumnString() const; + void setColumnName(const QString& name); + void setCollation(const QString& name); + void clearCollation(); SqliteExpr* expr = nullptr; - SqliteSortOrder order; + SqliteSortOrder order = SqliteSortOrder::null; protected: TokenList rebuildTokensFromContents(); diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitetablerelatedddl.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitetablerelatedddl.h index 599849a..9de9be7 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitetablerelatedddl.h +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitetablerelatedddl.h @@ -2,6 +2,7 @@ #define SQLITETABLERELATEDDDL_H #include "coreSQLiteStudio_global.h" +#include class API_EXPORT SqliteTableRelatedDdl { diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitevacuum.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitevacuum.cpp index 96ff7a4..9d595ed 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitevacuum.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitevacuum.cpp @@ -32,6 +32,9 @@ QStringList SqliteVacuum::getDatabasesInStatement() TokenList SqliteVacuum::getDatabaseTokensInStatement() { + if (!tokensMap.contains("nm")) + return TokenList(); + return getTokenListFromNamedKey("nm"); } diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/lexer.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/lexer.cpp index c85b3ba..6be7528 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/lexer.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/lexer.cpp @@ -3,6 +3,7 @@ #include "lexer_low_lev.h" #include "sqlite2_parse.h" #include "sqlite3_parse.h" +#include "common/utils_sql.h" #include #include #include @@ -281,11 +282,41 @@ QString Lexer::detokenize(const TokenList& tokens) QString str; foreach (TokenPtr token, tokens) - str += token->value; + str += detokenize(token); return str; } +QString Lexer::detokenize(const TokenPtr& token) +{ + switch (token->type) { + case Token::OTHER: + case Token::CTX_ALIAS: + case Token::CTX_COLLATION: + case Token::CTX_COLUMN: + case Token::CTX_COLUMN_NEW: + case Token::CTX_COLUMN_TYPE: + case Token::CTX_CONSTRAINT: + case Token::CTX_DATABASE: + case Token::CTX_INDEX: + case Token::CTX_INDEX_NEW: + case Token::CTX_TABLE: + case Token::CTX_TABLE_NEW: + case Token::CTX_TRANSACTION: + case Token::CTX_TRIGGER: + case Token::CTX_TRIGGER_NEW: + case Token::CTX_VIEW: + case Token::CTX_VIEW_NEW: + return token->value.isEmpty() ? wrapObjName(token->value, Dialect::Sqlite3, NameWrapper::DOUBLE_QUOTE) : token->value; + case Token::CTX_ERROR_MESSAGE: + case Token::STRING: + return token->value.isEmpty() ? wrapString(token->value) : token->value; + default: + break; + } + return token->value; +} + TokenList Lexer::tokenize(const QString& sql, Dialect dialect) { Lexer lexer(dialect); diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/lexer.h b/SQLiteStudio3/coreSQLiteStudio/parser/lexer.h index b21639e..8473844 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/lexer.h +++ b/SQLiteStudio3/coreSQLiteStudio/parser/lexer.h @@ -128,6 +128,15 @@ class API_EXPORT Lexer */ static QString detokenize(const TokenList& tokens); + /** + * @brief Translates token to string propert representation. + * @param token Token to translate. + * @return Translated string. + * + * This method applies wrappers where needed (for strings and ids). + */ + static QString detokenize(const TokenPtr& token); + /** * @brief Tokenizes given SQL query with given dialect. * @param sql SQL query to tokenize. diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/sqlite3_parse.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/sqlite3_parse.cpp index 9ff6487..43cc4a0 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/sqlite3_parse.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/sqlite3_parse.cpp @@ -170,7 +170,7 @@ typedef union { #define sqlite3_parseARG_PDECL ,ParserContext* parserContext #define sqlite3_parseARG_FETCH ParserContext* parserContext = yypParser->parserContext #define sqlite3_parseARG_STORE yypParser->parserContext = parserContext -#define YYNSTATE 724 +#define YYNSTATE 725 #define YYNRULE 424 #define YYFALLBACK 1 #define YY_NO_ACTION (YYNSTATE+YYNRULE+2) @@ -243,235 +243,237 @@ static const YYMINORTYPE yyzerominor = { 0 }; ** shifting non-terminals after a reduce. ** yy_default[] Default action for each state. */ -#define YY_ACTTAB_COUNT (2263) +#define YY_ACTTAB_COUNT (2285) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 431, 48, 48, 47, 47, 47, 46, 216, 716, 339, - /* 10 */ 643, 425, 51, 51, 51, 51, 44, 49, 49, 49, - /* 20 */ 49, 48, 48, 47, 47, 47, 46, 216, 721, 1026, - /* 30 */ 1026, 643, 131, 580, 51, 51, 51, 51, 411, 49, - /* 40 */ 49, 49, 49, 48, 48, 47, 47, 47, 46, 216, - /* 50 */ 579, 81, 58, 643, 157, 685, 301, 282, 1026, 1026, - /* 60 */ 41, 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1026, - /* 70 */ 1026, 1026, 563, 1026, 1026, 1026, 1026, 38, 39, 1026, - /* 80 */ 1026, 1026, 1026, 1026, 40, 431, 528, 385, 716, 595, - /* 90 */ 594, 280, 4, 377, 716, 630, 425, 642, 608, 422, - /* 100 */ 12, 134, 687, 429, 562, 609, 483, 690, 331, 279, - /* 110 */ 714, 713, 564, 565, 642, 689, 688, 687, 235, 506, - /* 120 */ 60, 320, 610, 411, 47, 47, 47, 46, 216, 122, - /* 130 */ 243, 213, 247, 59, 1142, 1142, 486, 609, 607, 603, - /* 140 */ 685, 306, 485, 584, 716, 41, 507, 509, 642, 508, - /* 150 */ 676, 9, 642, 144, 95, 281, 379, 276, 378, 132, - /* 160 */ 297, 716, 38, 39, 601, 200, 199, 7, 355, 40, - /* 170 */ 884, 307, 1134, 274, 249, 716, 17, 4, 884, 1134, - /* 180 */ 56, 717, 642, 431, 422, 884, 329, 687, 429, 716, - /* 190 */ 687, 643, 690, 687, 425, 690, 714, 713, 690, 642, - /* 200 */ 689, 688, 687, 689, 688, 687, 689, 688, 687, 98, - /* 210 */ 682, 240, 643, 218, 410, 884, 486, 884, 884, 483, - /* 220 */ 716, 411, 239, 884, 303, 582, 512, 581, 884, 884, - /* 230 */ 884, 884, 884, 642, 643, 676, 9, 642, 685, 217, - /* 240 */ 245, 673, 102, 41, 287, 300, 714, 713, 67, 302, - /* 250 */ 148, 307, 1133, 151, 306, 484, 81, 715, 97, 1133, - /* 260 */ 38, 39, 551, 714, 713, 771, 130, 40, 946, 376, - /* 270 */ 373, 372, 447, 46, 216, 4, 946, 714, 713, 334, - /* 280 */ 642, 682, 422, 946, 606, 687, 429, 371, 448, 447, - /* 290 */ 690, 714, 713, 304, 265, 146, 267, 642, 689, 688, - /* 300 */ 687, 287, 68, 677, 691, 255, 362, 259, 359, 692, - /* 310 */ 1027, 1027, 682, 946, 715, 946, 946, 447, 698, 234, - /* 320 */ 386, 715, 714, 713, 773, 651, 946, 946, 946, 946, - /* 330 */ 110, 642, 317, 676, 9, 642, 222, 677, 299, 52, - /* 340 */ 53, 426, 289, 1027, 1027, 675, 675, 50, 50, 51, - /* 350 */ 51, 51, 51, 716, 49, 49, 49, 49, 48, 48, - /* 360 */ 47, 47, 47, 46, 216, 431, 428, 340, 716, 335, - /* 370 */ 671, 670, 287, 283, 716, 138, 425, 209, 219, 430, - /* 380 */ 268, 395, 651, 682, 336, 715, 715, 686, 187, 52, - /* 390 */ 53, 426, 289, 715, 452, 675, 675, 50, 50, 51, - /* 400 */ 51, 51, 51, 411, 49, 49, 49, 49, 48, 48, - /* 410 */ 47, 47, 47, 46, 216, 91, 953, 716, 619, 712, - /* 420 */ 685, 403, 382, 130, 710, 41, 376, 373, 372, 711, - /* 430 */ 233, 953, 394, 311, 210, 593, 666, 384, 428, 16, - /* 440 */ 316, 659, 38, 39, 371, 231, 230, 716, 89, 40, - /* 450 */ 931, 430, 716, 658, 716, 714, 713, 4, 931, 686, - /* 460 */ 92, 143, 642, 358, 422, 931, 674, 687, 429, 14, - /* 470 */ 714, 713, 690, 131, 456, 551, 714, 713, 953, 642, - /* 480 */ 689, 688, 687, 668, 667, 210, 593, 458, 384, 457, - /* 490 */ 576, 88, 1027, 1027, 13, 931, 672, 931, 931, 54, - /* 500 */ 575, 678, 42, 368, 37, 401, 35, 381, 931, 1, - /* 510 */ 931, 931, 641, 642, 634, 676, 9, 642, 661, 714, - /* 520 */ 713, 52, 53, 426, 289, 1027, 1027, 675, 675, 50, - /* 530 */ 50, 51, 51, 51, 51, 660, 49, 49, 49, 49, - /* 540 */ 48, 48, 47, 47, 47, 46, 216, 657, 648, 714, - /* 550 */ 713, 496, 542, 569, 714, 713, 714, 713, 656, 691, - /* 560 */ 543, 614, 320, 30, 692, 27, 716, 585, 274, 682, - /* 570 */ 160, 1027, 1027, 426, 289, 693, 613, 675, 675, 50, - /* 580 */ 50, 51, 51, 51, 51, 398, 49, 49, 49, 49, - /* 590 */ 48, 48, 47, 47, 47, 46, 216, 1025, 1025, 81, - /* 600 */ 52, 53, 426, 289, 1027, 1027, 675, 675, 50, 50, - /* 610 */ 51, 51, 51, 51, 496, 49, 49, 49, 49, 48, - /* 620 */ 48, 47, 47, 47, 46, 216, 1025, 1025, 1025, 1025, - /* 630 */ 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, - /* 640 */ 716, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, - /* 650 */ 1025, 1025, 1027, 1027, 357, 49, 49, 49, 49, 48, - /* 660 */ 48, 47, 47, 47, 46, 216, 288, 552, 714, 713, - /* 670 */ 495, 682, 298, 662, 346, 153, 538, 69, 694, 715, - /* 680 */ 715, 52, 53, 426, 289, 1027, 1027, 675, 675, 50, - /* 690 */ 50, 51, 51, 51, 51, 1094, 49, 49, 49, 49, - /* 700 */ 48, 48, 47, 47, 47, 46, 216, 52, 53, 426, - /* 710 */ 289, 418, 511, 675, 675, 50, 50, 51, 51, 51, - /* 720 */ 51, 159, 49, 49, 49, 49, 48, 48, 47, 47, - /* 730 */ 47, 46, 216, 490, 954, 315, 482, 482, 663, 553, - /* 740 */ 215, 650, 714, 713, 81, 52, 53, 426, 289, 954, - /* 750 */ 414, 675, 675, 50, 50, 51, 51, 51, 51, 397, - /* 760 */ 49, 49, 49, 49, 48, 48, 47, 47, 47, 46, - /* 770 */ 216, 158, 1094, 21, 716, 627, 459, 716, 1079, 716, - /* 780 */ 647, 1045, 140, 89, 716, 1149, 154, 435, 2, 715, - /* 790 */ 424, 671, 670, 396, 460, 461, 954, 52, 53, 426, - /* 800 */ 289, 573, 716, 675, 675, 50, 50, 51, 51, 51, - /* 810 */ 51, 321, 49, 49, 49, 49, 48, 48, 47, 47, - /* 820 */ 47, 46, 216, 431, 1108, 81, 206, 205, 204, 52, - /* 830 */ 53, 426, 289, 716, 425, 675, 675, 50, 50, 51, - /* 840 */ 51, 51, 51, 344, 49, 49, 49, 49, 48, 48, - /* 850 */ 47, 47, 47, 46, 216, 597, 715, 666, 600, 462, - /* 860 */ 666, 411, 31, 716, 657, 90, 12, 894, 720, 668, - /* 870 */ 667, 609, 724, 434, 81, 656, 714, 713, 685, 714, - /* 880 */ 713, 714, 713, 41, 528, 272, 714, 713, 610, 349, - /* 890 */ 528, 450, 89, 677, 12, 633, 633, 338, 636, 609, - /* 900 */ 38, 39, 649, 609, 714, 713, 716, 40, 1142, 1142, - /* 910 */ 716, 524, 682, 581, 716, 4, 610, 468, 60, 450, - /* 920 */ 642, 208, 422, 506, 60, 687, 429, 677, 32, 109, - /* 930 */ 690, 609, 500, 501, 352, 714, 713, 642, 689, 688, - /* 940 */ 687, 428, 900, 900, 467, 466, 552, 465, 421, 383, - /* 950 */ 507, 509, 142, 508, 430, 440, 69, 1142, 1142, 715, - /* 960 */ 444, 722, 686, 182, 646, 714, 713, 645, 231, 230, - /* 970 */ 437, 642, 356, 676, 9, 642, 417, 444, 52, 53, - /* 980 */ 426, 289, 91, 91, 675, 675, 50, 50, 51, 51, - /* 990 */ 51, 51, 644, 49, 49, 49, 49, 48, 48, 47, - /* 1000 */ 47, 47, 46, 216, 1034, 444, 668, 667, 714, 713, - /* 1010 */ 91, 453, 714, 713, 682, 641, 714, 713, 324, 202, - /* 1020 */ 52, 53, 426, 289, 446, 680, 675, 675, 50, 50, - /* 1030 */ 51, 51, 51, 51, 639, 49, 49, 49, 49, 48, - /* 1040 */ 48, 47, 47, 47, 46, 216, 605, 52, 53, 426, - /* 1050 */ 289, 716, 446, 675, 675, 50, 50, 51, 51, 51, - /* 1060 */ 51, 459, 49, 49, 49, 49, 48, 48, 47, 47, - /* 1070 */ 47, 46, 216, 453, 715, 36, 663, 423, 215, 460, - /* 1080 */ 341, 369, 592, 52, 53, 426, 289, 638, 89, 675, - /* 1090 */ 675, 50, 50, 51, 51, 51, 51, 31, 49, 49, - /* 1100 */ 49, 49, 48, 48, 47, 47, 47, 46, 216, 413, - /* 1110 */ 723, 2, 11, 52, 53, 426, 289, 33, 588, 675, - /* 1120 */ 675, 50, 50, 51, 51, 51, 51, 624, 49, 49, - /* 1130 */ 49, 49, 48, 48, 47, 47, 47, 46, 216, 515, - /* 1140 */ 715, 537, 29, 91, 342, 666, 140, 136, 571, 52, - /* 1150 */ 53, 426, 289, 714, 713, 675, 675, 50, 50, 51, - /* 1160 */ 51, 51, 51, 548, 49, 49, 49, 49, 48, 48, - /* 1170 */ 47, 47, 47, 46, 216, 91, 716, 234, 386, 52, - /* 1180 */ 53, 426, 289, 338, 271, 675, 675, 50, 50, 51, - /* 1190 */ 51, 51, 51, 333, 49, 49, 49, 49, 48, 48, - /* 1200 */ 47, 47, 47, 46, 216, 532, 8, 517, 696, 87, - /* 1210 */ 137, 52, 53, 426, 289, 22, 557, 675, 675, 50, - /* 1220 */ 50, 51, 51, 51, 51, 135, 49, 49, 49, 49, - /* 1230 */ 48, 48, 47, 47, 47, 46, 216, 81, 1109, 91, - /* 1240 */ 716, 91, 52, 53, 426, 289, 615, 722, 675, 675, - /* 1250 */ 50, 50, 51, 51, 51, 51, 620, 49, 49, 49, - /* 1260 */ 49, 48, 48, 47, 47, 47, 46, 216, 604, 1107, - /* 1270 */ 99, 504, 390, 491, 52, 53, 426, 289, 714, 713, - /* 1280 */ 675, 675, 50, 50, 51, 51, 51, 51, 682, 49, - /* 1290 */ 49, 49, 49, 48, 48, 47, 47, 47, 46, 216, - /* 1300 */ 226, 52, 57, 426, 289, 599, 388, 675, 675, 50, - /* 1310 */ 50, 51, 51, 51, 51, 428, 49, 49, 49, 49, - /* 1320 */ 48, 48, 47, 47, 47, 46, 216, 431, 430, 5, - /* 1330 */ 10, 620, 620, 632, 491, 631, 686, 187, 425, 53, - /* 1340 */ 426, 289, 714, 713, 675, 675, 50, 50, 51, 51, - /* 1350 */ 51, 51, 716, 49, 49, 49, 49, 48, 48, 47, - /* 1360 */ 47, 47, 46, 216, 552, 411, 598, 107, 464, 591, - /* 1370 */ 403, 387, 428, 697, 69, 612, 611, 715, 428, 716, - /* 1380 */ 404, 715, 685, 716, 209, 430, 209, 41, 625, 316, - /* 1390 */ 682, 430, 596, 686, 187, 428, 223, 590, 539, 686, - /* 1400 */ 187, 653, 287, 716, 38, 39, 589, 225, 430, 718, - /* 1410 */ 431, 40, 620, 716, 91, 715, 686, 187, 252, 4, - /* 1420 */ 570, 425, 715, 19, 642, 89, 422, 403, 405, 687, - /* 1430 */ 429, 716, 624, 332, 690, 716, 428, 328, 716, 705, - /* 1440 */ 716, 642, 689, 688, 687, 715, 316, 266, 411, 430, - /* 1450 */ 561, 365, 316, 716, 714, 713, 602, 686, 187, 488, - /* 1460 */ 715, 829, 716, 375, 65, 685, 308, 682, 540, 406, - /* 1470 */ 41, 706, 285, 209, 273, 642, 475, 676, 9, 642, - /* 1480 */ 530, 714, 713, 651, 715, 714, 713, 38, 39, 64, - /* 1490 */ 18, 399, 370, 431, 40, 129, 716, 366, 326, 534, - /* 1500 */ 534, 63, 4, 270, 425, 714, 713, 642, 475, 422, - /* 1510 */ 316, 530, 687, 429, 716, 714, 713, 690, 279, 716, - /* 1520 */ 533, 716, 156, 624, 642, 689, 688, 687, 525, 716, - /* 1530 */ 125, 411, 519, 714, 713, 514, 715, 714, 713, 3, - /* 1540 */ 714, 713, 714, 713, 79, 525, 682, 85, 685, 519, - /* 1550 */ 479, 26, 514, 41, 25, 714, 713, 516, 642, 472, - /* 1560 */ 676, 9, 642, 716, 714, 713, 407, 479, 716, 682, - /* 1570 */ 38, 39, 353, 77, 286, 431, 510, 40, 283, 505, - /* 1580 */ 555, 428, 616, 503, 83, 4, 425, 715, 140, 351, - /* 1590 */ 642, 715, 422, 469, 430, 687, 429, 716, 714, 713, - /* 1600 */ 690, 716, 686, 192, 472, 428, 703, 642, 689, 688, - /* 1610 */ 687, 438, 428, 411, 497, 62, 714, 713, 430, 119, - /* 1620 */ 254, 714, 713, 714, 713, 430, 686, 181, 438, 704, - /* 1630 */ 685, 714, 713, 686, 163, 41, 251, 629, 311, 161, - /* 1640 */ 138, 642, 715, 676, 9, 642, 455, 1035, 682, 531, - /* 1650 */ 701, 702, 38, 39, 152, 641, 498, 469, 431, 40, - /* 1660 */ 499, 478, 699, 428, 715, 714, 713, 4, 1037, 425, - /* 1670 */ 714, 713, 642, 416, 422, 715, 430, 687, 429, 641, - /* 1680 */ 428, 350, 690, 619, 686, 172, 641, 494, 454, 642, - /* 1690 */ 689, 688, 687, 430, 111, 428, 411, 716, 72, 714, - /* 1700 */ 713, 686, 190, 714, 713, 621, 287, 337, 430, 428, - /* 1710 */ 436, 428, 96, 685, 209, 558, 686, 188, 41, 715, - /* 1720 */ 567, 287, 430, 642, 430, 676, 9, 642, 716, 207, - /* 1730 */ 686, 196, 686, 195, 715, 38, 39, 641, 716, 286, - /* 1740 */ 431, 327, 40, 224, 86, 428, 695, 319, 203, 428, - /* 1750 */ 4, 425, 715, 318, 641, 642, 325, 422, 430, 715, - /* 1760 */ 687, 429, 430, 150, 261, 690, 686, 197, 221, 641, - /* 1770 */ 686, 201, 642, 689, 688, 687, 428, 715, 411, 716, - /* 1780 */ 719, 709, 708, 641, 433, 641, 707, 651, 258, 430, - /* 1790 */ 428, 283, 220, 536, 428, 685, 149, 686, 232, 714, - /* 1800 */ 713, 715, 651, 430, 715, 147, 642, 430, 676, 9, - /* 1810 */ 642, 686, 290, 428, 82, 686, 191, 38, 39, 641, - /* 1820 */ 679, 367, 432, 641, 40, 15, 430, 145, 700, 234, - /* 1830 */ 714, 713, 4, 715, 686, 194, 408, 642, 420, 422, - /* 1840 */ 714, 713, 687, 429, 716, 428, 684, 690, 637, 715, - /* 1850 */ 641, 227, 428, 294, 642, 689, 688, 687, 430, 716, - /* 1860 */ 293, 715, 428, 17, 641, 430, 686, 193, 641, 292, - /* 1870 */ 400, 291, 402, 686, 185, 430, 521, 28, 683, 55, - /* 1880 */ 428, 714, 713, 686, 189, 43, 428, 641, 642, 640, - /* 1890 */ 676, 9, 642, 430, 216, 419, 428, 66, 529, 430, - /* 1900 */ 428, 686, 314, 428, 229, 214, 228, 686, 313, 430, - /* 1910 */ 428, 415, 34, 430, 141, 626, 430, 686, 312, 641, - /* 1920 */ 428, 686, 184, 430, 686, 171, 641, 428, 715, 635, - /* 1930 */ 139, 686, 170, 430, 108, 386, 641, 716, 463, 622, - /* 1940 */ 430, 686, 183, 428, 617, 428, 714, 713, 686, 169, - /* 1950 */ 428, 716, 715, 389, 641, 583, 430, 715, 430, 380, - /* 1960 */ 641, 714, 713, 430, 686, 186, 686, 168, 428, 716, - /* 1970 */ 641, 686, 167, 541, 641, 428, 578, 641, 716, 257, - /* 1980 */ 133, 430, 577, 256, 641, 428, 474, 428, 430, 686, - /* 1990 */ 93, 428, 715, 715, 641, 716, 686, 166, 430, 716, - /* 2000 */ 430, 641, 330, 716, 430, 716, 686, 164, 686, 174, - /* 2010 */ 428, 277, 686, 173, 393, 428, 275, 641, 716, 641, - /* 2020 */ 716, 568, 574, 430, 641, 428, 573, 715, 430, 715, - /* 2030 */ 428, 686, 175, 489, 715, 428, 686, 178, 430, 714, - /* 2040 */ 713, 572, 641, 430, 716, 428, 686, 94, 430, 641, - /* 2050 */ 310, 686, 177, 714, 713, 128, 686, 176, 430, 641, - /* 2060 */ 554, 641, 549, 716, 428, 641, 686, 180, 716, 428, - /* 2070 */ 716, 714, 713, 716, 392, 715, 547, 430, 546, 545, - /* 2080 */ 714, 713, 430, 502, 641, 686, 179, 430, 544, 641, - /* 2090 */ 686, 165, 527, 309, 80, 686, 70, 714, 713, 641, - /* 2100 */ 535, 714, 713, 269, 641, 714, 713, 714, 713, 641, - /* 2110 */ 127, 106, 471, 523, 248, 263, 715, 518, 481, 641, - /* 2120 */ 714, 713, 714, 713, 476, 212, 246, 715, 715, 244, - /* 2130 */ 477, 126, 492, 473, 480, 262, 242, 354, 641, 715, - /* 2140 */ 470, 236, 715, 641, 360, 322, 714, 713, 641, 715, - /* 2150 */ 347, 363, 24, 652, 715, 442, 427, 715, 443, 441, - /* 2160 */ 124, 284, 526, 715, 648, 714, 713, 264, 715, 715, - /* 2170 */ 714, 713, 714, 713, 715, 714, 713, 253, 78, 250, - /* 2180 */ 715, 241, 237, 238, 105, 123, 121, 84, 104, 155, - /* 2190 */ 715, 513, 715, 120, 715, 715, 715, 493, 348, 103, - /* 2200 */ 118, 345, 76, 343, 117, 75, 116, 115, 114, 74, - /* 2210 */ 73, 113, 23, 323, 451, 101, 20, 100, 623, 112, - /* 2220 */ 61, 520, 449, 445, 439, 655, 628, 162, 278, 669, - /* 2230 */ 665, 412, 569, 295, 681, 198, 374, 522, 618, 260, - /* 2240 */ 361, 6, 305, 664, 654, 556, 364, 409, 566, 211, - /* 2250 */ 296, 71, 560, 559, 487, 587, 586, 81, 550, 1150, - /* 2260 */ 1150, 1150, 45, + /* 0 */ 432, 49, 49, 48, 48, 48, 47, 216, 717, 340, + /* 10 */ 644, 426, 52, 52, 52, 52, 45, 50, 50, 50, + /* 20 */ 50, 49, 49, 48, 48, 48, 47, 216, 722, 1027, + /* 30 */ 1027, 644, 131, 581, 52, 52, 52, 52, 412, 50, + /* 40 */ 50, 50, 50, 49, 49, 48, 48, 48, 47, 216, + /* 50 */ 580, 81, 59, 644, 157, 686, 302, 283, 1027, 1027, + /* 60 */ 42, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, + /* 70 */ 1027, 1027, 564, 1027, 1027, 1027, 1027, 39, 40, 1027, + /* 80 */ 1027, 1027, 1027, 1027, 41, 432, 529, 386, 717, 596, + /* 90 */ 595, 281, 4, 378, 717, 631, 426, 643, 609, 423, + /* 100 */ 13, 134, 688, 430, 563, 610, 484, 691, 332, 280, + /* 110 */ 715, 714, 565, 566, 643, 690, 689, 688, 235, 507, + /* 120 */ 61, 321, 611, 412, 48, 48, 48, 47, 216, 122, + /* 130 */ 243, 213, 247, 60, 1143, 1143, 487, 610, 608, 604, + /* 140 */ 686, 307, 486, 585, 717, 42, 508, 510, 643, 509, + /* 150 */ 677, 9, 643, 144, 95, 282, 380, 277, 379, 132, + /* 160 */ 298, 717, 39, 40, 602, 200, 199, 7, 356, 41, + /* 170 */ 885, 308, 1135, 275, 249, 717, 18, 4, 885, 1135, + /* 180 */ 57, 718, 643, 432, 423, 885, 330, 688, 430, 717, + /* 190 */ 688, 644, 691, 688, 426, 691, 715, 714, 691, 643, + /* 200 */ 690, 689, 688, 690, 689, 688, 690, 689, 688, 98, + /* 210 */ 683, 240, 644, 218, 411, 885, 487, 885, 885, 484, + /* 220 */ 717, 412, 239, 885, 304, 583, 513, 582, 885, 885, + /* 230 */ 885, 885, 885, 643, 644, 677, 9, 643, 686, 217, + /* 240 */ 245, 674, 102, 42, 288, 301, 715, 714, 67, 303, + /* 250 */ 148, 308, 1134, 151, 307, 485, 81, 716, 97, 1134, + /* 260 */ 39, 40, 552, 715, 714, 772, 130, 41, 947, 377, + /* 270 */ 374, 373, 448, 47, 216, 4, 947, 715, 714, 335, + /* 280 */ 643, 683, 423, 947, 607, 688, 430, 372, 449, 448, + /* 290 */ 691, 715, 714, 305, 265, 146, 268, 643, 690, 689, + /* 300 */ 688, 288, 68, 678, 692, 255, 363, 259, 360, 693, + /* 310 */ 1028, 1028, 683, 947, 716, 947, 947, 448, 699, 234, + /* 320 */ 387, 716, 715, 714, 774, 652, 947, 947, 947, 947, + /* 330 */ 110, 643, 318, 677, 9, 643, 222, 678, 300, 53, + /* 340 */ 54, 427, 290, 1028, 1028, 676, 676, 51, 51, 52, + /* 350 */ 52, 52, 52, 717, 50, 50, 50, 50, 49, 49, + /* 360 */ 48, 48, 48, 47, 216, 432, 429, 341, 717, 336, + /* 370 */ 672, 671, 288, 284, 717, 138, 426, 209, 219, 431, + /* 380 */ 269, 396, 652, 683, 337, 716, 716, 687, 187, 53, + /* 390 */ 54, 427, 290, 716, 453, 676, 676, 51, 51, 52, + /* 400 */ 52, 52, 52, 412, 50, 50, 50, 50, 49, 49, + /* 410 */ 48, 48, 48, 47, 216, 91, 954, 717, 620, 713, + /* 420 */ 686, 404, 383, 130, 711, 42, 377, 374, 373, 712, + /* 430 */ 233, 954, 395, 312, 210, 594, 667, 385, 429, 17, + /* 440 */ 317, 660, 39, 40, 372, 231, 230, 717, 89, 41, + /* 450 */ 932, 431, 717, 659, 717, 715, 714, 4, 932, 687, + /* 460 */ 92, 143, 643, 359, 423, 932, 675, 688, 430, 15, + /* 470 */ 715, 714, 691, 131, 457, 552, 715, 714, 954, 643, + /* 480 */ 690, 689, 688, 669, 668, 210, 594, 459, 385, 458, + /* 490 */ 577, 88, 1028, 1028, 14, 932, 673, 932, 932, 55, + /* 500 */ 576, 679, 43, 369, 38, 402, 36, 382, 932, 1, + /* 510 */ 932, 932, 642, 643, 635, 677, 9, 643, 662, 715, + /* 520 */ 714, 53, 54, 427, 290, 1028, 1028, 676, 676, 51, + /* 530 */ 51, 52, 52, 52, 52, 661, 50, 50, 50, 50, + /* 540 */ 49, 49, 48, 48, 48, 47, 216, 658, 649, 715, + /* 550 */ 714, 497, 543, 570, 715, 714, 715, 714, 657, 692, + /* 560 */ 544, 615, 321, 31, 693, 28, 717, 586, 275, 683, + /* 570 */ 160, 1028, 1028, 427, 290, 694, 614, 676, 676, 51, + /* 580 */ 51, 52, 52, 52, 52, 399, 50, 50, 50, 50, + /* 590 */ 49, 49, 48, 48, 48, 47, 216, 1026, 1026, 81, + /* 600 */ 53, 54, 427, 290, 1028, 1028, 676, 676, 51, 51, + /* 610 */ 52, 52, 52, 52, 497, 50, 50, 50, 50, 49, + /* 620 */ 49, 48, 48, 48, 47, 216, 1026, 1026, 1026, 1026, + /* 630 */ 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1026, + /* 640 */ 717, 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1026, + /* 650 */ 1026, 1026, 1028, 1028, 358, 50, 50, 50, 50, 49, + /* 660 */ 49, 48, 48, 48, 47, 216, 289, 553, 715, 714, + /* 670 */ 496, 683, 299, 663, 347, 153, 539, 69, 695, 716, + /* 680 */ 716, 53, 54, 427, 290, 1028, 1028, 676, 676, 51, + /* 690 */ 51, 52, 52, 52, 52, 1095, 50, 50, 50, 50, + /* 700 */ 49, 49, 48, 48, 48, 47, 216, 53, 54, 427, + /* 710 */ 290, 419, 512, 676, 676, 51, 51, 52, 52, 52, + /* 720 */ 52, 159, 50, 50, 50, 50, 49, 49, 48, 48, + /* 730 */ 48, 47, 216, 491, 955, 316, 483, 483, 664, 554, + /* 740 */ 215, 651, 715, 714, 81, 53, 54, 427, 290, 955, + /* 750 */ 415, 676, 676, 51, 51, 52, 52, 52, 52, 398, + /* 760 */ 50, 50, 50, 50, 49, 49, 48, 48, 48, 47, + /* 770 */ 216, 158, 1095, 22, 717, 628, 460, 717, 1080, 717, + /* 780 */ 648, 1046, 140, 89, 717, 1150, 154, 436, 2, 716, + /* 790 */ 425, 672, 671, 397, 461, 462, 955, 53, 54, 427, + /* 800 */ 290, 574, 717, 676, 676, 51, 51, 52, 52, 52, + /* 810 */ 52, 322, 50, 50, 50, 50, 49, 49, 48, 48, + /* 820 */ 48, 47, 216, 432, 1109, 81, 206, 205, 204, 53, + /* 830 */ 54, 427, 290, 717, 426, 676, 676, 51, 51, 52, + /* 840 */ 52, 52, 52, 345, 50, 50, 50, 50, 49, 49, + /* 850 */ 48, 48, 48, 47, 216, 598, 716, 667, 601, 463, + /* 860 */ 667, 412, 32, 717, 658, 90, 13, 895, 721, 669, + /* 870 */ 668, 610, 725, 435, 81, 657, 715, 714, 686, 715, + /* 880 */ 714, 715, 714, 42, 529, 273, 715, 714, 611, 350, + /* 890 */ 529, 451, 89, 678, 13, 634, 634, 339, 637, 610, + /* 900 */ 39, 40, 650, 610, 715, 714, 717, 41, 1143, 1143, + /* 910 */ 717, 525, 683, 582, 717, 4, 611, 469, 61, 451, + /* 920 */ 643, 208, 423, 507, 61, 688, 430, 678, 33, 109, + /* 930 */ 691, 610, 501, 502, 353, 715, 714, 643, 690, 689, + /* 940 */ 688, 429, 901, 901, 468, 467, 553, 466, 422, 384, + /* 950 */ 508, 510, 142, 509, 431, 441, 69, 1143, 1143, 716, + /* 960 */ 445, 723, 687, 182, 647, 715, 714, 646, 231, 230, + /* 970 */ 438, 643, 357, 677, 9, 643, 418, 445, 53, 54, + /* 980 */ 427, 290, 91, 91, 676, 676, 51, 51, 52, 52, + /* 990 */ 52, 52, 645, 50, 50, 50, 50, 49, 49, 48, + /* 1000 */ 48, 48, 47, 216, 1035, 445, 669, 668, 715, 714, + /* 1010 */ 91, 454, 715, 714, 683, 642, 715, 714, 325, 202, + /* 1020 */ 53, 54, 427, 290, 447, 681, 676, 676, 51, 51, + /* 1030 */ 52, 52, 52, 52, 640, 50, 50, 50, 50, 49, + /* 1040 */ 49, 48, 48, 48, 47, 216, 606, 53, 54, 427, + /* 1050 */ 290, 717, 447, 676, 676, 51, 51, 52, 52, 52, + /* 1060 */ 52, 460, 50, 50, 50, 50, 49, 49, 48, 48, + /* 1070 */ 48, 47, 216, 454, 716, 37, 664, 424, 215, 461, + /* 1080 */ 342, 370, 593, 53, 54, 427, 290, 639, 89, 676, + /* 1090 */ 676, 51, 51, 52, 52, 52, 52, 32, 50, 50, + /* 1100 */ 50, 50, 49, 49, 48, 48, 48, 47, 216, 414, + /* 1110 */ 724, 2, 12, 53, 54, 427, 290, 34, 589, 676, + /* 1120 */ 676, 51, 51, 52, 52, 52, 52, 625, 50, 50, + /* 1130 */ 50, 50, 49, 49, 48, 48, 48, 47, 216, 516, + /* 1140 */ 716, 538, 30, 91, 343, 667, 140, 136, 572, 53, + /* 1150 */ 54, 427, 290, 715, 714, 676, 676, 51, 51, 52, + /* 1160 */ 52, 52, 52, 549, 50, 50, 50, 50, 49, 49, + /* 1170 */ 48, 48, 48, 47, 216, 91, 717, 234, 387, 53, + /* 1180 */ 54, 427, 290, 339, 272, 676, 676, 51, 51, 52, + /* 1190 */ 52, 52, 52, 334, 50, 50, 50, 50, 49, 49, + /* 1200 */ 48, 48, 48, 47, 216, 533, 8, 518, 697, 87, + /* 1210 */ 137, 53, 54, 427, 290, 23, 558, 676, 676, 51, + /* 1220 */ 51, 52, 52, 52, 52, 135, 50, 50, 50, 50, + /* 1230 */ 49, 49, 48, 48, 48, 47, 216, 81, 1110, 91, + /* 1240 */ 717, 91, 53, 54, 427, 290, 616, 723, 676, 676, + /* 1250 */ 51, 51, 52, 52, 52, 52, 605, 50, 50, 50, + /* 1260 */ 50, 49, 49, 48, 48, 48, 47, 216, 99, 1108, + /* 1270 */ 391, 505, 389, 492, 53, 54, 427, 290, 715, 714, + /* 1280 */ 676, 676, 51, 51, 52, 52, 52, 52, 621, 50, + /* 1290 */ 50, 50, 50, 49, 49, 48, 48, 48, 47, 216, + /* 1300 */ 683, 53, 58, 427, 290, 683, 600, 676, 676, 51, + /* 1310 */ 51, 52, 52, 52, 52, 429, 50, 50, 50, 50, + /* 1320 */ 49, 49, 48, 48, 48, 47, 216, 432, 431, 717, + /* 1330 */ 5, 621, 226, 633, 492, 632, 687, 187, 426, 54, + /* 1340 */ 427, 290, 715, 714, 676, 676, 51, 51, 52, 52, + /* 1350 */ 52, 52, 717, 50, 50, 50, 50, 49, 49, 48, + /* 1360 */ 48, 48, 47, 216, 553, 412, 288, 599, 287, 717, + /* 1370 */ 404, 388, 429, 698, 69, 613, 252, 716, 429, 716, + /* 1380 */ 405, 716, 686, 30, 209, 431, 209, 42, 626, 317, + /* 1390 */ 489, 431, 597, 687, 187, 429, 223, 309, 540, 687, + /* 1400 */ 187, 329, 683, 717, 39, 40, 11, 683, 431, 287, + /* 1410 */ 432, 41, 621, 654, 91, 592, 687, 92, 556, 4, + /* 1420 */ 571, 426, 716, 625, 643, 537, 423, 404, 406, 688, + /* 1430 */ 430, 715, 714, 333, 691, 717, 716, 429, 717, 591, + /* 1440 */ 717, 643, 690, 689, 688, 107, 317, 652, 412, 531, + /* 1450 */ 431, 590, 317, 717, 715, 714, 612, 830, 687, 187, + /* 1460 */ 429, 225, 326, 717, 541, 686, 526, 417, 20, 642, + /* 1470 */ 42, 715, 714, 431, 683, 643, 717, 677, 9, 643, + /* 1480 */ 531, 687, 187, 526, 562, 717, 621, 39, 40, 327, + /* 1490 */ 376, 65, 64, 432, 41, 274, 19, 266, 371, 535, + /* 1500 */ 535, 267, 4, 271, 426, 715, 714, 643, 421, 423, + /* 1510 */ 716, 407, 688, 430, 286, 400, 717, 691, 717, 280, + /* 1520 */ 717, 63, 129, 429, 643, 690, 689, 688, 367, 717, + /* 1530 */ 603, 412, 520, 534, 317, 515, 431, 715, 714, 156, + /* 1540 */ 715, 714, 715, 714, 687, 192, 717, 209, 686, 520, + /* 1550 */ 480, 465, 515, 42, 717, 715, 714, 3, 643, 717, + /* 1560 */ 677, 9, 643, 717, 716, 715, 714, 480, 138, 125, + /* 1570 */ 39, 40, 85, 476, 79, 432, 683, 41, 715, 714, + /* 1580 */ 27, 429, 473, 511, 717, 4, 426, 715, 714, 517, + /* 1590 */ 643, 532, 423, 408, 431, 688, 430, 642, 26, 719, + /* 1600 */ 691, 717, 687, 181, 77, 476, 506, 643, 690, 689, + /* 1610 */ 688, 620, 716, 412, 354, 470, 706, 439, 715, 714, + /* 1620 */ 715, 714, 715, 714, 261, 288, 717, 473, 221, 504, + /* 1630 */ 686, 715, 714, 704, 439, 42, 717, 716, 716, 568, + /* 1640 */ 83, 643, 140, 677, 9, 643, 498, 1036, 715, 714, + /* 1650 */ 702, 284, 39, 40, 254, 642, 715, 714, 432, 41, + /* 1660 */ 328, 715, 714, 429, 716, 715, 714, 4, 1038, 426, + /* 1670 */ 119, 10, 643, 503, 423, 707, 431, 688, 430, 470, + /* 1680 */ 429, 161, 691, 251, 687, 163, 715, 714, 716, 643, + /* 1690 */ 690, 689, 688, 431, 717, 429, 412, 152, 479, 456, + /* 1700 */ 455, 687, 172, 715, 714, 72, 652, 705, 431, 429, + /* 1710 */ 630, 312, 111, 686, 530, 338, 687, 190, 42, 437, + /* 1720 */ 716, 622, 431, 643, 96, 677, 9, 643, 715, 714, + /* 1730 */ 687, 188, 209, 717, 207, 39, 40, 642, 715, 714, + /* 1740 */ 432, 224, 41, 617, 86, 429, 703, 717, 203, 429, + /* 1750 */ 4, 426, 320, 720, 642, 643, 150, 423, 431, 716, + /* 1760 */ 688, 430, 431, 700, 429, 691, 687, 196, 475, 642, + /* 1770 */ 687, 195, 643, 690, 689, 688, 716, 431, 412, 717, + /* 1780 */ 319, 710, 717, 642, 522, 687, 197, 709, 708, 258, + /* 1790 */ 499, 429, 434, 220, 500, 686, 715, 714, 625, 16, + /* 1800 */ 42, 717, 716, 257, 431, 717, 643, 256, 677, 9, + /* 1810 */ 643, 716, 687, 201, 717, 351, 716, 39, 40, 642, + /* 1820 */ 149, 248, 432, 642, 41, 482, 147, 246, 433, 442, + /* 1830 */ 368, 478, 4, 426, 716, 715, 714, 643, 642, 423, + /* 1840 */ 716, 717, 715, 430, 82, 701, 429, 691, 685, 715, + /* 1850 */ 714, 145, 495, 234, 643, 690, 689, 688, 429, 431, + /* 1860 */ 412, 559, 244, 284, 352, 642, 474, 687, 232, 18, + /* 1870 */ 242, 431, 401, 429, 471, 716, 716, 686, 295, 687, + /* 1880 */ 291, 715, 714, 716, 715, 714, 431, 294, 643, 696, + /* 1890 */ 677, 9, 643, 542, 687, 191, 528, 293, 680, 39, + /* 1900 */ 40, 717, 716, 715, 714, 429, 41, 715, 714, 429, + /* 1910 */ 490, 716, 292, 29, 4, 493, 715, 714, 431, 643, + /* 1920 */ 642, 423, 431, 227, 688, 430, 687, 194, 429, 691, + /* 1930 */ 687, 193, 642, 429, 477, 429, 643, 690, 689, 688, + /* 1940 */ 429, 431, 717, 715, 714, 429, 431, 642, 431, 687, + /* 1950 */ 185, 717, 403, 431, 687, 189, 687, 315, 431, 717, + /* 1960 */ 216, 687, 314, 429, 409, 684, 687, 313, 717, 429, + /* 1970 */ 643, 56, 677, 9, 643, 44, 431, 716, 717, 642, + /* 1980 */ 638, 627, 431, 642, 687, 184, 623, 420, 236, 653, + /* 1990 */ 687, 171, 323, 716, 716, 641, 229, 66, 214, 716, + /* 2000 */ 429, 716, 642, 715, 714, 618, 35, 642, 228, 642, + /* 2010 */ 429, 133, 394, 431, 642, 524, 276, 429, 716, 642, + /* 2020 */ 429, 687, 170, 431, 716, 716, 636, 569, 416, 716, + /* 2030 */ 431, 687, 183, 431, 429, 550, 429, 642, 687, 169, + /* 2040 */ 716, 687, 186, 642, 715, 714, 429, 431, 716, 431, + /* 2050 */ 141, 429, 108, 715, 714, 687, 168, 687, 167, 431, + /* 2060 */ 139, 715, 714, 270, 431, 519, 429, 687, 93, 390, + /* 2070 */ 715, 714, 687, 166, 642, 717, 716, 429, 584, 431, + /* 2080 */ 715, 714, 481, 429, 642, 717, 381, 687, 164, 717, + /* 2090 */ 431, 642, 444, 579, 642, 578, 431, 387, 687, 174, + /* 2100 */ 429, 263, 429, 472, 687, 173, 429, 331, 642, 278, + /* 2110 */ 642, 574, 575, 431, 716, 431, 429, 361, 464, 431, + /* 2120 */ 642, 687, 175, 687, 178, 642, 429, 687, 94, 431, + /* 2130 */ 716, 429, 573, 429, 555, 548, 348, 687, 177, 431, + /* 2140 */ 642, 547, 546, 545, 431, 429, 431, 687, 176, 716, + /* 2150 */ 393, 642, 687, 180, 687, 179, 443, 642, 431, 536, + /* 2160 */ 428, 128, 285, 431, 311, 310, 687, 165, 80, 716, + /* 2170 */ 264, 687, 70, 716, 642, 716, 642, 715, 714, 366, + /* 2180 */ 642, 649, 253, 716, 106, 250, 127, 715, 714, 241, + /* 2190 */ 642, 715, 714, 237, 126, 716, 238, 262, 716, 355, + /* 2200 */ 642, 212, 716, 25, 124, 642, 716, 642, 527, 716, + /* 2210 */ 364, 78, 105, 123, 121, 155, 84, 514, 104, 642, + /* 2220 */ 120, 349, 494, 624, 642, 346, 103, 118, 76, 344, + /* 2230 */ 117, 75, 116, 115, 74, 73, 114, 521, 324, 113, + /* 2240 */ 24, 452, 450, 21, 101, 100, 112, 446, 62, 440, + /* 2250 */ 162, 296, 670, 666, 656, 413, 279, 619, 570, 198, + /* 2260 */ 629, 375, 523, 260, 362, 306, 6, 71, 682, 665, + /* 2270 */ 655, 557, 211, 297, 410, 567, 365, 46, 551, 561, + /* 2280 */ 560, 488, 588, 81, 587, }; static const YYCODETYPE yy_lookahead[] = { /* 0 */ 4, 81, 82, 83, 84, 85, 86, 87, 4, 58, @@ -599,271 +601,273 @@ static const YYCODETYPE yy_lookahead[] = { /* 1220 */ 71, 72, 73, 74, 75, 97, 77, 78, 79, 80, /* 1230 */ 81, 82, 83, 84, 85, 86, 87, 55, 89, 219, /* 1240 */ 4, 219, 62, 63, 64, 65, 30, 89, 68, 69, - /* 1250 */ 70, 71, 72, 73, 74, 75, 191, 77, 78, 79, - /* 1260 */ 80, 81, 82, 83, 84, 85, 86, 87, 144, 89, - /* 1270 */ 99, 89, 99, 101, 62, 63, 64, 65, 106, 107, - /* 1280 */ 68, 69, 70, 71, 72, 73, 74, 75, 4, 77, + /* 1250 */ 70, 71, 72, 73, 74, 75, 144, 77, 78, 79, + /* 1260 */ 80, 81, 82, 83, 84, 85, 86, 87, 99, 89, + /* 1270 */ 99, 89, 104, 101, 62, 63, 64, 65, 106, 107, + /* 1280 */ 68, 69, 70, 71, 72, 73, 74, 75, 191, 77, /* 1290 */ 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - /* 1300 */ 235, 62, 63, 64, 65, 83, 104, 68, 69, 70, + /* 1300 */ 4, 62, 63, 64, 65, 4, 83, 68, 69, 70, /* 1310 */ 71, 72, 73, 74, 75, 177, 77, 78, 79, 80, - /* 1320 */ 81, 82, 83, 84, 85, 86, 87, 4, 190, 96, - /* 1330 */ 96, 191, 191, 201, 162, 201, 198, 199, 15, 63, + /* 1320 */ 81, 82, 83, 84, 85, 86, 87, 4, 190, 4, + /* 1330 */ 96, 191, 235, 201, 162, 201, 198, 199, 15, 63, /* 1340 */ 64, 65, 106, 107, 68, 69, 70, 71, 72, 73, /* 1350 */ 74, 75, 4, 77, 78, 79, 80, 81, 82, 83, - /* 1360 */ 84, 85, 86, 87, 177, 42, 97, 17, 177, 97, - /* 1370 */ 232, 233, 177, 186, 187, 235, 235, 190, 177, 4, - /* 1380 */ 185, 190, 59, 4, 252, 190, 252, 64, 152, 251, - /* 1390 */ 106, 190, 135, 198, 199, 177, 209, 97, 211, 198, - /* 1400 */ 199, 117, 177, 4, 81, 82, 97, 38, 190, 177, - /* 1410 */ 4, 88, 191, 4, 219, 190, 198, 199, 97, 96, - /* 1420 */ 97, 15, 190, 96, 101, 104, 103, 232, 233, 106, - /* 1430 */ 107, 4, 177, 232, 111, 4, 177, 212, 4, 91, - /* 1440 */ 4, 118, 119, 120, 121, 190, 251, 177, 42, 190, - /* 1450 */ 6, 181, 251, 4, 106, 107, 235, 198, 199, 97, - /* 1460 */ 190, 97, 4, 38, 96, 59, 104, 4, 104, 251, - /* 1470 */ 64, 177, 254, 252, 97, 152, 101, 154, 155, 156, - /* 1480 */ 101, 106, 107, 258, 190, 106, 107, 81, 82, 96, - /* 1490 */ 96, 232, 38, 4, 88, 115, 4, 64, 243, 100, - /* 1500 */ 101, 96, 96, 97, 15, 106, 107, 101, 133, 103, - /* 1510 */ 251, 132, 106, 107, 4, 106, 107, 111, 129, 4, - /* 1520 */ 103, 4, 98, 177, 118, 119, 120, 121, 101, 4, - /* 1530 */ 123, 42, 101, 106, 107, 101, 190, 106, 107, 12, - /* 1540 */ 106, 107, 106, 107, 142, 118, 4, 128, 59, 118, - /* 1550 */ 101, 71, 118, 64, 71, 106, 107, 139, 152, 101, - /* 1560 */ 154, 155, 156, 4, 106, 107, 157, 118, 4, 106, - /* 1570 */ 81, 82, 22, 153, 177, 4, 89, 88, 177, 89, - /* 1580 */ 117, 177, 146, 47, 39, 96, 15, 190, 104, 243, - /* 1590 */ 101, 190, 103, 101, 190, 106, 107, 4, 106, 107, - /* 1600 */ 111, 4, 198, 199, 146, 177, 91, 118, 119, 120, - /* 1610 */ 121, 101, 177, 42, 39, 96, 106, 107, 190, 123, - /* 1620 */ 161, 106, 107, 106, 107, 190, 198, 199, 118, 177, - /* 1630 */ 59, 106, 107, 198, 199, 64, 95, 236, 237, 96, - /* 1640 */ 98, 152, 190, 154, 155, 156, 97, 158, 106, 132, - /* 1650 */ 91, 177, 81, 82, 143, 251, 7, 165, 4, 88, - /* 1660 */ 11, 103, 177, 177, 190, 106, 107, 96, 97, 15, - /* 1670 */ 106, 107, 101, 276, 103, 190, 190, 106, 107, 251, - /* 1680 */ 177, 32, 111, 141, 198, 199, 251, 162, 97, 118, - /* 1690 */ 119, 120, 121, 190, 93, 177, 42, 4, 95, 106, - /* 1700 */ 107, 198, 199, 106, 107, 141, 177, 37, 190, 177, - /* 1710 */ 36, 177, 189, 59, 252, 118, 198, 199, 64, 190, - /* 1720 */ 127, 177, 190, 152, 190, 154, 155, 156, 4, 238, - /* 1730 */ 198, 199, 198, 199, 190, 81, 82, 251, 4, 177, - /* 1740 */ 4, 212, 88, 204, 204, 177, 177, 275, 273, 177, - /* 1750 */ 96, 15, 190, 275, 251, 101, 212, 103, 190, 190, - /* 1760 */ 106, 107, 190, 90, 177, 111, 198, 199, 181, 251, - /* 1770 */ 198, 199, 118, 119, 120, 121, 177, 190, 42, 4, - /* 1780 */ 176, 176, 176, 251, 176, 251, 49, 258, 177, 190, - /* 1790 */ 177, 177, 181, 100, 177, 59, 178, 198, 199, 106, - /* 1800 */ 107, 190, 258, 190, 190, 178, 152, 190, 154, 155, - /* 1810 */ 156, 198, 199, 177, 180, 198, 199, 81, 82, 251, - /* 1820 */ 177, 60, 183, 251, 88, 104, 190, 56, 184, 138, - /* 1830 */ 106, 107, 96, 190, 198, 199, 177, 101, 276, 103, - /* 1840 */ 106, 107, 106, 107, 4, 177, 221, 111, 177, 190, - /* 1850 */ 251, 237, 177, 227, 118, 119, 120, 121, 190, 4, - /* 1860 */ 228, 190, 177, 151, 251, 190, 198, 199, 251, 229, - /* 1870 */ 148, 230, 147, 198, 199, 190, 152, 149, 231, 150, - /* 1880 */ 177, 106, 107, 198, 199, 252, 177, 251, 152, 64, - /* 1890 */ 154, 155, 156, 190, 87, 203, 177, 96, 164, 190, - /* 1900 */ 177, 198, 199, 177, 259, 87, 255, 198, 199, 190, - /* 1910 */ 177, 203, 158, 190, 99, 177, 190, 198, 199, 251, - /* 1920 */ 177, 198, 199, 190, 198, 199, 251, 177, 190, 241, - /* 1930 */ 241, 198, 199, 190, 99, 139, 251, 4, 163, 177, - /* 1940 */ 190, 198, 199, 177, 177, 177, 106, 107, 198, 199, - /* 1950 */ 177, 4, 190, 223, 251, 200, 190, 190, 190, 123, - /* 1960 */ 251, 106, 107, 190, 198, 199, 198, 199, 177, 4, - /* 1970 */ 251, 198, 199, 118, 251, 177, 200, 251, 4, 177, - /* 1980 */ 177, 190, 208, 181, 251, 177, 146, 177, 190, 198, - /* 1990 */ 199, 177, 190, 190, 251, 4, 198, 199, 190, 4, - /* 2000 */ 190, 251, 31, 4, 190, 4, 198, 199, 198, 199, - /* 2010 */ 177, 200, 198, 199, 177, 177, 177, 251, 4, 251, - /* 2020 */ 4, 177, 202, 190, 251, 177, 122, 190, 190, 190, - /* 2030 */ 177, 198, 199, 100, 190, 177, 198, 199, 190, 106, - /* 2040 */ 107, 200, 251, 190, 4, 177, 198, 199, 190, 251, - /* 2050 */ 203, 198, 199, 106, 107, 99, 198, 199, 190, 251, - /* 2060 */ 208, 251, 177, 4, 177, 251, 198, 199, 4, 177, - /* 2070 */ 4, 106, 107, 4, 177, 190, 200, 190, 200, 200, - /* 2080 */ 106, 107, 190, 118, 251, 198, 199, 190, 200, 251, - /* 2090 */ 198, 199, 118, 203, 180, 198, 199, 106, 107, 251, - /* 2100 */ 241, 106, 107, 177, 251, 106, 107, 106, 107, 251, - /* 2110 */ 99, 180, 165, 118, 177, 177, 190, 118, 181, 251, - /* 2120 */ 106, 107, 106, 107, 133, 241, 177, 190, 190, 177, - /* 2130 */ 181, 99, 118, 181, 118, 264, 177, 27, 251, 190, - /* 2140 */ 181, 177, 190, 251, 177, 181, 106, 107, 251, 190, - /* 2150 */ 177, 265, 158, 152, 190, 177, 177, 190, 118, 100, - /* 2160 */ 99, 177, 227, 190, 100, 106, 107, 177, 190, 190, - /* 2170 */ 106, 107, 106, 107, 190, 106, 107, 177, 215, 177, - /* 2180 */ 190, 177, 177, 177, 62, 99, 99, 96, 180, 250, - /* 2190 */ 190, 215, 190, 99, 190, 190, 190, 227, 241, 180, - /* 2200 */ 99, 241, 217, 60, 99, 217, 99, 99, 99, 217, - /* 2210 */ 217, 99, 268, 241, 18, 99, 268, 99, 152, 99, - /* 2220 */ 270, 152, 241, 241, 16, 201, 240, 224, 201, 261, - /* 2230 */ 261, 256, 206, 226, 191, 210, 202, 227, 242, 242, - /* 2240 */ 242, 224, 175, 191, 191, 191, 263, 216, 207, 262, - /* 2250 */ 222, 239, 207, 207, 274, 198, 198, 55, 211, 277, - /* 2260 */ 277, 277, 253, + /* 1360 */ 84, 85, 86, 87, 177, 42, 177, 97, 177, 4, + /* 1370 */ 232, 233, 177, 186, 187, 235, 97, 190, 177, 190, + /* 1380 */ 185, 190, 59, 104, 252, 190, 252, 64, 152, 251, + /* 1390 */ 97, 190, 135, 198, 199, 177, 209, 104, 211, 198, + /* 1400 */ 199, 212, 106, 4, 81, 82, 96, 106, 190, 177, + /* 1410 */ 4, 88, 191, 117, 219, 97, 198, 199, 117, 96, + /* 1420 */ 97, 15, 190, 177, 101, 100, 103, 232, 233, 106, + /* 1430 */ 107, 106, 107, 232, 111, 4, 190, 177, 4, 97, + /* 1440 */ 4, 118, 119, 120, 121, 17, 251, 258, 42, 101, + /* 1450 */ 190, 97, 251, 4, 106, 107, 235, 97, 198, 199, + /* 1460 */ 177, 38, 244, 4, 104, 59, 101, 276, 96, 251, + /* 1470 */ 64, 106, 107, 190, 4, 152, 4, 154, 155, 156, + /* 1480 */ 132, 198, 199, 118, 6, 4, 191, 81, 82, 243, + /* 1490 */ 38, 96, 96, 4, 88, 97, 96, 177, 38, 100, + /* 1500 */ 101, 181, 96, 97, 15, 106, 107, 101, 276, 103, + /* 1510 */ 190, 251, 106, 107, 254, 232, 4, 111, 4, 129, + /* 1520 */ 4, 96, 115, 177, 118, 119, 120, 121, 64, 4, + /* 1530 */ 235, 42, 101, 103, 251, 101, 190, 106, 107, 98, + /* 1540 */ 106, 107, 106, 107, 198, 199, 4, 252, 59, 118, + /* 1550 */ 101, 177, 118, 64, 4, 106, 107, 12, 152, 4, + /* 1560 */ 154, 155, 156, 4, 190, 106, 107, 118, 98, 123, + /* 1570 */ 81, 82, 128, 101, 142, 4, 106, 88, 106, 107, + /* 1580 */ 71, 177, 101, 89, 4, 96, 15, 106, 107, 139, + /* 1590 */ 101, 132, 103, 157, 190, 106, 107, 251, 71, 177, + /* 1600 */ 111, 4, 198, 199, 153, 133, 89, 118, 119, 120, + /* 1610 */ 121, 141, 190, 42, 22, 101, 91, 101, 106, 107, + /* 1620 */ 106, 107, 106, 107, 177, 177, 4, 146, 181, 47, + /* 1630 */ 59, 106, 107, 91, 118, 64, 4, 190, 190, 127, + /* 1640 */ 39, 152, 104, 154, 155, 156, 39, 158, 106, 107, + /* 1650 */ 91, 177, 81, 82, 161, 251, 106, 107, 4, 88, + /* 1660 */ 212, 106, 107, 177, 190, 106, 107, 96, 97, 15, + /* 1670 */ 123, 96, 101, 118, 103, 177, 190, 106, 107, 165, + /* 1680 */ 177, 96, 111, 95, 198, 199, 106, 107, 190, 118, + /* 1690 */ 119, 120, 121, 190, 4, 177, 42, 143, 103, 97, + /* 1700 */ 97, 198, 199, 106, 107, 95, 258, 177, 190, 177, + /* 1710 */ 236, 237, 93, 59, 164, 37, 198, 199, 64, 36, + /* 1720 */ 190, 141, 190, 152, 189, 154, 155, 156, 106, 107, + /* 1730 */ 198, 199, 252, 4, 238, 81, 82, 251, 106, 107, + /* 1740 */ 4, 204, 88, 146, 204, 177, 177, 4, 273, 177, + /* 1750 */ 96, 15, 275, 176, 251, 101, 90, 103, 190, 190, + /* 1760 */ 106, 107, 190, 177, 177, 111, 198, 199, 146, 251, + /* 1770 */ 198, 199, 118, 119, 120, 121, 190, 190, 42, 4, + /* 1780 */ 275, 176, 4, 251, 152, 198, 199, 176, 49, 177, + /* 1790 */ 7, 177, 176, 181, 11, 59, 106, 107, 177, 104, + /* 1800 */ 64, 4, 190, 177, 190, 4, 152, 181, 154, 155, + /* 1810 */ 156, 190, 198, 199, 4, 32, 190, 81, 82, 251, + /* 1820 */ 178, 177, 4, 251, 88, 181, 178, 177, 183, 100, + /* 1830 */ 60, 181, 96, 15, 190, 106, 107, 101, 251, 103, + /* 1840 */ 190, 4, 106, 107, 180, 184, 177, 111, 221, 106, + /* 1850 */ 107, 56, 162, 138, 118, 119, 120, 121, 177, 190, + /* 1860 */ 42, 118, 177, 177, 243, 251, 181, 198, 199, 151, + /* 1870 */ 177, 190, 148, 177, 181, 190, 190, 59, 227, 198, + /* 1880 */ 199, 106, 107, 190, 106, 107, 190, 228, 152, 177, + /* 1890 */ 154, 155, 156, 118, 198, 199, 118, 229, 177, 81, + /* 1900 */ 82, 4, 190, 106, 107, 177, 88, 106, 107, 177, + /* 1910 */ 100, 190, 230, 149, 96, 118, 106, 107, 190, 101, + /* 1920 */ 251, 103, 190, 237, 106, 107, 198, 199, 177, 111, + /* 1930 */ 198, 199, 251, 177, 133, 177, 118, 119, 120, 121, + /* 1940 */ 177, 190, 4, 106, 107, 177, 190, 251, 190, 198, + /* 1950 */ 199, 4, 147, 190, 198, 199, 198, 199, 190, 4, + /* 1960 */ 87, 198, 199, 177, 177, 231, 198, 199, 4, 177, + /* 1970 */ 152, 150, 154, 155, 156, 252, 190, 190, 4, 251, + /* 1980 */ 177, 177, 190, 251, 198, 199, 177, 203, 177, 152, + /* 1990 */ 198, 199, 181, 190, 190, 64, 259, 96, 87, 190, + /* 2000 */ 177, 190, 251, 106, 107, 177, 158, 251, 255, 251, + /* 2010 */ 177, 177, 177, 190, 251, 118, 177, 177, 190, 251, + /* 2020 */ 177, 198, 199, 190, 190, 190, 241, 177, 203, 190, + /* 2030 */ 190, 198, 199, 190, 177, 177, 177, 251, 198, 199, + /* 2040 */ 190, 198, 199, 251, 106, 107, 177, 190, 190, 190, + /* 2050 */ 99, 177, 99, 106, 107, 198, 199, 198, 199, 190, + /* 2060 */ 241, 106, 107, 177, 190, 118, 177, 198, 199, 223, + /* 2070 */ 106, 107, 198, 199, 251, 4, 190, 177, 200, 190, + /* 2080 */ 106, 107, 118, 177, 251, 4, 123, 198, 199, 4, + /* 2090 */ 190, 251, 118, 200, 251, 208, 190, 139, 198, 199, + /* 2100 */ 177, 177, 177, 165, 198, 199, 177, 31, 251, 200, + /* 2110 */ 251, 122, 202, 190, 190, 190, 177, 177, 163, 190, + /* 2120 */ 251, 198, 199, 198, 199, 251, 177, 198, 199, 190, + /* 2130 */ 190, 177, 200, 177, 208, 200, 177, 198, 199, 190, + /* 2140 */ 251, 200, 200, 200, 190, 177, 190, 198, 199, 190, + /* 2150 */ 177, 251, 198, 199, 198, 199, 177, 251, 190, 241, + /* 2160 */ 177, 99, 177, 190, 203, 203, 198, 199, 180, 190, + /* 2170 */ 177, 198, 199, 190, 251, 190, 251, 106, 107, 203, + /* 2180 */ 251, 100, 177, 190, 180, 177, 99, 106, 107, 177, + /* 2190 */ 251, 106, 107, 177, 99, 190, 177, 264, 190, 27, + /* 2200 */ 251, 241, 190, 158, 99, 251, 190, 251, 227, 190, + /* 2210 */ 265, 215, 62, 99, 99, 250, 96, 215, 180, 251, + /* 2220 */ 99, 241, 227, 152, 251, 241, 180, 99, 217, 60, + /* 2230 */ 99, 217, 99, 99, 217, 217, 99, 152, 241, 99, + /* 2240 */ 268, 18, 241, 268, 99, 99, 99, 241, 270, 16, + /* 2250 */ 224, 226, 261, 261, 201, 256, 201, 242, 206, 210, + /* 2260 */ 240, 202, 227, 242, 242, 175, 224, 239, 191, 191, + /* 2270 */ 191, 191, 262, 222, 216, 207, 263, 253, 211, 207, + /* 2280 */ 207, 274, 198, 55, 198, }; #define YY_SHIFT_USE_DFLT (-81) -#define YY_SHIFT_COUNT (434) +#define YY_SHIFT_COUNT (435) #define YY_SHIFT_MIN (-80) -#define YY_SHIFT_MAX (2208) +#define YY_SHIFT_MAX (2233) static const short yy_shift_ofst[] = { /* 0 */ 1158, -4, 201, 1182, 819, 1571, 1571, 689, 361, 1489, - /* 10 */ 1654, 1654, 770, 364, 364, 157, 81, 179, 1406, 1323, - /* 20 */ 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, + /* 10 */ 1654, 1654, 1654, 770, 364, 364, 157, 81, 179, 1406, + /* 20 */ 1323, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, /* 30 */ 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, /* 40 */ 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, - /* 50 */ 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1736, 370, 798, - /* 60 */ 181, 370, 2001, 2001, 2001, 2001, 2001, 887, 887, 565, - /* 70 */ 277, 4, 1510, 1492, 1458, 1375, 1449, 1434, 1431, 1427, - /* 80 */ 1379, 448, 1399, 2066, 2066, 2069, 439, 2066, 2064, 2001, + /* 50 */ 1654, 1654, 1654, 1654, 1654, 1654, 1736, 1654, 1818, 370, + /* 60 */ 798, 181, 370, 1837, 1837, 1837, 1837, 887, 887, 565, + /* 70 */ 277, 4, 1516, 1514, 1481, 1472, 1449, 1434, 1431, 1365, + /* 80 */ 1348, 448, 1399, 2071, 2071, 2085, 439, 2071, 2081, 1837, /* 90 */ 565, 1039, 538, 538, 735, 84, 44, 171, 859, 775, /* 100 */ 906, 773, 910, 636, 1172, 5, 450, 5, 443, 413, - /* 110 */ 185, 2059, 2040, 1775, 1947, 1840, 1991, 2016, 1933, 2014, - /* 120 */ 1525, 1999, 1724, 1995, 1974, 1965, 1734, 1517, 1693, 1855, - /* 130 */ 1047, 1593, 1597, 902, 140, 1542, 1542, 1436, 1564, 1542, - /* 140 */ 1236, 780, 1409, 349, 562, 216, 620, 1559, 1515, 1348, - /* 150 */ 90, 829, 829, 829, 872, 544, 2202, 2202, 2202, 2202, - /* 160 */ 2202, -81, -81, 459, 619, 619, 619, 619, 619, 619, + /* 110 */ 185, 1729, 1974, 1955, 1938, 1622, 1801, 1964, 1810, 1797, + /* 120 */ 1690, 1947, 1632, 1897, 1778, 1555, 1550, 1459, 1325, 1775, + /* 130 */ 1047, 1512, 1743, 902, 140, 1470, 1470, 1597, 1580, 1470, + /* 140 */ 1236, 780, 1436, 349, 562, 216, 620, 1559, 1542, 1525, + /* 150 */ 90, 829, 829, 829, 872, 544, 2228, 2228, 2228, 2228, + /* 160 */ 2228, -81, -81, 459, 619, 619, 619, 619, 619, 619, /* 170 */ 619, 619, 619, 645, 327, 683, 1180, 1149, 1117, 1087, /* 180 */ 1051, 1021, 985, 958, 916, 767, 1239, 1212, 1276, 509, /* 190 */ 509, -60, -38, -38, -38, -38, 578, -80, 314, 87, /* 200 */ 87, 41, 155, 75, 58, 58, 58, -6, 186, 862, - /* 210 */ -47, 808, 1649, 1463, 1284, 206, 908, 424, 400, 25, - /* 220 */ 729, 729, 679, 1364, -2, 855, 729, 442, 346, 855, - /* 230 */ 750, 750, 187, -9, 169, 2208, 2120, 2118, 2116, 2196, - /* 240 */ 2196, 2112, 2109, 2143, 2108, 2143, 2107, 2143, 2105, 2143, - /* 250 */ 2101, 1761, 1712, 2094, 1761, 2122, 2091, 2087, 2086, 2122, - /* 260 */ 1712, 2061, 1994, 2110, 2032, 1761, 2011, 1761, 1956, 1801, - /* 270 */ 1836, 1836, 1836, 1836, 1971, 1801, 1836, 1904, 1836, 1971, - /* 280 */ 1836, 1836, 1796, 1835, 1815, 1754, 1801, 1818, 1801, 1825, - /* 290 */ 1807, 1729, 1725, 1728, 1722, 1712, 1691, 1771, 1721, 1761, - /* 300 */ 1737, 1737, 1673, 1673, 1673, 1673, -81, -81, -81, -81, - /* 310 */ -81, -81, -81, -81, -81, -81, 564, 79, 158, 45, - /* 320 */ 702, 243, -49, 398, 1362, 1321, 1042, 984, 788, 2, - /* 330 */ 471, -20, 758, 678, 344, 144, -44, 1674, 1670, 1601, - /* 340 */ 1603, 1591, 1549, 1558, 1543, 1511, 1541, 1519, 1496, 1459, - /* 350 */ 1575, 1484, 1545, 1536, 1550, 1490, 1487, 1418, 1420, 1483, - /* 360 */ 1480, 1419, 1402, 1527, 1407, 1424, 1417, 1433, 1389, 1380, - /* 370 */ 1405, 1454, 1394, 1393, 1377, 1368, 1425, 1444, 1327, 1369, - /* 380 */ 1350, 1309, 1300, 1272, 1202, 1257, 1234, 1269, 1233, 1202, - /* 390 */ 1222, 1173, 1171, 1124, 1128, 1050, 1216, 1197, 1113, 993, - /* 400 */ 1193, 1038, 1099, 993, 990, 937, 846, 895, 870, 848, - /* 410 */ 867, 825, 757, 805, 675, 652, 571, 644, 625, 613, - /* 420 */ 571, 438, 474, 421, 399, 406, 355, 362, 231, 225, - /* 430 */ 166, 143, 63, -37, -61, + /* 210 */ -47, 808, 1783, 1301, 1296, 206, 908, 424, 400, 25, + /* 220 */ 729, 729, 679, 1360, -2, 855, 729, 442, 346, 855, + /* 230 */ 750, 750, 187, -9, 169, 2233, 2147, 2146, 2145, 2223, + /* 240 */ 2223, 2140, 2137, 2169, 2134, 2169, 2133, 2169, 2131, 2169, + /* 250 */ 2128, 1770, 1718, 2121, 1770, 2150, 2120, 2115, 2114, 2150, + /* 260 */ 1718, 2105, 2045, 2172, 2095, 1770, 2087, 1901, 1770, 2062, + /* 270 */ 1901, 1963, 1963, 1963, 1963, 2076, 1901, 1963, 1989, 1963, + /* 280 */ 2076, 1963, 1963, 1958, 1953, 1951, 1848, 1901, 1911, 1901, + /* 290 */ 1931, 1873, 1821, 1805, 1764, 1724, 1718, 1715, 1795, 1695, + /* 300 */ 1770, 1739, 1739, 1666, 1666, 1666, 1666, -81, -81, -81, + /* 310 */ -81, -81, -81, -81, -81, -81, -81, 564, 79, 158, + /* 320 */ 45, 702, 243, -49, 398, 1293, 1279, 1042, 984, 788, + /* 330 */ 2, 471, -20, 758, 678, 344, 144, -44, 1683, 1678, + /* 340 */ 1619, 1610, 1603, 1602, 1595, 1585, 1554, 1588, 1575, 1547, + /* 350 */ 1493, 1607, 1538, 1601, 1582, 1592, 1517, 1494, 1450, 1451, + /* 360 */ 1527, 1509, 1444, 1432, 1545, 1446, 1441, 1430, 1464, 1390, + /* 370 */ 1407, 1425, 1460, 1400, 1396, 1398, 1395, 1452, 1478, 1372, + /* 380 */ 1423, 1428, 1354, 1342, 1318, 1168, 1257, 1310, 1270, 1234, + /* 390 */ 1168, 1223, 1171, 1169, 1112, 1128, 1050, 1216, 1197, 1113, + /* 400 */ 993, 1193, 1038, 1099, 993, 990, 937, 846, 895, 870, + /* 410 */ 848, 867, 825, 757, 805, 675, 652, 571, 644, 625, + /* 420 */ 613, 571, 438, 474, 421, 399, 406, 355, 362, 231, + /* 430 */ 225, 166, 143, 63, -37, -61, }; #define YY_REDUCE_USE_DFLT (-100) -#define YY_REDUCE_COUNT (315) +#define YY_REDUCE_COUNT (316) #define YY_REDUCE_MIN (-99) -#define YY_REDUCE_MAX (2067) +#define YY_REDUCE_MAX (2090) static const short yy_reduce_ofst[] = { - /* 0 */ 615, 1195, 699, -99, 764, 1138, 189, 705, 1259, 1218, - /* 10 */ 1201, 261, 196, 884, 599, 1187, 1897, 1892, 1887, 1868, - /* 20 */ 1858, 1853, 1848, 1838, 1833, 1814, 1810, 1808, 1798, 1791, - /* 30 */ 1773, 1768, 1766, 1750, 1743, 1733, 1726, 1723, 1719, 1709, - /* 40 */ 1703, 1685, 1675, 1668, 1636, 1617, 1613, 1599, 1572, 1568, - /* 50 */ 1534, 1532, 1518, 1503, 1486, 1435, 1428, 1404, 490, 1401, - /* 60 */ 214, 769, 1544, 1529, 1225, 124, 67, 596, 175, 547, - /* 70 */ 1221, 1614, 1964, 1959, 1952, 1949, 1937, 1802, 1611, 1587, - /* 80 */ 1270, 1562, 203, 1346, 1255, 131, 347, 950, 1397, 195, - /* 90 */ 885, 265, 1134, 1132, 125, 377, 1011, 2006, 2005, 1979, - /* 100 */ 1671, 1671, 2004, 2002, 2000, 697, 1990, 11, 1671, 1984, - /* 110 */ 1979, 1978, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1973, - /* 120 */ 1671, 1671, 1967, 1671, 1671, 1938, 1671, 1671, 1671, 1926, - /* 130 */ 1885, 1844, 1839, 1837, 1803, 1141, 1140, 1767, 1762, 1065, - /* 140 */ 1738, 1671, 1659, 1643, 1569, 1485, 632, 1474, 1452, 1294, - /* 150 */ 1232, 1191, 666, 489, 938, 1022, 1020, 956, 924, 791, - /* 160 */ 763, 746, 205, 1462, 1462, 1462, 1462, 1462, 1462, 1462, - /* 170 */ 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, - /* 180 */ 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, - /* 190 */ 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 2047, 2058, - /* 200 */ 2057, 1462, 1980, 1980, 2046, 2045, 2041, 2012, 2031, 2009, - /* 210 */ 2028, 1983, 1987, 2054, 2053, 2052, 2043, 2017, 2067, 2010, - /* 220 */ 1998, 1997, 2034, 2025, 2026, 2027, 1996, 1986, 1975, 2024, - /* 230 */ 1969, 1968, 1462, 2007, 2003, 1950, 1859, 1982, 1981, 1948, - /* 240 */ 1944, 1972, 1859, 1993, 1859, 1992, 1859, 1988, 1859, 1985, - /* 250 */ 1960, 2019, 1970, 1957, 2008, 1976, 1939, 1859, 1859, 1963, - /* 260 */ 1935, 1859, 1886, 1871, 1884, 1931, 1859, 1914, 1859, 1890, - /* 270 */ 1888, 1879, 1878, 1876, 1852, 1847, 1841, 1820, 1811, 1774, - /* 280 */ 1776, 1755, 1730, 1689, 1688, 1651, 1708, 1645, 1692, 1633, - /* 290 */ 1462, 1647, 1641, 1640, 1632, 1626, 1625, 1644, 1639, 1634, - /* 300 */ 1627, 1618, 1608, 1606, 1605, 1604, 1478, 1472, 1475, 1540, - /* 310 */ 1539, 1491, 1462, 1462, 1462, 1523, + /* 0 */ 615, 1195, 699, -99, 764, 1138, 189, 705, 1283, 1260, + /* 10 */ 1218, 1201, 261, 196, 884, 599, 1187, 1973, 1968, 1956, + /* 20 */ 1954, 1949, 1939, 1929, 1925, 1923, 1906, 1900, 1889, 1874, + /* 30 */ 1869, 1859, 1857, 1843, 1840, 1833, 1823, 1792, 1786, 1768, + /* 40 */ 1763, 1758, 1756, 1751, 1732, 1728, 1696, 1681, 1669, 1614, + /* 50 */ 1587, 1572, 1568, 1532, 1518, 1503, 1486, 1404, 1346, 490, + /* 60 */ 1474, 214, 769, 1448, 1189, 124, 67, 596, 175, 547, + /* 70 */ 1295, 1686, 1811, 1693, 1685, 1650, 1644, 1626, 1612, 1447, + /* 80 */ 1320, 1232, 203, 1621, 1246, 131, 347, 950, 1191, 195, + /* 90 */ 885, 265, 1134, 1132, 125, 377, 1011, 2019, 2016, 1983, + /* 100 */ 1803, 1803, 2012, 2008, 2005, 697, 1993, 11, 1803, 1985, + /* 110 */ 1983, 1979, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1959, + /* 120 */ 1803, 1803, 1940, 1803, 1803, 1924, 1803, 1803, 1803, 1886, + /* 130 */ 1858, 1850, 1839, 1835, 1834, 1221, 1140, 1828, 1809, 1097, + /* 140 */ 1804, 1803, 1787, 1721, 1712, 1586, 632, 1569, 1530, 1498, + /* 150 */ 1422, 1374, 666, 489, 938, 1022, 1020, 956, 924, 791, + /* 160 */ 763, 746, 205, 1480, 1480, 1480, 1480, 1480, 1480, 1480, + /* 170 */ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, + /* 180 */ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, + /* 190 */ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 2067, 2086, + /* 200 */ 2084, 1480, 2007, 2007, 2073, 2072, 2068, 2028, 2058, 2024, + /* 210 */ 2051, 2013, 2010, 2080, 2079, 2078, 2077, 2042, 2090, 2035, + /* 220 */ 2022, 2021, 2059, 2049, 2052, 2055, 2015, 2020, 1999, 2053, + /* 230 */ 1992, 1991, 1480, 2025, 2026, 1978, 1918, 2006, 2001, 1975, + /* 240 */ 1972, 1997, 1918, 2018, 1918, 2017, 1918, 2014, 1918, 2011, + /* 250 */ 1984, 2046, 1995, 1980, 2038, 2002, 1965, 1918, 1918, 1996, + /* 260 */ 1981, 1918, 1945, 1933, 1960, 2004, 1918, 1976, 1988, 1918, + /* 270 */ 1962, 1943, 1942, 1941, 1935, 1926, 1961, 1932, 1910, 1909, + /* 280 */ 1887, 1893, 1878, 1846, 1819, 1785, 1753, 1825, 1737, 1784, + /* 290 */ 1723, 1480, 1734, 1682, 1668, 1659, 1651, 1627, 1661, 1645, + /* 300 */ 1664, 1648, 1642, 1616, 1611, 1605, 1577, 1505, 1477, 1475, + /* 310 */ 1540, 1537, 1496, 1480, 1480, 1480, 1535, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 729, 1037, 1142, 1142, 1026, 1026, 1026, 1142, 1026, 1026, - /* 10 */ 1026, 1026, 900, 1148, 1148, 1148, 1026, 1026, 1026, 1026, - /* 20 */ 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1026, - /* 30 */ 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1026, - /* 40 */ 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1026, - /* 50 */ 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1015, 1148, 894, - /* 60 */ 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 774, - /* 70 */ 890, 900, 1148, 1148, 1148, 1148, 1148, 962, 949, 940, - /* 80 */ 1148, 1148, 1148, 972, 972, 955, 842, 972, 1148, 1148, - /* 90 */ 1148, 1148, 928, 928, 1027, 1148, 766, 1112, 1117, 1013, - /* 100 */ 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 901, 1148, - /* 110 */ 1013, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, - /* 120 */ 1148, 963, 956, 950, 941, 1148, 1148, 1148, 1148, 1148, - /* 130 */ 1148, 1148, 1148, 1148, 1148, 890, 890, 1148, 1148, 890, - /* 140 */ 1148, 1148, 1148, 1014, 1148, 1148, 763, 1148, 1148, 1148, - /* 150 */ 735, 1058, 1148, 1148, 729, 1142, 1142, 1142, 1142, 1142, - /* 160 */ 1142, 1135, 880, 935, 906, 945, 933, 937, 1038, 1031, - /* 170 */ 1032, 1030, 936, 1027, 1027, 1027, 1027, 1027, 1027, 1027, - /* 180 */ 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 988, 1000, - /* 190 */ 987, 995, 1004, 999, 996, 990, 989, 991, 1148, 1148, - /* 200 */ 1148, 992, 1148, 1148, 1148, 1148, 1148, 893, 1148, 1148, - /* 210 */ 864, 1148, 1086, 1148, 1148, 776, 1148, 878, 738, 944, - /* 220 */ 918, 918, 809, 833, 798, 928, 918, 908, 1033, 928, - /* 230 */ 1148, 1148, 993, 891, 878, 1126, 909, 909, 909, 1111, - /* 240 */ 1111, 909, 909, 855, 909, 855, 909, 855, 909, 855, - /* 250 */ 909, 760, 944, 909, 760, 846, 968, 909, 909, 846, - /* 260 */ 944, 909, 1093, 1091, 909, 760, 909, 760, 909, 1046, - /* 270 */ 844, 844, 844, 844, 825, 1046, 844, 809, 844, 825, - /* 280 */ 844, 844, 1148, 909, 909, 1148, 1046, 1052, 1046, 1027, - /* 290 */ 994, 934, 922, 932, 929, 944, 1148, 757, 828, 760, - /* 300 */ 746, 746, 734, 734, 734, 734, 1139, 1139, 1135, 811, - /* 310 */ 811, 896, 1003, 1002, 1001, 785, 1039, 1148, 1148, 1148, - /* 320 */ 1148, 1148, 1148, 1060, 1148, 1148, 1148, 1148, 1148, 1148, - /* 330 */ 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 730, 1148, - /* 340 */ 1148, 1148, 1148, 1148, 1129, 1148, 1148, 1148, 1148, 1148, - /* 350 */ 1148, 1090, 1089, 1148, 1148, 1148, 1148, 1148, 1148, 1148, - /* 360 */ 1148, 1148, 1148, 1078, 1148, 1148, 1148, 1148, 1148, 1148, - /* 370 */ 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, - /* 380 */ 1148, 1148, 1148, 1148, 867, 869, 1148, 1148, 1148, 868, - /* 390 */ 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 930, - /* 400 */ 1148, 923, 1148, 1036, 1148, 1017, 1025, 1148, 1148, 1148, - /* 410 */ 1148, 1148, 1016, 1148, 1148, 1148, 1144, 1148, 1148, 1148, - /* 420 */ 1143, 1148, 1148, 1148, 1148, 1148, 1028, 980, 1148, 979, - /* 430 */ 978, 769, 1148, 744, 1148, 726, 731, 1128, 1125, 1127, - /* 440 */ 1122, 1123, 1121, 1124, 1120, 1118, 1119, 1116, 1114, 1113, - /* 450 */ 1115, 1110, 1106, 1066, 1064, 1062, 1071, 1070, 1069, 1068, - /* 460 */ 1067, 1063, 1061, 1065, 1059, 959, 947, 938, 862, 1105, - /* 470 */ 1103, 1104, 1057, 1055, 1056, 861, 860, 859, 854, 853, - /* 480 */ 852, 851, 1132, 1141, 1140, 1138, 1137, 1136, 1130, 1131, - /* 490 */ 1044, 1043, 1041, 1040, 1042, 762, 1082, 1085, 1084, 1083, - /* 500 */ 1088, 1087, 1080, 1092, 1097, 1096, 1101, 1100, 1099, 1098, - /* 510 */ 1095, 1077, 967, 966, 964, 969, 961, 960, 965, 952, - /* 520 */ 958, 957, 948, 951, 847, 943, 939, 942, 863, 1081, - /* 530 */ 858, 857, 856, 761, 756, 911, 755, 754, 765, 831, - /* 540 */ 832, 840, 843, 838, 841, 837, 836, 835, 839, 834, - /* 550 */ 830, 768, 767, 775, 824, 802, 800, 799, 803, 816, - /* 560 */ 815, 822, 821, 820, 819, 818, 814, 817, 813, 812, - /* 570 */ 804, 797, 796, 810, 795, 827, 826, 823, 794, 850, - /* 580 */ 849, 848, 845, 793, 792, 791, 790, 789, 788, 986, - /* 590 */ 985, 1006, 977, 865, 872, 871, 870, 874, 875, 885, - /* 600 */ 883, 882, 881, 917, 916, 915, 914, 913, 912, 905, - /* 610 */ 903, 899, 898, 904, 902, 920, 921, 919, 897, 889, - /* 620 */ 887, 888, 886, 974, 971, 973, 970, 907, 895, 892, - /* 630 */ 879, 925, 924, 1029, 1018, 1008, 1019, 910, 1007, 1005, - /* 640 */ 1028, 1025, 1020, 1102, 1024, 1012, 1011, 1010, 1147, 1145, - /* 650 */ 1146, 1049, 1051, 1054, 1053, 1050, 927, 926, 1048, 1047, - /* 660 */ 1009, 984, 781, 779, 780, 1074, 1073, 1076, 1075, 1072, - /* 670 */ 783, 782, 778, 777, 998, 997, 982, 1021, 1022, 981, - /* 680 */ 1023, 983, 770, 873, 866, 976, 975, 808, 807, 806, - /* 690 */ 805, 877, 876, 787, 801, 786, 784, 764, 759, 758, - /* 700 */ 753, 751, 748, 750, 747, 752, 749, 745, 743, 742, - /* 710 */ 741, 740, 739, 773, 772, 771, 769, 737, 736, 733, - /* 720 */ 732, 728, 727, 725, + /* 0 */ 730, 1038, 1143, 1143, 1027, 1027, 1027, 1143, 1027, 1027, + /* 10 */ 1027, 1027, 1027, 901, 1149, 1149, 1149, 1027, 1027, 1027, + /* 20 */ 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, + /* 30 */ 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, + /* 40 */ 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, + /* 50 */ 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1016, 1149, + /* 60 */ 895, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 775, + /* 70 */ 891, 901, 1149, 1149, 1149, 1149, 1149, 963, 950, 941, + /* 80 */ 1149, 1149, 1149, 973, 973, 956, 843, 973, 1149, 1149, + /* 90 */ 1149, 1149, 929, 929, 1028, 1149, 767, 1113, 1118, 1014, + /* 100 */ 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 902, 1149, + /* 110 */ 1014, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, + /* 120 */ 1149, 964, 957, 951, 942, 1149, 1149, 1149, 1149, 1149, + /* 130 */ 1149, 1149, 1149, 1149, 1149, 891, 891, 1149, 1149, 891, + /* 140 */ 1149, 1149, 1149, 1015, 1149, 1149, 764, 1149, 1149, 1149, + /* 150 */ 736, 1059, 1149, 1149, 730, 1143, 1143, 1143, 1143, 1143, + /* 160 */ 1143, 1136, 881, 936, 907, 946, 934, 938, 1039, 1032, + /* 170 */ 1033, 1031, 937, 1028, 1028, 1028, 1028, 1028, 1028, 1028, + /* 180 */ 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 989, 1001, + /* 190 */ 988, 996, 1005, 1000, 997, 991, 990, 992, 1149, 1149, + /* 200 */ 1149, 993, 1149, 1149, 1149, 1149, 1149, 894, 1149, 1149, + /* 210 */ 865, 1149, 1087, 1149, 1149, 777, 1149, 879, 739, 945, + /* 220 */ 919, 919, 810, 834, 799, 929, 919, 909, 1034, 929, + /* 230 */ 1149, 1149, 994, 892, 879, 1127, 910, 910, 910, 1112, + /* 240 */ 1112, 910, 910, 856, 910, 856, 910, 856, 910, 856, + /* 250 */ 910, 761, 945, 910, 761, 847, 969, 910, 910, 847, + /* 260 */ 945, 910, 1094, 1092, 910, 761, 910, 1047, 761, 910, + /* 270 */ 1047, 845, 845, 845, 845, 826, 1047, 845, 810, 845, + /* 280 */ 826, 845, 845, 1149, 910, 910, 1149, 1047, 1053, 1047, + /* 290 */ 1028, 995, 935, 923, 933, 930, 945, 1149, 758, 829, + /* 300 */ 761, 747, 747, 735, 735, 735, 735, 1140, 1140, 1136, + /* 310 */ 812, 812, 897, 1004, 1003, 1002, 786, 1040, 1149, 1149, + /* 320 */ 1149, 1149, 1149, 1149, 1061, 1149, 1149, 1149, 1149, 1149, + /* 330 */ 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 731, + /* 340 */ 1149, 1149, 1149, 1149, 1149, 1130, 1149, 1149, 1149, 1149, + /* 350 */ 1149, 1149, 1091, 1090, 1149, 1149, 1149, 1149, 1149, 1149, + /* 360 */ 1149, 1149, 1149, 1149, 1079, 1149, 1149, 1149, 1149, 1149, + /* 370 */ 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, + /* 380 */ 1149, 1149, 1149, 1149, 1149, 868, 870, 1149, 1149, 1149, + /* 390 */ 869, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, + /* 400 */ 931, 1149, 924, 1149, 1037, 1149, 1018, 1026, 1149, 1149, + /* 410 */ 1149, 1149, 1149, 1017, 1149, 1149, 1149, 1145, 1149, 1149, + /* 420 */ 1149, 1144, 1149, 1149, 1149, 1149, 1149, 1029, 981, 1149, + /* 430 */ 980, 979, 770, 1149, 745, 1149, 727, 732, 1129, 1126, + /* 440 */ 1128, 1123, 1124, 1122, 1125, 1121, 1119, 1120, 1117, 1115, + /* 450 */ 1114, 1116, 1111, 1107, 1067, 1065, 1063, 1072, 1071, 1070, + /* 460 */ 1069, 1068, 1064, 1062, 1066, 1060, 960, 948, 939, 863, + /* 470 */ 1106, 1104, 1105, 1058, 1056, 1057, 862, 861, 860, 855, + /* 480 */ 854, 853, 852, 1133, 1142, 1141, 1139, 1138, 1137, 1131, + /* 490 */ 1132, 1045, 1044, 1042, 1041, 1043, 763, 1083, 1086, 1085, + /* 500 */ 1084, 1089, 1088, 1081, 1093, 1098, 1097, 1102, 1101, 1100, + /* 510 */ 1099, 1096, 1078, 968, 967, 965, 970, 962, 961, 966, + /* 520 */ 953, 959, 958, 949, 952, 848, 944, 940, 943, 864, + /* 530 */ 1082, 859, 858, 857, 762, 757, 912, 756, 755, 766, + /* 540 */ 832, 833, 841, 844, 839, 842, 838, 837, 836, 840, + /* 550 */ 835, 831, 769, 768, 776, 825, 803, 801, 800, 804, + /* 560 */ 817, 816, 823, 822, 821, 820, 819, 815, 818, 814, + /* 570 */ 813, 805, 798, 797, 811, 796, 828, 827, 824, 795, + /* 580 */ 851, 850, 849, 846, 794, 793, 792, 791, 790, 789, + /* 590 */ 987, 986, 1007, 978, 866, 873, 872, 871, 875, 876, + /* 600 */ 886, 884, 883, 882, 918, 917, 916, 915, 914, 913, + /* 610 */ 906, 904, 900, 899, 905, 903, 921, 922, 920, 898, + /* 620 */ 890, 888, 889, 887, 975, 972, 974, 971, 908, 896, + /* 630 */ 893, 880, 926, 925, 1030, 1019, 1009, 1020, 911, 1008, + /* 640 */ 1006, 1029, 1026, 1021, 1103, 1025, 1013, 1012, 1011, 1148, + /* 650 */ 1146, 1147, 1050, 1052, 1055, 1054, 1051, 928, 927, 1049, + /* 660 */ 1048, 1010, 985, 782, 780, 781, 1075, 1074, 1077, 1076, + /* 670 */ 1073, 784, 783, 779, 778, 999, 998, 983, 1022, 1023, + /* 680 */ 982, 1024, 984, 771, 874, 867, 977, 976, 809, 808, + /* 690 */ 807, 806, 878, 877, 788, 802, 787, 785, 765, 760, + /* 700 */ 759, 754, 752, 749, 751, 748, 753, 750, 746, 744, + /* 710 */ 743, 742, 741, 740, 774, 773, 772, 770, 738, 737, + /* 720 */ 734, 733, 729, 728, 726, }; /* The next table maps tokens into fallback tokens. If a construct @@ -1297,7 +1301,7 @@ static const char *const yyRuleName[] = { /* 129 */ "cmd ::= DROP TABLE ifexists ID_DB|ID_TAB", /* 130 */ "ifexists ::= IF EXISTS", /* 131 */ "ifexists ::=", - /* 132 */ "cmd ::= CREATE temp VIEW ifnotexists fullname AS select", + /* 132 */ "cmd ::= CREATE temp VIEW ifnotexists fullname idxlist_opt AS select", /* 133 */ "cmd ::= CREATE temp VIEW ifnotexists nm DOT ID_VIEW_NEW", /* 134 */ "cmd ::= CREATE temp VIEW ifnotexists ID_DB|ID_VIEW_NEW", /* 135 */ "cmd ::= DROP VIEW ifexists fullname", @@ -1481,7 +1485,7 @@ static const char *const yyRuleName[] = { /* 313 */ "exprlist ::=", /* 314 */ "nexprlist ::= nexprlist COMMA expr", /* 315 */ "nexprlist ::= exprx", - /* 316 */ "cmd ::= CREATE uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt", + /* 316 */ "cmd ::= CREATE uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", /* 317 */ "cmd ::= CREATE uniqueflag INDEX ifnotexists nm dbnm ON ID_TAB", /* 318 */ "cmd ::= CREATE uniqueflag INDEX ifnotexists nm DOT ID_IDX_NEW", /* 319 */ "cmd ::= CREATE uniqueflag INDEX ifnotexists ID_DB|ID_IDX_NEW", @@ -2354,7 +2358,7 @@ static const struct { { 169, 4 }, { 217, 2 }, { 217, 0 }, - { 169, 7 }, + { 169, 8 }, { 169, 7 }, { 169, 5 }, { 169, 4 }, @@ -3398,12 +3402,13 @@ static void yy_reduce( { yy_destructor(yypParser,177,&yymsp[-2].minor); } break; - case 132: /* cmd ::= CREATE temp VIEW ifnotexists fullname AS select */ + case 132: /* cmd ::= CREATE temp VIEW ifnotexists fullname idxlist_opt AS select */ { - yygotominor.yy399 = new SqliteCreateView(*(yymsp[-5].minor.yy376), *(yymsp[-3].minor.yy237), yymsp[-2].minor.yy66->name1, yymsp[-2].minor.yy66->name2, yymsp[0].minor.yy123); - delete yymsp[-5].minor.yy376; - delete yymsp[-3].minor.yy237; - delete yymsp[-2].minor.yy66; + yygotominor.yy399 = new SqliteCreateView(*(yymsp[-6].minor.yy376), *(yymsp[-4].minor.yy237), yymsp[-3].minor.yy66->name1, yymsp[-3].minor.yy66->name2, yymsp[0].minor.yy123, *(yymsp[-2].minor.yy139)); + delete yymsp[-6].minor.yy376; + delete yymsp[-4].minor.yy237; + delete yymsp[-3].minor.yy66; + delete yymsp[-2].minor.yy139; objectForTokens = yygotominor.yy399; } break; @@ -4463,7 +4468,7 @@ static void yy_reduce( yygotominor.yy13->append(yymsp[0].minor.yy490); } break; - case 316: /* cmd ::= CREATE uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt */ + case 316: /* cmd ::= CREATE uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ { yygotominor.yy399 = new SqliteCreateIndex( *(yymsp[-10].minor.yy237), @@ -4471,7 +4476,7 @@ static void yy_reduce( *(yymsp[-7].minor.yy211), *(yymsp[-6].minor.yy211), *(yymsp[-4].minor.yy211), - *(yymsp[-2].minor.yy139), + *(yymsp[-2].minor.yy495), yymsp[0].minor.yy490 ); delete yymsp[-8].minor.yy237; @@ -4479,7 +4484,7 @@ static void yy_reduce( delete yymsp[-7].minor.yy211; delete yymsp[-6].minor.yy211; delete yymsp[-4].minor.yy211; - delete yymsp[-2].minor.yy139; + delete yymsp[-2].minor.yy495; objectForTokens = yygotominor.yy399; } break; diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/sqlite3_parse.y b/SQLiteStudio3/coreSQLiteStudio/parser/sqlite3_parse.y index 0bab877..932e965 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/sqlite3_parse.y +++ b/SQLiteStudio3/coreSQLiteStudio/parser/sqlite3_parse.y @@ -737,11 +737,12 @@ ifexists(X) ::= . {X = new bool(false);} cmd(X) ::= CREATE temp(T) VIEW ifnotexists(E) fullname(N) - AS select(S). { - X = new SqliteCreateView(*(T), *(E), N->name1, N->name2, S); + idxlist_opt(C) AS select(S). { + X = new SqliteCreateView(*(T), *(E), N->name1, N->name2, S, *(C)); delete T; delete E; delete N; + delete C; objectForTokens = X; } @@ -1824,7 +1825,7 @@ nexprlist(X) ::= exprx(E). { cmd(X) ::= CREATE uniqueflag(U) INDEX ifnotexists(E) nm(N1) dbnm(N2) - ON nm(N3) LP idxlist(L) RP + ON nm(N3) LP sortlist(L) RP where_opt(W). { X = new SqliteCreateIndex( *(U), diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/statementtokenbuilder.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/statementtokenbuilder.cpp index ba2ea37..a97b765 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/statementtokenbuilder.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/statementtokenbuilder.cpp @@ -74,7 +74,7 @@ StatementTokenBuilder& StatementTokenBuilder::withComment(const QString& value) StatementTokenBuilder& StatementTokenBuilder::withFloat(double value) { - return with(Token::FLOAT, QString::number(value)); + return with(Token::FLOAT, doubleToString(value)); } StatementTokenBuilder& StatementTokenBuilder::withInteger(qint64 value) diff --git a/SQLiteStudio3/coreSQLiteStudio/querygenerator.cpp b/SQLiteStudio3/coreSQLiteStudio/querygenerator.cpp new file mode 100644 index 0000000..4e2d9b6 --- /dev/null +++ b/SQLiteStudio3/coreSQLiteStudio/querygenerator.cpp @@ -0,0 +1,275 @@ +#include "querygenerator.h" +#include "common/global.h" +#include "common/utils_sql.h" +#include "db/db.h" + +QueryGenerator::QueryGenerator() +{ + +} + +QString QueryGenerator::generateSelectFromTable(Db* db, const QString& table, const StrHash values) +{ + return generateSelectFromTable(db, QString(), table, values); +} + +QString QueryGenerator::generateSelectFromTable(Db* db, const QString& database, const QString& table, const StrHash values) +{ + SchemaResolver resolver(db); + QStringList columns = resolver.getTableColumns(database, table); + return generateSelectFromTableOrView(db, database, table, columns, values); +} + +QString QueryGenerator::generateInsertToTable(Db* db, const QString& table, const StrHash values) +{ + return generateInsertToTable(db, QString(), table, values); +} + +QString QueryGenerator::generateInsertToTable(Db* db, const QString& database, const QString& table, StrHash values) +{ + static_qstring(tpl, "INSERT INTO %1 (%2) VALUES %3"); + static_qstring(rowTpl, "(%1)"); + + Dialect dialect = db->getDialect(); + QString target = toFullObjectName(database, table, dialect); + + // Get all table's columns + SchemaResolver resolver(db); + QStringList tableCols = resolver.getTableColumns(database, table); + + // If no values were given, then column names will serve as values for insertion + if (values.isEmpty()) + { + QStringList valueList = wrapStrings(tableCols); + QList wrappedCols = wrapObjNamesIfNeeded(tableCols, dialect); + return tpl.arg(target, wrappedCols.join(", "), rowTpl.arg(valueList.join(", "))); + } + + // Values were given. Sort given columns in order they are defined in table + QStringList valueCols = values.keys(); + sortWithReferenceList(valueCols, tableCols); + + // Group values into rows + QStringList valueSets = toValueSets(valueCols, values, dialect); + QString valueStr = rowTpl.arg(valueSets.join("), (")); + + // Wrap given column names + QList wrappedCols = wrapObjNamesIfNeeded(valueCols, dialect); + + return tpl.arg(target, wrappedCols.join(", "), valueStr); +} + +QString QueryGenerator::generateUpdateOfTable(Db* db, const QString& table, const StrHash values) +{ + return generateUpdateOfTable(db, QString(), table, values); +} + +QString QueryGenerator::generateUpdateOfTable(Db* db, const QString& database, const QString& table, StrHash values) +{ + static_qstring(tpl, "UPDATE %1 SET %2%3"); + static_qstring(tplWithWhere, "UPDATE %1 SET %2 WHERE %3"); + static_qstring(updateColTpl, "%1 = %2"); + + Dialect dialect = db->getDialect(); + QString target = toFullObjectName(database, table, dialect); + + // Get all columns of the table + SchemaResolver resolver(db); + QStringList tableCols = resolver.getTableColumns(database, table); + + // Create list of "column = 'column'" + QStringList commonUpdateCols; + for (const QString& col : tableCols) + commonUpdateCols << updateColTpl.arg(wrapObjIfNeeded(col, dialect), wrapString(col)); + + // Put it to comma spearated string + QString commonColumnStr = commonUpdateCols.join(", "); + + // If no values were given, we simply use column names as values everywhere + if (values.isEmpty()) + return tplWithWhere.arg(target, commonColumnStr, commonColumnStr); + + // If values were given, then they will be used in WHERE clause + QStringList valueCols = values.keys(); + sortWithReferenceList(valueCols, tableCols); + + // Conditions for WHERE clause + QString conditionStr = valuesToConditionStr(values, dialect); + + return tpl.arg(target, commonColumnStr, conditionStr); +} + +QString QueryGenerator::generateDeleteFromTable(Db* db, const QString& table, const StrHash values) +{ + return generateDeleteFromTable(db, QString(), table, values); +} + +QString QueryGenerator::generateDeleteFromTable(Db* db, const QString& database, const QString& table, StrHash values) +{ + static_qstring(tpl, "DELETE FROM %1%2"); + static_qstring(tplWithWhere, "DELETE FROM %1 WHERE %2"); + static_qstring(conditionColTpl, "%1 = %2"); + + Dialect dialect = db->getDialect(); + QString target = toFullObjectName(database, table, dialect); + + // Get all columns of the table + SchemaResolver resolver(db); + QStringList tableCols = resolver.getTableColumns(database, table); + + // If no values were given, we simply use column names as values everywhere + if (values.isEmpty()) + { + // Create list of "column = 'column'" + QStringList conditionCols; + for (const QString& col : tableCols) + conditionCols << conditionColTpl.arg(wrapObjIfNeeded(col, dialect), wrapString(col)); + + // Put it to comma spearated string + QString conditionStr = conditionCols.join(", "); + + return tplWithWhere.arg(target, conditionStr); + } + + // If values were given, then they will be used in WHERE clause + QStringList valueCols = values.keys(); + sortWithReferenceList(valueCols, tableCols); + + // Conditions for WHERE clause + QString conditionStr = valuesToConditionStr(values, dialect); + + return tpl.arg(target, conditionStr); +} + +QString QueryGenerator::generateSelectFromView(Db* db, const QString& view, const StrHash values) +{ + return generateSelectFromView(db, QString(), view, values); +} + +QString QueryGenerator::generateSelectFromView(Db* db, const QString& database, const QString& view, const StrHash values) +{ + SchemaResolver resolver(db); + QStringList columns = resolver.getViewColumns(database, view); + return generateSelectFromTableOrView(db, database, view, columns, values); +} + +QString QueryGenerator::generateSelectFromSelect(Db* db, const QString& initialSelect, const StrHash values, const BiStrHash& dbNameToAttach) +{ + static_qstring(tpl, "SELECT %1 FROM (%2)%3"); + + Dialect dialect = db->getDialect(); + + // Resolve all columns of the select + SelectResolver resolver(db, initialSelect, dbNameToAttach); + QList columns = resolver.resolveColumnsFromFirstCore(); + + // Generate result columns + QStringList resCols; + for (const SelectResolver::Column& col : columns) + resCols << toResultColumnString(col, dialect); + + // Generate conditions for WHERE clause + QString conditionStr = valuesToConditionStr(values, dialect); + + return tpl.arg(resCols.join(", "), initialSelect, conditionStr); +} + +QString QueryGenerator::generateSelectFromTableOrView(Db* db, const QString& database, const QString& tableOrView, const QStringList& columns, const StrHash values) +{ + static_qstring(tpl, "SELECT %1 FROM %2%3"); + + Dialect dialect = db->getDialect(); + + QString target = toFullObjectName(database, tableOrView, dialect); + QString conditionStr = valuesToConditionStr(values, dialect); + + return tpl.arg(columns.join(", "), target, conditionStr); +} + +QString QueryGenerator::getAlias(const QString& name, QSet& usedAliases) +{ + static_qstring(tpl, "%2%1"); + + QString letter; + if (name.length() == 0) + letter = "t"; + else + letter = name[0]; + + QString alias = letter + "1"; + int i = 2; + while (usedAliases.contains(alias)) + alias = tpl.arg(i++).arg(letter); + + usedAliases << alias; + return alias; +} + +QStringList QueryGenerator::valuesToConditionList(const StrHash& values, Dialect dialect) +{ + static_qstring(conditionTpl1, "%1 = %2"); + static_qstring(conditionTpl2, "%1 IN (%2)"); + + QStringList conditions; + QStringList conditionValues; + for (const QString& col : values.keys()) + { + conditionValues = valueListToSqlList(values[col], dialect); + conditionValues.removeDuplicates(); + if (conditionValues.size() == 1) + conditions << conditionTpl1.arg(wrapObjIfNeeded(col, dialect), conditionValues.first()); + else + conditions << conditionTpl2.arg(wrapObjIfNeeded(col, dialect), conditionValues.join(", ")); + } + return conditions; +} + +QString QueryGenerator::valuesToConditionStr(const StrHash& values, Dialect dialect) +{ + static_qstring(condTpl, " WHERE %1"); + + QStringList conditions = valuesToConditionList(values, dialect); + QString conditionStr = ""; + if (conditions.size() > 0) + conditionStr = condTpl.arg(conditions.join(" AND ")); + + return conditionStr; +} + +QString QueryGenerator::toResultColumnString(const SelectResolver::Column& column, Dialect dialect) +{ + return wrapObjIfNeeded(column.displayName, dialect); +} + +QString QueryGenerator::toFullObjectName(const QString& database, const QString& object, Dialect dialect) +{ + static_qstring(tpl, "%1%2"); + + QString dbName = ""; + if (!database.isEmpty() && dbName.toLower() != "main") + dbName = wrapObjIfNeeded(database, dialect); + + if (!dbName.isEmpty()) + dbName.append("."); + + return tpl.arg(dbName, wrapObjIfNeeded(object, dialect)); +} + +QStringList QueryGenerator::toValueSets(const QStringList& columns, const StrHash values, Dialect dialect) +{ + QStringList rows; + QVariantList rowValues; + QStringList valueList; + + for (int total = values.values().first().size(), i = 0; i < total; i++) + { + rowValues.clear(); + for (const QString& col : columns) + rowValues << values[col][i]; + + valueList = valueListToSqlList(rowValues, dialect); + rows << valueList.join(", "); + } + + return rows; +} diff --git a/SQLiteStudio3/coreSQLiteStudio/querygenerator.h b/SQLiteStudio3/coreSQLiteStudio/querygenerator.h new file mode 100644 index 0000000..3f7df9c --- /dev/null +++ b/SQLiteStudio3/coreSQLiteStudio/querygenerator.h @@ -0,0 +1,75 @@ +#ifndef QUERYGENERATOR_H +#define QUERYGENERATOR_H + +#include "common/column.h" +#include "dialect.h" +#include "common/bistrhash.h" +#include "schemaresolver.h" +#include "common/strhash.h" +#include +#include + +class Db; + +class API_EXPORT QueryGenerator +{ + public: + QueryGenerator(); + + /** + * @brief Generates select of all column from the \p table having given column values matched. + * @overload + */ + QString generateSelectFromTable(Db* db, const QString& table, const StrHash values = StrHash()); + + /** + * @brief Generates SELECT of all column from the \p table having given column values matched. + * @param db Database where the \p table exists. + * @param database Attach name of the database (such as "main" or "temp", or any other used for ATTACH). + * @param table Table to generate select for. + * @param values Values to comply with. + * @return SELECT statement string. + * + * Generates SELECT for given table, listing all result columns explicitly and adding WHERE clause (if \p values is not empty) with columns included in \p values + * having any of values specified for those columns in that parameter. + * + * If \p values is ommited, then no WHERE clause is added. + */ + QString generateSelectFromTable(Db* db, const QString& database, const QString& table, const StrHash values = StrHash()); + + QString generateInsertToTable(Db* db, const QString& table, const StrHash values = StrHash()); + QString generateInsertToTable(Db* db, const QString& database, const QString& table, StrHash values = StrHash()); + + QString generateUpdateOfTable(Db* db, const QString& table, const StrHash values = StrHash()); + QString generateUpdateOfTable(Db* db, const QString& database, const QString& table, StrHash values = StrHash()); + + QString generateDeleteFromTable(Db* db, const QString& table, const StrHash values = StrHash()); + QString generateDeleteFromTable(Db* db, const QString& database, const QString& table, StrHash values = StrHash()); + + QString generateSelectFromView(Db* db, const QString& view, const StrHash values = StrHash()); + QString generateSelectFromView(Db* db, const QString& database, const QString& view, const StrHash values = StrHash()); + + /** + * @brief Generates SELECT for all columns from the \p initialSelect having values matched. + * @param db Database that will be used to resolve tables used in the \p initialSelect + * @param initialSelect The SELECT statement that will be used as a base for generating new query. + * @param values Map of column names and values for them, so the WHERE clause is generated for them. + * @param dbNameToAttach If the \p initialSelect uses attached databases, they should be provided in this parameter, so their symbolic names can be resolved to real attach name. + * @return Generated SELECT statement string. + * + * Generates SELECT using \p initialSelect as a base. Lists all columns from \p initialSelect result columns explicitly (no star operator). + * If there are \p values given, then the WHERE clause is added for them to match columns. + */ + QString generateSelectFromSelect(Db* db, const QString& initialSelect, const StrHash values = StrHash(), const BiStrHash& dbNameToAttach = BiStrHash()); + + private: + QString generateSelectFromTableOrView(Db* db, const QString& database, const QString& tableOrView, const QStringList& columns, const StrHash values = StrHash()); + QString getAlias(const QString& name, QSet& usedAliases); + QStringList valuesToConditionList(const StrHash& values, Dialect dialect); + QString valuesToConditionStr(const StrHash& values, Dialect dialect); + QString toResultColumnString(const SelectResolver::Column& column, Dialect dialect); + QString toFullObjectName(const QString& database, const QString& object, Dialect dialect); + QStringList toValueSets(const QStringList& columns, const StrHash values, Dialect dialect); +}; + +#endif // QUERYGENERATOR_H diff --git a/SQLiteStudio3/coreSQLiteStudio/schemaresolver.cpp b/SQLiteStudio3/coreSQLiteStudio/schemaresolver.cpp index 7988748..0044c3e 100644 --- a/SQLiteStudio3/coreSQLiteStudio/schemaresolver.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/schemaresolver.cpp @@ -250,8 +250,10 @@ SqliteCreateTablePtr SchemaResolver::virtualTableAsRegularTable(const QString &d // Create temp table to see columns. QString newTable = db->getUniqueNewObjectName(strippedName); - QString origTable = wrapObjName(strippedName, dialect); - db->exec(QString("CREATE TEMP TABLE %1 AS SELECT * FROM %2.%3 LIMIT 0;").arg(newTable, dbName, origTable), dbFlags); + QString origTable = wrapObjIfNeeded(strippedName, dialect); + SqlQueryPtr tempTableRes = db->exec(QString("CREATE TEMP TABLE %1 AS SELECT * FROM %2.%3 LIMIT 0;").arg(newTable, dbName, origTable), dbFlags); + if (tempTableRes->isError()) + qWarning() << "Could not create temp table to identify virtual table columns of virtual table " << origTable << ". Error details:" << tempTableRes->getErrorText(); // Get parsed DDL of the temp table. SqliteQueryPtr query = getParsedObject("temp", newTable, TABLE); @@ -288,6 +290,11 @@ QString SchemaResolver::getObjectDdl(const QString &database, const QString &nam // Prepare db prefix. QString dbName = getPrefixDb(database, dialect); + // Standalone or temp table? + QString targetTable = "sqlite_master"; + if (database.toLower() == "temp") + targetTable = "sqlite_temp_master"; + // Cache QString typeStr = objectTypeToString(type); bool useCache = usesCache(); @@ -297,29 +304,32 @@ QString SchemaResolver::getObjectDdl(const QString &database, const QString &nam // Get the DDL QVariant results; + SqlQueryPtr queryResults; if (type != ANY) { - results = db->exec(QString( - "SELECT sql FROM %1.sqlite_master WHERE lower(name) = '%2' AND type = '%3';").arg(dbName, escapeString(lowerName), typeStr), + queryResults = db->exec(QString( + "SELECT sql FROM %1.%4 WHERE lower(name) = '%2' AND type = '%3';").arg(dbName, escapeString(lowerName), typeStr, targetTable), dbFlags - )->getSingleCell(); + ); + } else { - results = db->exec(QString( - "SELECT sql FROM %1.sqlite_master WHERE lower(name) = '%2';").arg(dbName, escapeString(lowerName)), + queryResults = db->exec(QString( + "SELECT sql FROM %1.%3 WHERE lower(name) = '%2';").arg(dbName, escapeString(lowerName), targetTable), dbFlags - )->getSingleCell(); + ); } // Validate query results - if (!results.isValid() || results.isNull()) + if (queryResults->isError()) { - qDebug() << "Could not get object's DDL:" << dbName << "." << name; + qDebug() << "Could not get object's DDL:" << dbName << "." << name << ", details:" << queryResults->getErrorText(); return QString::null; } // The DDL string + results = queryResults->getSingleCell(); QString resStr = results.toString(); // If the DDL doesn't have semicolon at the end (usually the case), add it. @@ -333,6 +343,95 @@ QString SchemaResolver::getObjectDdl(const QString &database, const QString &nam return resStr; } +QStringList SchemaResolver::getColumnsFromDdlUsingPragma(const QString& ddl) +{ + Parser parser(db->getDialect()); + if (!parser.parse(ddl) || parser.getQueries().isEmpty()) + { + qWarning() << "Could not parse DDL for determinating columns using PRAGMA. The DDL was:\n" << ddl; + return QStringList(); + } + + SqliteQueryPtr query = parser.getQueries().first(); + if (query->queryType == SqliteQueryType::CreateTable) + return getColumnsUsingPragma(query.dynamicCast().data()); + + if (query->queryType == SqliteQueryType::CreateView) + return getColumnsUsingPragma(query.dynamicCast().data()); + + qWarning() << "Tried to get columns of DDL using pragma for statement other than table or view:" << sqliteQueryTypeToString(query->queryType) << "for DDL:\n" << ddl; + return QStringList(); +} + +QStringList SchemaResolver::getColumnsUsingPragma(const QString& tableOrView) +{ + static_qstring(query, "PRAGMA table_info(%1)"); + SqlQueryPtr results = db->exec(query.arg(wrapObjIfNeeded(tableOrView, db->getDialect()))); + if (results->isError()) + { + qWarning() << "Could not get column list using PRAGMA for table or view:" << tableOrView << ", error was:" << results->getErrorText(); + return QStringList(); + } + + QStringList cols; + for (const SqlResultsRowPtr& row : results->getAll()) + cols << row->value("name").toString(); + + return cols; +} + +QStringList SchemaResolver::getColumnsUsingPragma(SqliteCreateTable* createTable) +{ + QString name = getUniqueName(); + SqliteCreateTable* stmt = dynamic_cast(createTable->clone()); + stmt->tempKw = true; + stmt->table = name; + stmt->database = QString(); + stmt->rebuildTokens(); + QString ddl = stmt->tokens.detokenize(); + delete stmt; + + SqlQueryPtr result = db->exec(ddl); + if (result->isError()) + { + qWarning() << "Could not create table for finding its columns using PRAGMA. Error was:" << result->getErrorText(); + return QStringList(); + } + + QStringList columns = getColumnsUsingPragma(name); + + static_qstring(dropSql, "DROP TABLE %1"); + db->exec(dropSql.arg(wrapObjIfNeeded(name, db->getDialect()))); + + return columns; +} + +QStringList SchemaResolver::getColumnsUsingPragma(SqliteCreateView* createView) +{ + QString name = getUniqueName(); + SqliteCreateView* stmt = dynamic_cast(createView->clone()); + stmt->tempKw = true; + stmt->view = name; + stmt->database = QString(); + stmt->rebuildTokens(); + QString ddl = stmt->tokens.detokenize(); + delete stmt; + + SqlQueryPtr result = db->exec(ddl); + if (result->isError()) + { + qWarning() << "Could not create view for finding its columns using PRAGMA. Error was:" << result->getErrorText(); + return QStringList(); + } + + QStringList columns = getColumnsUsingPragma(name); + + static_qstring(dropSql, "DROP VIEW %1"); + db->exec(dropSql.arg(wrapObjIfNeeded(name, db->getDialect()))); + + return columns; +} + SqliteQueryPtr SchemaResolver::getParsedObject(const QString &name, ObjectType type) { return getParsedObject("main", name, type); @@ -679,8 +778,11 @@ QList SchemaResolver::getParsedIndexesForTable(const QStri QStringList indexes = getIndexes(database); SqliteQueryPtr query; SqliteCreateIndexPtr createIndex; - foreach (const QString& index, indexes) + for (const QString& index : indexes) { + if (index.startsWith("sqlite_", Qt::CaseInsensitive)) + continue; + query = getParsedObject(database, index, INDEX); if (!query) continue; diff --git a/SQLiteStudio3/coreSQLiteStudio/schemaresolver.h b/SQLiteStudio3/coreSQLiteStudio/schemaresolver.h index 5d325d8..336b0f2 100644 --- a/SQLiteStudio3/coreSQLiteStudio/schemaresolver.h +++ b/SQLiteStudio3/coreSQLiteStudio/schemaresolver.h @@ -141,6 +141,11 @@ class API_EXPORT SchemaResolver QString getObjectDdl(const QString& name, ObjectType type); QString getObjectDdl(const QString& database, const QString& name, ObjectType type); + QStringList getColumnsFromDdlUsingPragma(const QString& ddl); + QStringList getColumnsUsingPragma(const QString& tableOrView); + QStringList getColumnsUsingPragma(SqliteCreateTable* createTable); + QStringList getColumnsUsingPragma(SqliteCreateView* createView); + /** * @brief Parses given object's DDL. * @param name Name of the object in the database. diff --git a/SQLiteStudio3/coreSQLiteStudio/selectresolver.cpp b/SQLiteStudio3/coreSQLiteStudio/selectresolver.cpp index 8107b94..02489ee 100644 --- a/SQLiteStudio3/coreSQLiteStudio/selectresolver.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/selectresolver.cpp @@ -28,13 +28,29 @@ SelectResolver::~SelectResolver() safe_delete(schemaResolver); } +QList SelectResolver::resolveColumnsFromFirstCore() +{ + if (!parseOriginalQuery()) + return QList(); + + return resolve(originalQueryParsed->coreSelects.first()); +} + +QList> SelectResolver::resolveColumns() +{ + if (!parseOriginalQuery()) + return QList>(); + + return resolve(originalQueryParsed.data()); +} + QList SelectResolver::resolve(SqliteSelect::Core *selectCore) { errors.clear(); return resolveCore(selectCore); } -QList > SelectResolver::resolve(SqliteSelect *select) +QList> SelectResolver::resolve(SqliteSelect *select) { errors.clear(); QList > results; @@ -377,10 +393,16 @@ void SelectResolver::resolveDbAndTable(SqliteSelect::Core::ResultColumn *resCol) col.tableAlias = matched.tableAlias; col.flags = matched.flags; } + else if (matched.type == Column::OTHER) + { + col.type = Column::OTHER; + } else if (!ignoreInvalidNames) { - qDebug() << "Source table for column '" << expr->detokenize() + QString colStr = expr->detokenize(); + qDebug() << "Source table for column '" << colStr << "' not matched while resolving select: " << query; + errors << QObject::tr("Could not resolve table for column '%1'.").arg(colStr); } currentCoreResults << col; @@ -473,7 +495,7 @@ TokenList SelectResolver::getResColTokensWithoutAlias(SqliteSelect::Core::Result { depth--; } - else if (token->type == Token::KEYWORD && token->value.compare("AS", Qt::CaseInsensitive) && depth <= 0) + else if (token->type == Token::KEYWORD && token->value.compare("AS", Qt::CaseInsensitive) == 0 && depth <= 0) { idx = idxCandidate; break; @@ -534,6 +556,16 @@ QList SelectResolver::resolveSingleSourceSubSelect(Sqlit { QList columnSources = resolveSubSelect(joinSrc->select); applySubSelectAlias(columnSources, joinSrc->alias); + + QMutableListIterator it(columnSources); + while (it.hasNext()) + { + if (it.next().alias.isEmpty()) + continue; + + it.value().aliasDefinedInSubQuery = true; + } + return columnSources; } @@ -640,6 +672,29 @@ QString SelectResolver::resolveDatabase(const QString& database) return database; } +bool SelectResolver::parseOriginalQuery() +{ + if (originalQueryParsed) + return true; + + Parser parser(db->getDialect()); + if (!parser.parse(query) || parser.getQueries().isEmpty()) + { + qWarning() << "Could not parse query in SelectResolver:" << query; + return false; + } + + SqliteQueryPtr theQuery = parser.getQueries().first(); + if (theQuery.dynamicCast().isNull()) + { + qWarning() << "Parsed query is not SELECT as expected in SelectResolver::parseOriginalQuery():" << query; + return false; + } + + originalQueryParsed = theQuery.dynamicCast(); + return true; +} + int SelectResolver::Table::operator ==(const SelectResolver::Table &other) { return table == other.table && database == other.database && alias == other.alias; diff --git a/SQLiteStudio3/coreSQLiteStudio/selectresolver.h b/SQLiteStudio3/coreSQLiteStudio/selectresolver.h index 4213d73..1edfcb9 100644 --- a/SQLiteStudio3/coreSQLiteStudio/selectresolver.h +++ b/SQLiteStudio3/coreSQLiteStudio/selectresolver.h @@ -109,6 +109,7 @@ class API_EXPORT SelectResolver QString alias; QString tableAlias; QString displayName; + bool aliasDefinedInSubQuery = false; int flags = 0; SqliteSelect::Core::ResultColumn* originalColumn = nullptr; @@ -120,6 +121,9 @@ class API_EXPORT SelectResolver SelectResolver(Db* db, const QString &originalQuery, const BiStrHash& dbNameToAttach); ~SelectResolver(); + QList resolveColumnsFromFirstCore(); + QList > resolveColumns(); + QList resolve(SqliteSelect::Core* selectCore); QList > resolve(SqliteSelect* select); @@ -212,6 +216,7 @@ class API_EXPORT SelectResolver QStringList getTableColumns(const QString& database, const QString& table, const QString &alias); void applySubSelectAlias(QList& columns, const QString& alias); QString resolveDatabase(const QString& database); + bool parseOriginalQuery(); void markDistinctColumns(); void markCompoundColumns(); @@ -224,6 +229,7 @@ class API_EXPORT SelectResolver Db* db = nullptr; QString query; + SqliteSelectPtr originalQueryParsed; /** * @brief Database name to attach name map. diff --git a/SQLiteStudio3/coreSQLiteStudio/services/dbmanager.h b/SQLiteStudio3/coreSQLiteStudio/services/dbmanager.h index 66bbf08..52746e4 100644 --- a/SQLiteStudio3/coreSQLiteStudio/services/dbmanager.h +++ b/SQLiteStudio3/coreSQLiteStudio/services/dbmanager.h @@ -131,7 +131,7 @@ class API_EXPORT DbManager : public QObject * * This method is fast, as it uses hash table lookup. */ - virtual Db* getByName(const QString& name, Qt::CaseSensitivity cs = Qt::CaseSensitive) = 0; + virtual Db* getByName(const QString& name, Qt::CaseSensitivity cs = Qt::CaseInsensitive) = 0; /** * @brief Gives database object by its file path. @@ -162,6 +162,10 @@ class API_EXPORT DbManager : public QObject */ virtual bool isTemporary(Db* db) = 0; + virtual DbPlugin* getPluginForDbFile(const QString& filePath) = 0; + virtual QString generateUniqueDbName(const QString& filePath) = 0; + virtual QString generateUniqueDbName(DbPlugin* plugin, const QString& filePath) = 0; + /** * @brief Generates database name. * @param filePath Database file path. diff --git a/SQLiteStudio3/coreSQLiteStudio/services/impl/dbmanagerimpl.cpp b/SQLiteStudio3/coreSQLiteStudio/services/impl/dbmanagerimpl.cpp index cbdc921..74f482f 100644 --- a/SQLiteStudio3/coreSQLiteStudio/services/impl/dbmanagerimpl.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/services/impl/dbmanagerimpl.cpp @@ -99,7 +99,7 @@ bool DbManagerImpl::updateDb(Db* db, const QString &name, const QString &path, c db->setPath(normalizedPath); db->setConnectionOptions(options); - bool result = false; + bool result = true; if (permanent) { if (CFG->isDbInConfig(oldName)) @@ -284,6 +284,44 @@ QString DbManagerImpl::quickAddDb(const QString& path, const QHash options; + Db* probeDb = nullptr; + for (DbPlugin* plugin : dbPlugins) + { + probeDb = plugin->getInstance("", filePath, options); + if (probeDb) + { + delete probeDb; + probeDb = nullptr; + return plugin; + } + } + + return nullptr; +} + +QString DbManagerImpl::generateUniqueDbName(const QString& filePath) +{ + DbPlugin* plugin = getPluginForDbFile(filePath); + if (!plugin) + return QString(); + + return generateUniqueDbName(plugin, filePath); +} + +QString DbManagerImpl::generateUniqueDbName(DbPlugin* plugin, const QString& filePath) +{ + QString name = plugin->generateDbName(filePath); + name = generateUniqueName(name, getDbNames(), Qt::CaseInsensitive); + return name; +} + void DbManagerImpl::setInMemDbCreatorPlugin(DbPlugin* plugin) { inMemDbCreatorPlugin = plugin; @@ -543,6 +581,7 @@ void DbManagerImpl::aboutToUnload(Plugin* plugin, PluginType* type) InvalidDb* invalidDb = nullptr; DbPlugin* dbPlugin = dynamic_cast(plugin); + dbPlugins.removeOne(dbPlugin); QList toRemove; for (Db* db : dbList) { @@ -577,5 +616,6 @@ void DbManagerImpl::loaded(Plugin* plugin, PluginType* type) return; DbPlugin* dbPlugin = dynamic_cast(plugin); + dbPlugins << dbPlugin; rescanInvalidDatabasesForPlugin(dbPlugin); } diff --git a/SQLiteStudio3/coreSQLiteStudio/services/impl/dbmanagerimpl.h b/SQLiteStudio3/coreSQLiteStudio/services/impl/dbmanagerimpl.h index 67a1335..2e3630a 100644 --- a/SQLiteStudio3/coreSQLiteStudio/services/impl/dbmanagerimpl.h +++ b/SQLiteStudio3/coreSQLiteStudio/services/impl/dbmanagerimpl.h @@ -40,11 +40,14 @@ class API_EXPORT DbManagerImpl : public DbManager QList getValidDbList(); QList getConnectedDbList(); QStringList getDbNames(); - Db* getByName(const QString& name, Qt::CaseSensitivity cs = Qt::CaseSensitive); + Db* getByName(const QString& name, Qt::CaseSensitivity cs = Qt::CaseInsensitive); Db* getByPath(const QString& path); Db* createInMemDb(); bool isTemporary(Db* db); QString quickAddDb(const QString &path, const QHash &options); + DbPlugin* getPluginForDbFile(const QString& filePath); + QString generateUniqueDbName(const QString& filePath); + QString generateUniqueDbName(DbPlugin* plugin, const QString& filePath); /** * @brief Defines database plugin used for creating in-memory databases. @@ -138,6 +141,8 @@ class API_EXPORT DbManagerImpl : public DbManager */ DbPlugin* inMemDbCreatorPlugin = nullptr; + QList dbPlugins; + private slots: /** * @brief Slot called when connected to db. diff --git a/SQLiteStudio3/coreSQLiteStudio/services/impl/pluginmanagerimpl.cpp b/SQLiteStudio3/coreSQLiteStudio/services/impl/pluginmanagerimpl.cpp index 017d260..9fe21de 100644 --- a/SQLiteStudio3/coreSQLiteStudio/services/impl/pluginmanagerimpl.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/services/impl/pluginmanagerimpl.cpp @@ -341,7 +341,7 @@ bool PluginManagerImpl::shouldAutoLoad(const QString& pluginName) { QStringList loadedPlugins = CFG_CORE.General.LoadedPlugins.get().split(",", QString::SkipEmptyParts); QStringList pair; - foreach (const QString& loadedPlugin, loadedPlugins) + for (const QString& loadedPlugin : loadedPlugins) { pair = loadedPlugin.split("="); if (pair.size() != 2) @@ -354,7 +354,7 @@ bool PluginManagerImpl::shouldAutoLoad(const QString& pluginName) return (bool)pair[1].toInt(); } - return true; + return pluginContainer[pluginName]->loadByDefault; } QStringList PluginManagerImpl::getAllPluginNames(PluginType* type) const @@ -626,6 +626,7 @@ bool PluginManagerImpl::readMetaData(PluginManagerImpl::PluginContainer* contain container->author = metaData["author"].toString(); container->description = metaData["description"].toString(); container->title = metaData["title"].toString(); + container->loadByDefault = metaData.contains("loadByDefault") ? metaData["loadByDefault"].toBool() : true; } else if (container->plugin) { @@ -635,6 +636,7 @@ bool PluginManagerImpl::readMetaData(PluginManagerImpl::PluginContainer* contain container->author = container->plugin->getAuthor(); container->description = container->plugin->getDescription(); container->title = container->plugin->getTitle(); + container->loadByDefault = true; } else { @@ -706,12 +708,9 @@ QHash PluginManagerImpl::readMetaData(const QJsonObject& meta results["name"] = metaData.value("className").toString(); QJsonObject root = metaData.value("MetaData").toObject(); - results["type"] = root.value("type").toString(); - results["title"] = root.value("title").toString(); - results["description"] = root.value("description").toString(); - results["author"] = root.value("author").toString(); - results["version"] = root.value("version").toInt(); - results["ui"] = root.value("ui").toString(); + for (const QString& k : root.keys()) { + results[k] = root.value(k).toVariant(); + } return results; } diff --git a/SQLiteStudio3/coreSQLiteStudio/services/impl/pluginmanagerimpl.h b/SQLiteStudio3/coreSQLiteStudio/services/impl/pluginmanagerimpl.h index 6968cab..c9d56aa 100644 --- a/SQLiteStudio3/coreSQLiteStudio/services/impl/pluginmanagerimpl.h +++ b/SQLiteStudio3/coreSQLiteStudio/services/impl/pluginmanagerimpl.h @@ -139,6 +139,14 @@ class API_EXPORT PluginManagerImpl : public PluginManager */ bool builtIn = false; + /** + * @brief Flag indicating that plugin should be loaded, unless user unloaded it manually. + * + * If this flag is set to false, then the plugin will not be loaded, even it was not manually unloaded. + * This flag can be defined in plugin's json file using property named 'loadByDefault'. + */ + bool loadByDefault = true; + /** * @brief Names of plugnis that this plugin depends on. */ diff --git a/SQLiteStudio3/coreSQLiteStudio/sqlitestudio.cpp b/SQLiteStudio3/coreSQLiteStudio/sqlitestudio.cpp index 46486e8..efb5bb4 100644 --- a/SQLiteStudio3/coreSQLiteStudio/sqlitestudio.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/sqlitestudio.cpp @@ -39,7 +39,7 @@ DEFINE_SINGLETON(SQLiteStudio) -static const int sqlitestudioVersion = 30007; +static const int sqlitestudioVersion = 30100; SQLiteStudio::SQLiteStudio() { diff --git a/SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp b/SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp index 3e23239..a0f6262 100644 --- a/SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp @@ -36,6 +36,11 @@ void TableModifier::alterTable(SqliteCreateTablePtr newCreateTable) existingColumns = newCreateTable->getColumnNames(); newName = newCreateTable->table; + if (db->getDialect() == Dialect::Sqlite3) + sqls << "PRAGMA foreign_keys = 0;"; + + handleFkConstrains(newCreateTable.data(), createTable->table, newName); + QString tempTableName; if (table.compare(newName, Qt::CaseInsensitive) == 0) tempTableName = renameToTemp(); @@ -44,7 +49,7 @@ void TableModifier::alterTable(SqliteCreateTablePtr newCreateTable) sqls << newCreateTable->detokenize(); copyDataTo(newCreateTable); - handleFks(tempTableName); + handleFks(); // If temp table was created, it means that table name hasn't changed. In that case we need to cleanup temp table (drop it). // Otherwise, the table name has changed, therefor there still remains the old table which we copied data from - we need to drop it here. @@ -53,6 +58,9 @@ void TableModifier::alterTable(SqliteCreateTablePtr newCreateTable) handleIndexes(); handleTriggers(); handleViews(); + + if (db->getDialect() == Dialect::Sqlite3) + sqls << "PRAGMA foreign_keys = 1;"; } void TableModifier::renameTo(const QString& newName) @@ -60,15 +68,10 @@ void TableModifier::renameTo(const QString& newName) if (!createTable) return; - if (dialect == Dialect::Sqlite3) - { - sqls << QString("ALTER TABLE %1 RENAME TO %2;").arg(wrapObjIfNeeded(table, dialect), wrapObjIfNeeded(newName, dialect)); - } - else - { - sqls << QString("CREATE TABLE %1 AS SELECT * FROM %2;").arg(wrapObjIfNeeded(newName, dialect), wrapObjIfNeeded(table, dialect)) - << QString("DROP TABLE %1;").arg(wrapObjIfNeeded(table, dialect)); - } + // Using ALTER TABLE RENAME TO is not a good solution here, because it automatically renames all occurrences in REFERENCES, + // which we don't want, because we rename a lot to temporary tables and drop them. + sqls << QString("CREATE TABLE %1 AS SELECT * FROM %2;").arg(wrapObjIfNeeded(newName, dialect), wrapObjIfNeeded(table, dialect)) + << QString("DROP TABLE %1;").arg(wrapObjIfNeeded(table, dialect)); table = newName; createTable->table = newName; @@ -93,14 +96,19 @@ void TableModifier::copyDataTo(const QString& targetTable) copyDataTo(targetTable, colsToCopy, colsToCopy); } -void TableModifier::handleFks(const QString& tempTableName) +void TableModifier::handleFks() { + tablesHandledForFk << originalTable; + SchemaResolver resolver(db); QStringList fkTables = resolver.getFkReferencingTables(originalTable); - foreach (const QString& fkTable, fkTables) + for (const QString& fkTable : fkTables) { + if (tablesHandledForFk.contains(fkTable, Qt::CaseInsensitive)) + continue; // Avoid recurrent FK handling + TableModifier subModifier(db, fkTable); if (!subModifier.isValid()) { @@ -109,15 +117,22 @@ void TableModifier::handleFks(const QString& tempTableName) continue; } + // Those were removed when fixing #2954. Seem to be useless for subHandleFks(). Unless there's some bug report for it, + // they should be removed in near future: + subModifier.usedTempTableNames = usedTempTableNames; - subModifier.tableColMap = tableColMap; subModifier.triggerNameToDdlMap = triggerNameToDdlMap; - subModifier.existingColumns = existingColumns; - subModifier.newName = newName; - subModifier.subHandleFks(originalTable, tempTableName); + subModifier.existingColumns = existingColumns; // for identifying removed columns + subModifier.tableColMap = tableColMap; // for identifying renamed columns + subModifier.newName = fkTable; + subModifier.tablesHandledForFk = tablesHandledForFk; + subModifier.handleFks(originalTable, newName); sqls += subModifier.generateSqls(); modifiedTables << fkTable; + triggerNameToDdlMap = subModifier.triggerNameToDdlMap; + tablesHandledForFk = subModifier.tablesHandledForFk; + usedTempTableNames = subModifier.usedTempTableNames; modifiedTables += subModifier.getModifiedTables(); modifiedIndexes += subModifier.getModifiedIndexes(); @@ -129,22 +144,9 @@ void TableModifier::handleFks(const QString& tempTableName) } } -void TableModifier::subHandleFks(const QString& oldName, const QString& oldTempName) +void TableModifier::handleFks(const QString& oldName, const QString& theNewName) { - bool modified = false; - foreach (SqliteCreateTable::Constraint* fk, createTable->getForeignKeysByTable(oldName)) - { - if (subHandleFks(fk->foreignKey, oldName, oldTempName)) - modified = true; - } - - foreach (SqliteCreateTable::Column::Constraint* fk, createTable->getColumnForeignKeysByTable(oldName)) - { - if (subHandleFks(fk->foreignKey, oldName, oldTempName)) - modified = true; - } - - if (!modified) + if (!handleFkConstrains(createTable.data(), oldName, theNewName)) return; QString tempName = renameToTemp(); @@ -155,7 +157,7 @@ void TableModifier::subHandleFks(const QString& oldName, const QString& oldTempN copyDataTo(originalTable); - handleFks(tempName); + handleFks(); sqls << QString("DROP TABLE %1;").arg(wrapObjIfNeeded(tempName, dialect)); @@ -163,21 +165,15 @@ void TableModifier::subHandleFks(const QString& oldName, const QString& oldTempN simpleHandleTriggers(); } -bool TableModifier::subHandleFks(SqliteForeignKey* fk, const QString& oldName, const QString& oldTempName) +bool TableModifier::handleFks(SqliteForeignKey* fk, const QString& oldName, const QString& theNewName) { // If table was not renamed (but uses temp table name), we will rename temp name into target name. // If table was renamed, we will rename old name to new name. bool modified = false; // Table - if (handleName(oldName, fk->foreignTable)) - modified = true; - else if (!oldTempName.isNull() && fk->foreignTable.compare(oldName, Qt::CaseInsensitive) == 0) - { - // This is the case when main table was not renamed - we will stay with the original name, but we need to mark it as modified, - // so the table gets recreated (the temp table is changed to the original table name in this FK). + if (handleName(oldName, theNewName, fk->foreignTable)) modified = true; - } // Columns if (handleIndexedColumns(fk->indexedColumns)) @@ -186,45 +182,59 @@ bool TableModifier::subHandleFks(SqliteForeignKey* fk, const QString& oldName, c return modified; } +bool TableModifier::handleFkConstrains(SqliteCreateTable* stmt, const QString& oldName, const QString& theNewName) +{ + bool modified = false; + for (SqliteCreateTable::Constraint* fk : stmt->getForeignKeysByTable(oldName)) + { + if (handleFks(fk->foreignKey, oldName, theNewName)) + modified = true; + } + + for (SqliteCreateTable::Column::Constraint* fk : stmt->getColumnForeignKeysByTable(oldName)) + { + if (handleFks(fk->foreignKey, oldName, theNewName)) + modified = true; + } + return modified; +} + bool TableModifier::handleName(const QString& oldName, QString& valueToUpdate) { - if (newName.compare(oldName, Qt::CaseInsensitive) == 0) + return handleName(oldName, newName, valueToUpdate); +} + +bool TableModifier::handleName(const QString& oldName, const QString& theNewName, QString& valueToUpdate) +{ + if (theNewName.compare(oldName, Qt::CaseInsensitive) == 0) return false; if (valueToUpdate.compare(oldName, Qt::CaseInsensitive) == 0) { - valueToUpdate = newName; + valueToUpdate = theNewName; return true; } return false; } -bool TableModifier::handleIndexedColumns(QList& columnsToUpdate) +bool TableModifier::handleIndexedColumnsInitial(SqliteOrderBy* col, bool& modified) { - bool modified = false; - QString lowerName; - QMutableListIterator it(columnsToUpdate); - while (it.hasNext()) - { - SqliteIndexedColumn* idxCol = it.next(); + if (col->isSimpleColumn()) + return false; - // If column was modified, assign new name - lowerName = idxCol->name.toLower(); - if (tableColMap.contains(lowerName)) - { - idxCol->name = tableColMap[lowerName]; - modified = true; - continue; - } + QString oldExpr = col->expr->tokens.detokenize(); + if (!handleExpr(col->expr)) + qWarning() << "Handling column change in multi-level expression of CREATE INDEX column failed. The change will most probably be skipped in the final update DDL."; - // It wasn't modified, but it's not on existing columns list? Remove it. - if (indexOf(existingColumns, idxCol->name, Qt::CaseInsensitive) == -1) - { - it.remove(); - modified = true; - } - } - return modified; + modified = (col->expr->tokens.detokenize() != oldExpr); + return true; +} + +bool TableModifier::handleIndexedColumnsInitial(SqliteIndexedColumn* col, bool& modified) +{ + UNUSED(col); + UNUSED(modified); + return false; } bool TableModifier::handleColumnNames(QStringList& columnsToUpdate) @@ -783,6 +793,51 @@ bool TableModifier::handleExprWithTrigTable(SqliteExpr* expr) return true; } +bool TableModifier::handleExpr(SqliteExpr* expr) +{ + // Handle subqueries + QList exprList; + exprList << expr->expr1; + exprList << expr->expr2; + exprList << expr->expr3; + exprList.append(expr->exprList); + exprList.removeAll(nullptr); + if (!exprList.isEmpty()) + { + bool res = true; + for (SqliteExpr* e : exprList) + { + res &= handleExpr(e); + if (!res) + break; + } + return res; + } + + // No need to handle subselect. Currently handleExpr() is used only in context of expr index column (in CREATE INDEX), + // which does not allow subselects. If the method comes to use with subselects supported, then this has to be implemented. + + // Handle specific column + if (expr->mode != SqliteExpr::Mode::ID) + return true; + + if (!expr->database.isNull()) + return true; + + QStringList columns = QStringList({expr->column}); + if (!handleColumnNames(columns)) + return true; + + if (columns.isEmpty()) + { + qDebug() << "Column in the expression is no longer present in the table. Cannot update the expression automatically."; + return false; + } + + expr->column = columns.first(); + return true; +} + void TableModifier::simpleHandleIndexes() { SchemaResolver resolver(db); diff --git a/SQLiteStudio3/coreSQLiteStudio/tablemodifier.h b/SQLiteStudio3/coreSQLiteStudio/tablemodifier.h index 675202d..cba27ed 100644 --- a/SQLiteStudio3/coreSQLiteStudio/tablemodifier.h +++ b/SQLiteStudio3/coreSQLiteStudio/tablemodifier.h @@ -59,6 +59,7 @@ class API_EXPORT TableModifier bool handleAllExprWithTrigTable(SqliteStatement* stmt, const QString& contextTable); bool handleExprListWithTrigTable(const QList& exprList); bool handleExprWithTrigTable(SqliteExpr* expr); + bool handleExpr(SqliteExpr* expr); void simpleHandleIndexes(); void simpleHandleTriggers(const QString& view = QString::null); SqliteQueryPtr parseQuery(const QString& ddl); @@ -68,16 +69,55 @@ class API_EXPORT TableModifier * @param newCreateTable * Finds all tables referencing currently modified table and updates their referenced table name and columns. */ - void handleFks(const QString& tempTableName); - void subHandleFks(const QString& oldName, const QString& oldTempName); - bool subHandleFks(SqliteForeignKey* fk, const QString& oldName, const QString& oldTempName); + void handleFks(); + void handleFks(const QString& oldName, const QString& theNewName); + bool handleFks(SqliteForeignKey* fk, const QString& oldName, const QString& theNewName); + bool handleFkConstrains(SqliteCreateTable* stmt, const QString& oldName, const QString& theNewName); bool handleName(const QString& oldName, QString& valueToUpdate); - bool handleIndexedColumns(QList& columnsToUpdate); + static bool handleName(const QString& oldName, const QString& theNewName, QString& valueToUpdate); + bool handleIndexedColumns(const QList& columnsToUpdate); + bool handleIndexedColumnsInitial(SqliteOrderBy* col, bool& modified); + bool handleIndexedColumnsInitial(SqliteIndexedColumn* col, bool& modified); bool handleColumnNames(QStringList& columnsToUpdate); bool handleColumnTokens(TokenList& columnsToUpdate); bool handleUpdateColumns(SqliteUpdate* update); + + template + bool handleIndexedColumns(QList& columnsToUpdate) + { + bool modified = false; + QString lowerName; + QString colName; + QMutableListIterator it(columnsToUpdate); + while (it.hasNext()) + { + T* idxCol = it.next(); + if (handleIndexedColumnsInitial(idxCol, modified)) + continue; + + colName = idxCol->getColumnName(); + + // If column was modified, assign new name + lowerName = colName.toLower(); + if (tableColMap.contains(lowerName)) + { + idxCol->setColumnName(tableColMap[lowerName]); + modified = true; + continue; + } + + // It wasn't modified, but it's not on existing columns list? Remove it. + if (indexOf(existingColumns, colName, Qt::CaseInsensitive) == -1) + { + it.remove(); + modified = true; + } + } + return modified; + } + Db* db = nullptr; Dialect dialect; @@ -114,6 +154,7 @@ class API_EXPORT TableModifier QStringList existingColumns; QHash tableColMap; QHash triggerNameToDdlMap; + QStringList tablesHandledForFk; QStringList modifiedTables; QStringList modifiedIndexes; QStringList modifiedTriggers; @@ -121,4 +162,5 @@ class API_EXPORT TableModifier QStringList usedTempTableNames; }; + #endif // TABLEMODIFIER_H diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_de.qm b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_de.qm index 9dad8df..2c10fb5 100644 Binary files a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_de.qm and b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_de.qm differ diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_de.ts b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_de.ts index 51b496d..0c60582 100644 --- a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_de.ts +++ b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_de.ts @@ -1,6 +1,6 @@ - + AbstractDb @@ -38,19 +38,25 @@ Die Datenbank ist zur Ausführung von Abfragen nicht geöffnet worden. - + + Could not disable foreign keys in the database. Details: %1 + chain executor + Fremdschlüssel konnten nicht deaktiviert werden für die Datenbank. Details: %1 + + + Could not start a database transaction. Details: %1 chain executor Es kann keine Datenbanktransaktion gestartet werden. Details: %1 - + Interrupted chain executor Abgebrochen - + Could not commit a database transaction. Details: %1 chain executor Die Datenbanktransaktion kann nicht 'committet' werden. Details: %1 @@ -153,25 +159,25 @@ Die Datenbank %1 kann nicht aktualisiert werden. Grund: %2 - - + + Database file doesn't exist. Die Datenbankdatei existiert nicht. - - - + + + No supporting plugin loaded. Es wurde kein passendes plugin geladen. - + Database could not be initialized. Die Datenbank kann nicht initialisiert werden. - + No suitable database driver plugin found. Es wurde kein passender Datenbanktreiber (plugin) gefunden. @@ -228,21 +234,28 @@ Tabellen, Indizes, Trigger und Views die in Datenbank %3 kopiert wurden, werden Error while creating trigger in target database: %1 Fehler beim Erstellen eines Triggers in der Zieldatenbank %1 + + + + + Could not parse object '%1' in order to move or copy it. + Objekt '%1' konnte analysieren, um es zu verschieben oder kopieren zu können. + DbVersionConverter - + Target file exists, but could not be overwritten. Die Zieldatei existiert zwar, konnte aber nicht überschrieben werden. - + Could not find proper database plugin to create target database. Es konnte kein geeignetes Datenbankplugin gefunden werden, um die Zieldatenbank zu erzeugen. - + Error while converting database: %1 Fehler beim Konvertieren der Datenbank: %1 @@ -320,33 +333,33 @@ Tabellen, Indizes, Trigger und Views die in Datenbank %3 kopiert wurden, werden ExportWorker - + Error while exporting query results: %1 Fehler beim Exportieren der Abfrageergebnisse: %1 - + Error while counting data column width to export from query results: %1 Fehler beim Ermitteln der Spaltenbreite für den Export der Abfrageergebnisse: %1 - - + + Could not parse %1 in order to export it. It will be excluded from the export output. %1 konnte zum Exportieren nicht korrekt verarbeitet werden. Diese Daten werden nicht exportiert. - + Error while reading data to export from table %1: %2 Fehler beim Lesen der zu exportierenden Daten aus der Tabelle %1: %2 - + Error while counting data to export from table %1: %2 Fehler beim Ermitteln der zu exportierenden Daten aus der Tabelle %1: %2 - + Error while counting data column width to export from table %1: %2 Fehler beim Ermitteln der Spaltenbreite für den Export aus Tabelle %1: %2 @@ -446,20 +459,20 @@ Tabellen, Indizes, Trigger und Views die in Datenbank %3 kopiert wurden, werden - - + + Error while importing data: %1 Fehler beim Import der Daten: %1 - + Interrupted. import process status update Abgebrochen. - + Could not import data row number %1. The row was ignored. Problem details: %2 Datenzeile %1 konnte nicht importiert werden. Die Zeile wurde ignoriert. Problembeschreibung: %2 @@ -487,13 +500,13 @@ Tabellen, Indizes, Trigger und Views die in Datenbank %3 kopiert wurden, werden Plugin %1 konnte wegen eines Fehlers bei der Initialisierung nicht geladen werden. - + min: %1 plugin dependency version Min: %1 - + max: %1 plugin dependency version Max: %1 @@ -833,7 +846,7 @@ Problembeschreibung: %2 SQLite %1 unterstützt keine '%2' Klausel Ausdrücken. - + Could not attach database %1: %2 Generell muss in den Übersetzungen das 'attached' genauer analysiert werden. Die Datenbank %1 kann nicht angefügt werden: %2 @@ -846,13 +859,13 @@ Problembeschreibung: %2 - + Parser stack overflow Stacküberlauf bei Verarbeitung - + Syntax error Syntaxfehler @@ -907,10 +920,15 @@ Problembeschreibung: %2 Der Implementationscode darf nicht leer sein. - + Could not resolve data source for column: %1 Die Datenquelle für Spalte %1 kann nicht aufgelöst werden. + + + Could not resolve table for column '%1'. + + Could not initialize configuration file. Any configuration changes and queries history will be lost after application restart. Tried to initialize the file at following localizations: %1. @@ -960,39 +978,39 @@ Problembeschreibung: %2 Tabellen füllen - + Table %1 is referencing table %2, but the foreign key definition will not be updated for new table definition due to problems while parsing DDL of the table %3. Tabelle %1 referenziert Tabelle %2, jedoch wird die 'foreign key'-Definition für die neue Tabellendefinition nicht aktualisiert, da es Probleme bei der DDL-Analyse von Tabelle %3 gibt. - + All columns indexed by the index %1 are gone. The index will not be recreated after table modification. Alle Spalten, die von Index %1 indiziert wurden, sind verloren. Der Index wird nach der Tabellenmodifikation nicht neu erstellt. - + There is problem with proper processing trigger %1. It may be not fully updated afterwards and will need your attention. Es ist ein Problem bei der korrekten Verarbeitung des Triggers %1 aufgetreten. Er wird möglicherweise nicht vollständig aktualisert werden und sollte geprüft werden. - + Cannot not update trigger %1 according to table %2 modification. Die Aktualisierung des Triggers %1, resultierend aus der Änderung der Tabelle %2, kann nicht ausgeführt werden. - - - + + + There is a problem with updating an %1 statement within %2 trigger. One of the %1 substatements which might be referring to table %3 cannot be properly modified. Manual update of the trigger may be necessary. Es ist ein Problem beim Aktualisieren einer %1 Abfrage innerhalb eines %2 Triggers aufgetreten. Eine der %1 Unterabfragen, welche möglicherweise die Tabelle %3 referenziert, kann nicht geändert werden. Eine manuelle Anpassung des Triggers wird nötig sein. - + All columns covered by the trigger %1 are gone. The trigger will not be recreated after table modification. Alle Spalten, die durch den Trigger %1 abgedeckt wurden, sind verloren. Der Trigger wird nach der Änderung nicht wiederhergestellt. - + Cannot not update view %1 according to table %2 modifications. The view will remain as it is. Die Aktualisierung des Views %1, resultierend aus der Änderung der Tabelle %2, kann nicht ausgeführt werden. Der View wird daher nicht geändert. @@ -1016,29 +1034,29 @@ The view will remain as it is. QueryExecutor - + Execution interrupted. Ausführung abgebrochen. - + Database is not open. Die Datenbank ist nicht geöffnet. - + Only one query can be executed simultaneously. Es kann nur eine Abfrage gleichzeitig ausgeführt werden. - - + + An error occured while executing the count(*) query, thus data paging will be disabled. Error details from the database: %1 Hier muss ggf. noch das 'data paging' korrekt übersetzt werden. Beim Ausführen der count(*) Abfrage ist ein Fehler aufgetreten, daher wird das data paging abgeschaltet. Problemdetails der Datenbank: %1 - + SQLiteStudio was unable to extract metadata from the query. Results won't be editable. SQLiteStudio konnte keine Metadaten aus der Abfrage extrahieren. Die Ergebnismenge kann daher nicht editiert werden. @@ -1094,7 +1112,7 @@ The view will remain as it is. An error occurred while checking for updates: %1. - Beim Prüfen auf Updates trat folgender Fehler auf: %1 + Beim Prüfen auf Updates trat folgender Fehler auf: %1. diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_es.ts b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_es.ts index 8131da9..6cab7b8 100644 --- a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_es.ts +++ b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_es.ts @@ -1,6 +1,6 @@ - + AbstractDb @@ -38,19 +38,25 @@ - + + Could not disable foreign keys in the database. Details: %1 + chain executor + + + + Could not start a database transaction. Details: %1 chain executor - + Interrupted chain executor - + Could not commit a database transaction. Details: %1 chain executor @@ -152,25 +158,25 @@ - - + + Database file doesn't exist. - - - + + + No supporting plugin loaded. - + Database could not be initialized. - + No suitable database driver plugin found. @@ -226,21 +232,28 @@ Tables, indexes, triggers and views copied to database %3 will remain. Error while creating trigger in target database: %1 + + + + + Could not parse object '%1' in order to move or copy it. + + DbVersionConverter - + Target file exists, but could not be overwritten. - + Could not find proper database plugin to create target database. - + Error while converting database: %1 @@ -318,33 +331,33 @@ Tables, indexes, triggers and views copied to database %3 will remain. ExportWorker - + Error while exporting query results: %1 - + Error while counting data column width to export from query results: %1 - - + + Could not parse %1 in order to export it. It will be excluded from the export output. - + Error while reading data to export from table %1: %2 - + Error while counting data to export from table %1: %2 - + Error while counting data column width to export from table %1: %2 @@ -443,20 +456,20 @@ Tables, indexes, triggers and views copied to database %3 will remain. - - + + Error while importing data: %1 - + Interrupted. import process status update - + Could not import data row number %1. The row was ignored. Problem details: %2 @@ -484,13 +497,13 @@ Tables, indexes, triggers and views copied to database %3 will remain. - + min: %1 plugin dependency version - + max: %1 plugin dependency version @@ -827,7 +840,7 @@ Error details: %2 - + Could not attach database %1: %2 @@ -839,13 +852,13 @@ Error details: %2 - + Parser stack overflow - + Syntax error @@ -900,10 +913,15 @@ Error details: %2 - + Could not resolve data source for column: %1 + + + Could not resolve table for column '%1'. + + Could not initialize configuration file. Any configuration changes and queries history will be lost after application restart. Tried to initialize the file at following localizations: %1. @@ -952,39 +970,39 @@ Error details: %2 - + Table %1 is referencing table %2, but the foreign key definition will not be updated for new table definition due to problems while parsing DDL of the table %3. - + All columns indexed by the index %1 are gone. The index will not be recreated after table modification. - + There is problem with proper processing trigger %1. It may be not fully updated afterwards and will need your attention. - + Cannot not update trigger %1 according to table %2 modification. - - - + + + There is a problem with updating an %1 statement within %2 trigger. One of the %1 substatements which might be referring to table %3 cannot be properly modified. Manual update of the trigger may be necessary. - + All columns covered by the trigger %1 are gone. The trigger will not be recreated after table modification. - + Cannot not update view %1 according to table %2 modifications. The view will remain as it is. @@ -1008,28 +1026,28 @@ The view will remain as it is. QueryExecutor - + Execution interrupted. - + Database is not open. - + Only one query can be executed simultaneously. - - + + An error occured while executing the count(*) query, thus data paging will be disabled. Error details from the database: %1 - + SQLiteStudio was unable to extract metadata from the query. Results won't be editable. diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_fr.ts b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_fr.ts index 5d6090c..6f86594 100644 --- a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_fr.ts +++ b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_fr.ts @@ -7,7 +7,7 @@ Cannot execute query on closed database. - Impossible d'exécuter la requête sur une base de données fermée. + Impossible d’exécuter la requête sur une base de données fermée. @@ -29,19 +29,19 @@ The database for executing queries was not defined. chain executor - La base de données pour exécuter des requêtes n'était pas définie. + La base de données pour exécuter des requêtes n’était pas définie. The database for executing queries was not open. chain executor - La base de données pour exécuter des requêtes n'est pas ouverte. + La base de données pour exécuter des requêtes n’est pas ouverte. Could not start a database transaction. Details: %1 chain executor - Impossible d'initialiser une transaction de la base de données:%1 + Impossible d’initialiser une transaction de la base de données:%1 @@ -53,7 +53,7 @@ Could not commit a database transaction. Details: %1 chain executor - Impossible d'enregistrer la transaction de la base de données:%1 + Impossible d’enregistrer la transaction de la base de données:%1 @@ -76,7 +76,7 @@ New index name - Nouveau nom d'index + Nouveau nom d’index @@ -116,7 +116,7 @@ Error message - Message d'erreur + Message d’erreur @@ -126,7 +126,7 @@ Any word - N'importe quel mot + N’importe quel mot @@ -144,18 +144,18 @@ Could not add database %1: %2 - Impossible d'ajouter une base de données %1: %2 + Impossible d’ajouter une base de données %1: %2 Database %1 could not be updated, because of an error: %2 - La base de données %1 ne peut ëtre mise à jour à cause de l'erreur: %2 + La base de données %1 ne peut ëtre mise à jour à cause de l’erreur: %2 Database file doesn't exist. - Le fichier de la base de données n'existe pas. + Le fichier de la base de données n’existe pas. @@ -186,7 +186,7 @@ Could not parse table. - Impossible d'analyser la table. + Impossible d’analyser la table. @@ -220,7 +220,7 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma Error while creating index in target database: %1 - Erreur lors de la création de l'index de la base de données:%1 + Erreur lors de la création de l’index de la base de données:%1 @@ -264,7 +264,7 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma Date of execution ddl history header - Date d'exécution + Date d’exécution @@ -278,22 +278,22 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma Export plugin %1 doesn't support exporing query results. - Plugin d'export %1 ne supporte pas l'exportation de la requête. + Plugin d’export %1 ne supporte pas l’exportation de la requête. Export plugin %1 doesn't support exporing tables. - Plugin d'export %1 ne supporte pas l'exportation de la table. + Plugin d’export %1 ne supporte pas l’exportation de la table. Export plugin %1 doesn't support exporing databases. - Plugin d'export %1 ne supporte pas l'exportation de la base de données. + Plugin d’export %1 ne supporte pas l’exportation de la base de données. Export format '%1' is not supported. Supported formats are: %2. - Format d'export %1 n'est pas supporté. Les formats supportés sont: %2. + Format d’export « %1 » n’est pas supporté. Les formats supportés sont: %2. @@ -303,7 +303,7 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma Export to the file '%1' was successful. - Export vers le fichier '%1' avec succès. + Export vers le fichier ’%1’ avec succès. @@ -313,7 +313,7 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma Could not export to file %1. File cannot be open for writting. - Impossible d'exporter vers le fichier '%1'. Le fichier ne peut être ouvert en écriture. + Impossible d’exporter vers le fichier %1. Le fichier ne peut être ouvert en écriture. @@ -321,7 +321,7 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma Error while exporting query results: %1 - Erreur lors de l'exportation des résultats de la requête:%1 + Erreur lors de l’exportation des résultats de la requête:%1 @@ -332,7 +332,7 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma Could not parse %1 in order to export it. It will be excluded from the export output. - Impossible d'analyser %1 afin de l'exporter. Celle-ci sera excluse de l'exportation. + Impossible d’analyser %1 afin de l’exporter. Celle-ci sera excluse de l’exportation. @@ -355,7 +355,7 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma Invalid number of arguments to function '%1'. Expected %2, but got %3. - Nombre de paramètres invalide de la fonction%1. Attendu %2, obtenu %3. + Nombre de paramètres invalide de la fonction %1. Attendu %2, obtenu %3. @@ -365,7 +365,7 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma Function %1(%2) was registered with language %3, but the plugin supporting that language is not currently loaded. - La fonction %1(%2) est référencée avec le langage %3, mais le plugin supportant ce langage n'est actuellement pas chargé. + La fonction %1(%2) est référencée avec le langage %3, mais le plugin supportant ce langage n’est actuellement pas chargé. @@ -376,17 +376,17 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma Could not open file %1 for reading: %2 - Impossible d'ouvrir en lecture le ficher %1:%2 + Impossible d’ouvrir en lecture le ficher %1:%2 Could not open file %1 for writting: %2 - Impossible d'ouvrir en écriture le ficher %1:%2 + Impossible d’ouvrir en écriture le ficher %1:%2 Error while writting to file %1: %2 - Erreur lors de l'écriture du fichier %1:%2 + Erreur lors de l’écriture du fichier %1:%2 @@ -399,7 +399,7 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma Could not initialize text codec for exporting. Using default codec: %1 - Impossible d'initialiser le paramètre texte por l'export. Utulisation du paramètre par défaut: %1 + Impossible d’initialiser le paramètre texte por l’export. Utulisation du paramètre par défaut: %1 @@ -407,7 +407,7 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma Imported data to the table '%1' successfully. - Importation des données de la table '%1' réussie. + Importation des données de la table « %1 » réussie. @@ -415,39 +415,39 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma No columns provided by the import plugin. - Aucune colonne fournie par le plugin d'importation. + Aucune colonne fournie par le plugin d’importation. Could not start transaction in order to import a data: %1 - Impossible d'initialiser la transaction d'import de données: %1 + Impossible d’initialiser la transaction d’import de données: %1 Could not commit transaction for imported data: %1 - Impossible d'enregistrer la transaction d'import de données: %1 + Impossible d’enregistrer la transaction d’import de données: %1 Table '%1' has less columns than there are columns in the data to be imported. Excessive data columns will be ignored. - La table %1 a moins de colonnes que de données à importer. Les colonnes supplèmentaires seront ignorées. + La table « %1 » a moins de colonnes que de données à importer. Les colonnes supplèmentaires seront ignorées. Table '%1' has more columns than there are columns in the data to be imported. Some columns in the table will be left empty. - La table %1 a plus de colonnes que de colonnes de données à importer. Certaines colonnes de la table seront vides. + La table « %1 » a plus de colonnes que de colonnes de données à importer. Certaines colonnes de la table seront vides. Could not create table to import to: %1 - Impossible de créer la table d'import: %1 + Impossible de créer la table d’import: %1 Error while importing data: %1 - Erreur lors de l'import des données: %1 + Erreur lors de l’import des données: %1 @@ -472,12 +472,12 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma Cannot load plugin %1, because its dependency was not loaded: %2. - Chargement impossible du plugin %1, les dépendances n'ont pa été chargées: %2. + Chargement impossible du plugin %1, les dépendances n’ont pa été chargées: %2. Cannot load plugin %1. Error details: %2 - Chargement impossible du plugin %1, Détails de l'erreur: %2 + Chargement impossible du plugin %1, Détails de l’erreur: %2 @@ -553,7 +553,7 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma Method of using words - Méthode d'utilisation des mots + Méthode d’utilisation des mots @@ -571,7 +571,7 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma Table '%1' populated successfully. - Table '%1' remplie avec succès. + Table « %1 » remplie avec succès. @@ -704,7 +704,7 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma Initialization code (optional) - Code d'initialisation (optionel) + Code d’initialisation (optionel) @@ -748,7 +748,7 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma Could not start transaction in order to perform table populating. Error details: %1 - Impossible d'initialiser la transaction pour remplir la table.Détails de l'erreur %1 + Impossible d’initialiser la transaction pour remplir la table.Détails de l’erreur %1 @@ -758,7 +758,7 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma Could not commit transaction after table populating. Error details: %1 - Impossible d'enregistrer la transaction après le remplissage de la table. Erreur %1 + Impossible d’enregistrer la transaction après le remplissage de la table. Erreur %1 @@ -767,7 +767,7 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma Could not open database: %1 - Impossible d'ouvrir la base de données: %1 + Impossible d’ouvrir la base de données: %1 @@ -789,18 +789,18 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma SQLite %1 does not support '%2' statement. - SQLite %1 ne supporte pas l'instruction '%2'. + SQLite %1 ne supporte pas l’instruction « %2 ». SQLite %1 does not support '%2' statement, but the regular table can be created instead if you proceed. - SQLite %1 ne supporte pas l'instruction '%2', mais la table normale peut être créée à la place si vous confirmez. + SQLite %1 ne supporte pas l’instruction « %2 », mais la table normale peut être créée à la place si vous confirmez. Could not parse statement: %1 Error details: %2 - Impossible d'analyser l'instruction: %1 + Impossible d’analyser l’instruction: %1 Détails erreur: %2 @@ -809,29 +809,29 @@ Détails erreur: %2 SQLite %1 does not support the '%2' clause. Cannot convert '%3' statement with that clause. - SQLite %1 ne supporte pas la clause '%2'. Impossible de convertir l'instruction '%3' avec cette clause. + SQLite %1 ne supporte pas la clause « %2 ». Impossible de convertir l’instruction « %3 » avec cette clause. SQLite %1 does not support the '%2' clause in the '%3' statement. - SQLite %1 ne supporte pas la clause '%2' de l'instruction '%3'. + SQLite %1 ne supporte pas la clause « %2 » de l’instruction « %3 ». SQLite %1 does not support current date or time clauses in expressions. - SQLite %1 ne supporte pas la clause date ou l'heure actuelle dans l'expression. + SQLite %1 ne supporte pas la clause date ou l’heure actuelle dans l’expression. SQLite %1 does not support '%2' clause in expressions. - SQLite %1 ne supporte pas la clause '%2' dans l'expression. + SQLite %1 ne supporte pas la clause « %2 » dans l’expression. Could not attach database %1: %2 - Impossible d'attacher la base de données %1: %2 + Impossible d’attacher la base de données %1: %2 @@ -849,12 +849,12 @@ Détails erreur: %2 Syntax error - Erreur de syntaxe + Erreur de syntaxe Could not open dictionary file %1 for reading. - Impossible d'ouvrir en lecture le fichier dictionnaire %1. + Impossible d’ouvrir en lecture le fichier dictionnaire %1. @@ -884,22 +884,22 @@ Détails erreur: %2 Error while executing populating initial code: %1 - Erreur à l'initialisation du code de remplissage: %1 + Erreur à l’initialisation du code de remplissage: %1 Error while executing populating code: %1 - Erreur à l'exécution du code de remplissage: %1 + Erreur à l’exécution du code de remplissage: %1 Select implementation language. - Sélectionnez l'application langage. + Sélectionnez l’application langage. Implementation code cannot be empty. - L'application de code ne peut être vide. + L’application de code ne peut être vide. @@ -909,7 +909,9 @@ Détails erreur: %2 Could not initialize configuration file. Any configuration changes and queries history will be lost after application restart. Tried to initialize the file at following localizations: %1. - Impossible d'initialiser le fichier de configuration. Aucune modification et les requêtes seront perdues après redémarrage. Essayez d'initialiser le fichier avec cette localisation: %1. + Impossible d’initialiser le fichier de configuration. + Aucune modification et les requêtes seront perdues après redémarrage. + Essayez d’initialiser le fichier avec cette localisation: %1. @@ -956,12 +958,12 @@ Détails erreur: %2 Table %1 is referencing table %2, but the foreign key definition will not be updated for new table definition due to problems while parsing DDL of the table %3. - La table %1 référence la table %2, mais la clé étrangère ne pourra être mise à jour pour la nouvelle table à cause de problèmes lors de l'analyse DDL de la table %3. + La table %1 référence la table %2, mais la clé étrangère ne pourra être mise à jour pour la nouvelle table à cause de problèmes lors de l’analyse DDL de la table %3. All columns indexed by the index %1 are gone. The index will not be recreated after table modification. - Toutes les colonnes indéxées par l'indexe %1 sont faites. L'indexe ne sera pas recréé après la modification de la table. + Toutes les colonnes indéxées par l’indexe %1 sont faites. L’indexe ne sera pas recréé après la modification de la table. @@ -994,22 +996,22 @@ La vue restera telque. There is a problem with updating an %1 statement within %2 trigger. One of the SELECT substatements which might be referring to table %3 cannot be properly modified. Manual update of the trigger may be necessary. - Il y a un problème à la mise à jour l'instruction %1 avec le déclencheur %2. Une partie de l'instruction SELECT référençant la table %3 ne ppermet pas sa modification. La mise à jour manuelle du déclencheur est nécessaire. + Il y a un problème à la mise à jour l’instruction %1 avec le déclencheur %2. Une partie de l’instruction SELECT référençant la table %3 ne ppermet pas sa modification. La mise à jour manuelle du déclencheur est nécessaire. Could not parse DDL of the view to be created. Details: %1 - Impossible d'analyser le DDL de création de vue. Détails: %1 + Impossible d’analyser le DDL de création de vue. Détails: %1 Parsed query is not CREATE VIEW. It's: %1 - L'expression CREATE VIEW est fausse. C'est: %1 + L’expression CREATE VIEW est fausse. C’est: %1 SQLiteStudio was unable to resolve columns returned by the new view, therefore it won't be able to tell which triggers might fail during the recreation process. - SQLiteStudio ne peut résoudre les colonnes résultant de la nouvelle vue, d'où le déclencheur en cause ne pourra être indiqué pendant le process. + SQLiteStudio ne peut résoudre les colonnes résultant de la nouvelle vue, d’où le déclencheur en cause ne pourra être indiqué pendant le process. @@ -1022,7 +1024,7 @@ La vue restera telque. Database is not open. - La base de données n'est ouverte. + La base de données n’est ouverte. @@ -1033,12 +1035,12 @@ La vue restera telque. An error occured while executing the count(*) query, thus data paging will be disabled. Error details from the database: %1 - Une erreur s'est produite à l'exécution de la requête count(*), la recherche des données est arrêtée. Erreur de la base de données:%1 + Une erreur s’est produite à l’exécution de la requête count(*), la recherche des données est arrêtée. Erreur de la base de données:%1 SQLiteStudio was unable to extract metadata from the query. Results won't be editable. - SQLiteStudio ne peut extraire des métadonnées d'une requête. Les résultats ne peut être affichés. + SQLiteStudio ne peut extraire des métadonnées d’une requête. Les résultats ne peut être affichés. @@ -1066,7 +1068,7 @@ La vue restera telque. Execution date sql history header - Date d'exécution + Date d’exécution @@ -1098,7 +1100,7 @@ La vue restera telque. Could not check available updates, because server responded with invalid message format. It is safe to ignore this warning. - Impossible de vérifier la mise à jour, car le serveur a répondu avec un message invalide. Il est possible d'ignorer le warning. + Impossible de vérifier la mise à jour, car le serveur a répondu avec un message invalide. Il est possible d’ignorer le warning. @@ -1108,7 +1110,7 @@ La vue restera telque. Could not download updates, because server responded with invalid message format. You can try again later or download and install updates manually. See <a href="%1">User Manual</a> for details. - Impossibles de télécharger les mises à jour, car le serveur répond avec un format de message invalide. Vous pover essayer plus tard ou télécharger et mettre à jour manuellement. Voir <a href="%1">User Manual</a> for details. + Impossibles de télécharger les mises à jour, car le serveur répond avec un format de message invalide. Vous pover essayer plus tard ou télécharger et mettre à jour manuellement. Voir <a href="%1">User Manual</a> for details. @@ -1118,7 +1120,7 @@ La vue restera telque. There was no updates to download. Updating aborted. - Il n'y a aucune mise à jour à télécharger. Mise à jour abandonnée. + Il n’y a aucune mise à jour à télécharger. Mise à jour abandonnée. @@ -1133,7 +1135,7 @@ La vue restera telque. Failed to open file '%1' for writting: %2. Updating aborted. - Erreur à l'ouverture du fichier %1 pour l'écriture: %2. Mise à jour abandonnée. + Erreur à l’ouverture du fichier « %1 » pour l’écriture: %2. Mise à jour abandonnée. @@ -1143,7 +1145,7 @@ La vue restera telque. Could not copy current application directory into %1 directory. - Impossible de copier le répertoire de l'application courante dans %1. + Impossible de copier le répertoire de l’application courante dans %1. @@ -1165,7 +1167,7 @@ Details: %3 Could not move directory %1 to %2 and also failed to restore original directory, so the original SQLiteStudio directory is now located at: %3 - Impossible de déplacer le répertoire %1 vers %2 d'où l'impossibilité de restaurer le répertoire original. SQLiteStudio est maintenant localisé: %3 + Impossible de déplacer le répertoire %1 vers %2 d’où l’impossibilité de restaurer le répertoire original. SQLiteStudio est maintenant localisé: %3 @@ -1175,12 +1177,12 @@ Details: %3 Could not unpack component %1 into %2 directory. - Impossible d'extraire le composant %1 dans le répertoire %2. + Impossible d’extraire le composant %1 dans le répertoire %2. Could not find permissions elevator application to run update as a root. Looked for: %1 - Impossible d'élever les autorisations pour lancer la mise à jour en tantque root. Bloqué: %1 + Impossible d’élever les autorisations pour lancer la mise à jour en tantque root. Bloqué: %1 @@ -1213,17 +1215,17 @@ Details: %3 Could not execute final updating steps as administrator. - Impossible de finaliser la mis à jour en tant qu'administrateur. + Impossible de finaliser la mis à jour en tant qu’administrateur. Could not execute final updating steps as administrator. Updater startup timed out. - Impossible de finaliser la mis à jour en tant qu'administrateur. Délai d'attente de lancement dépassé. + Impossible de finaliser la mis à jour en tant qu’administrateur. Délai d’attente de lancement dépassé. Could not execute final updating steps as administrator. Updater operation timed out. - Impossible de finaliser la mis à jour en tant qu'administrateur. Délai d'attente d'opération dépassé. + Impossible de finaliser la mis à jour en tant qu’administrateur. Délai d’attente d’opération dépassé. @@ -1238,7 +1240,7 @@ Details: %3 Package not in tar.gz format, cannot install: %1 - Installation impossible un paquet n'est pas au format tar.zg: %1 + Installation impossible un paquet n’est pas au format tar.zg: %1 @@ -1280,8 +1282,8 @@ Details: %3 Error executing update command: %1 Error message: %2 - Erreur d'exécution de la commande de mise à jour: %1 -Message d'erreur: %2 + Erreur d’exécution de la commande de mise à jour: %1 +Message d’erreur: %2 diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_it.qm b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_it.qm new file mode 100644 index 0000000..9dad8df Binary files /dev/null and b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_it.qm differ diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_it.ts b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_it.ts index 27d4349..9b031de 100644 --- a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_it.ts +++ b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_it.ts @@ -1,6 +1,6 @@ - + AbstractDb @@ -38,19 +38,25 @@ - + + Could not disable foreign keys in the database. Details: %1 + chain executor + + + + Could not start a database transaction. Details: %1 chain executor - + Interrupted chain executor - + Could not commit a database transaction. Details: %1 chain executor @@ -152,25 +158,25 @@ - - + + Database file doesn't exist. - - - + + + No supporting plugin loaded. - + Database could not be initialized. - + No suitable database driver plugin found. @@ -226,21 +232,28 @@ Tables, indexes, triggers and views copied to database %3 will remain. Error while creating trigger in target database: %1 + + + + + Could not parse object '%1' in order to move or copy it. + + DbVersionConverter - + Target file exists, but could not be overwritten. - + Could not find proper database plugin to create target database. - + Error while converting database: %1 @@ -318,33 +331,33 @@ Tables, indexes, triggers and views copied to database %3 will remain. ExportWorker - + Error while exporting query results: %1 - + Error while counting data column width to export from query results: %1 - - + + Could not parse %1 in order to export it. It will be excluded from the export output. - + Error while reading data to export from table %1: %2 - + Error while counting data to export from table %1: %2 - + Error while counting data column width to export from table %1: %2 @@ -443,20 +456,20 @@ Tables, indexes, triggers and views copied to database %3 will remain. - - + + Error while importing data: %1 - + Interrupted. import process status update - + Could not import data row number %1. The row was ignored. Problem details: %2 @@ -484,13 +497,13 @@ Tables, indexes, triggers and views copied to database %3 will remain. - + min: %1 plugin dependency version - + max: %1 plugin dependency version @@ -827,7 +840,7 @@ Error details: %2 - + Could not attach database %1: %2 @@ -839,13 +852,13 @@ Error details: %2 - + Parser stack overflow - + Syntax error @@ -900,10 +913,15 @@ Error details: %2 - + Could not resolve data source for column: %1 + + + Could not resolve table for column '%1'. + + Could not initialize configuration file. Any configuration changes and queries history will be lost after application restart. Tried to initialize the file at following localizations: %1. @@ -952,40 +970,40 @@ Error details: %2 - + Table %1 is referencing table %2, but the foreign key definition will not be updated for new table definition due to problems while parsing DDL of the table %3. - + All columns indexed by the index %1 are gone. The index will not be recreated after table modification. - + There is problem with proper processing trigger %1. It may be not fully updated afterwards and will need your attention. - + All columns covered by the trigger %1 are gone. The trigger will not be recreated after table modification. - + Cannot not update trigger %1 according to table %2 modification. - + Cannot not update view %1 according to table %2 modifications. The view will remain as it is. - - - + + + There is a problem with updating an %1 statement within %2 trigger. One of the %1 substatements which might be referring to table %3 cannot be properly modified. Manual update of the trigger may be necessary. @@ -1008,28 +1026,28 @@ The view will remain as it is. QueryExecutor - + Execution interrupted. - + Database is not open. - + Only one query can be executed simultaneously. - - + + An error occured while executing the count(*) query, thus data paging will be disabled. Error details from the database: %1 - + SQLiteStudio was unable to extract metadata from the query. Results won't be editable. diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_pl.ts b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_pl.ts index a89ea4d..c3e000c 100644 --- a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_pl.ts +++ b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_pl.ts @@ -38,19 +38,25 @@ Baza danych do wykonywania zapytań nie jest otwarta. - + + Could not disable foreign keys in the database. Details: %1 + chain executor + Nie udało się wyłączyć kluczy obcych w bazie. Szczegóły: %1 + + + Could not start a database transaction. Details: %1 chain executor Nie udało się rozpocząć transakcji bazy danych. Szczegóły: %1 - + Interrupted chain executor Przerwane - + Could not commit a database transaction. Details: %1 chain executor Nie udało się zatwierdzić transakcji bazy danych. Szczegóły: %1 @@ -152,25 +158,25 @@ Nie udało się zaktualizować baza danych %1 z powodu błędu: %2 - - + + Database file doesn't exist. Plik bazy danych nie istnieje. - - - + + + No supporting plugin loaded. Nie załadowano obsługującej wtyczki. - + Database could not be initialized. Nie udało się zainicjalizować bazy danych. - + No suitable database driver plugin found. Nie znaleziono odpowiedniej wtyczki sterownika. @@ -227,21 +233,28 @@ Tabele, indeksy, wyzwalacze i widoki skopiowane do bazy danych %3 pozostaną na Error while creating trigger in target database: %1 Błąd podczas tworzenia wyzwalacza w docelowej bazie danych: %1 + + + + + Could not parse object '%1' in order to move or copy it. + Nie można zanalizować obiektu '%1' w celu przeniesienia lub skopiowania go. + DbVersionConverter - + Target file exists, but could not be overwritten. Plik docelowy istnieje, ale nie może być nadpisany. - + Could not find proper database plugin to create target database. Nie znaleziono odpowiedniej wtyczki bazy danych, aby utworzyć docelową bazę danych. - + Error while converting database: %1 Błąd podczas konwersji bazy danych: %1 @@ -323,7 +336,7 @@ Tabele, indeksy, wyzwalacze i widoki skopiowane do bazy danych %3 pozostaną na ExportWorker - + Error while exporting query results: %1 Błąd podczas eksportowania wyników zapytania: %1 @@ -332,28 +345,28 @@ Tabele, indeksy, wyzwalacze i widoki skopiowane do bazy danych %3 pozostaną na Błąd podczas liczenia szerokości kolumn danych do eksportu wyników zapytania: %2 - + Error while counting data column width to export from query results: %1 Błąd podczas liczenia szerokości kolumn danych do eksportu wyników zapytania: %1 - - + + Could not parse %1 in order to export it. It will be excluded from the export output. Nie udało się przeanalizować %1 w celu wyeksportowania. Element ten zostanie pominięty w wynikach eksportu. - + Error while reading data to export from table %1: %2 Błąd podczas odczytu danych do eksportu z tabeli %1: %2 - + Error while counting data to export from table %1: %2 Błąd podczas liczenia danych do eksportu z tabeli %1: %2 - + Error while counting data column width to export from table %1: %2 Błąd podczas obliczania szerokości kolumn danych do eksportu z tabeli %1: %2 @@ -452,20 +465,20 @@ Tabele, indeksy, wyzwalacze i widoki skopiowane do bazy danych %3 pozostaną na - - + + Error while importing data: %1 Błąd podczas importowania danych: %1 - + Interrupted. import process status update Przerwano. - + Could not import data row number %1. The row was ignored. Problem details: %2 Nie udało się zaimportować wiersza danych numer %1. Wiersz ten został zignorowany. Szczegóły problemu: %2 @@ -493,13 +506,13 @@ Tabele, indeksy, wyzwalacze i widoki skopiowane do bazy danych %3 pozostaną na Nie udało się załadować wtyczki %1 (błąd podczas inicjalizacji wtyczki). - + min: %1 plugin dependency version min: %1 - + max: %1 plugin dependency version maks: %1 @@ -824,7 +837,7 @@ Szczegóły błędu: %2 SQLite %1 nie obsługuje klauzuli '%2' w wyrażeniach. - + Could not attach database %1: %2 Nie udało się dołączyć bazy danych %1: %2 @@ -836,13 +849,13 @@ Szczegóły błędu: %2 - + Parser stack overflow Przeciążenie stosu analizatora. - - + + Syntax error Błąd składni @@ -897,12 +910,17 @@ Szczegóły błędu: %2 Kod implementacji nie może być pusty. - + Could not resolve data source for column: %1 Nie znaleziono źródła danych dla kolumny: %1 - + + Could not resolve table for column '%1'. + Nie można ustalić tabeli lub kolumny '%1'. + + + Could not initialize configuration file. Any configuration changes and queries history will be lost after application restart. Tried to initialize the file at following localizations: %1. Nie udało się zainicjalizować pliku konfiguracyjnego. Jakiekolwiek zmiany w konfiguracji i historia zapytań będą utracone po zrestartowaniu aplikacji. Próbowano zainicjalizować plik konfiguracyjny w następujących lokalizacjach: %1. @@ -949,39 +967,39 @@ Szczegóły błędu: %2 Zaludnianie tabel - + Table %1 is referencing table %2, but the foreign key definition will not be updated for new table definition due to problems while parsing DDL of the table %3. Tabela %1 odwołuje się do tabeli %2, ale definicja klucza obcego nie zostanie zaktualizowane dla definicji nowej tabeli w związku z problemami przy analizowaniu DDL tabeli %3. - + All columns indexed by the index %1 are gone. The index will not be recreated after table modification. Wszystkie kolumny indeksowane przez indeks %1 już nie istnieją. Indeks ten nie będzie odtworzony po modyfikacji tabeli. - + There is problem with proper processing trigger %1. It may be not fully updated afterwards and will need your attention. Wystąpił problem z poprawnym przetworzeniem wyzwalacza %1. Może on zostać zaktualizowany tylko częściowo i będzie wymagał twojej uwagi. - + Cannot not update trigger %1 according to table %2 modification. Nie można zaktualizować wyzwalacza %1 zgodnie z modyfikacjami tabeli %2. - - - + + + There is a problem with updating an %1 statement within %2 trigger. One of the %1 substatements which might be referring to table %3 cannot be properly modified. Manual update of the trigger may be necessary. Jest problem ze zaktualizowaniem zapytania %1 w wyzwalaczu %2. Jedeno z podzapytań %1, które może odwoływać się do tabeli %3 nie może być poprawnie zmodyfikowane. Ręczna aktualizacja tego wyzwalacza może być niezbędna. - + All columns covered by the trigger %1 are gone. The trigger will not be recreated after table modification. Wszystkie kolumny obsługiwane przez wyzwalacz %1 już nie istnieją. Wyzwalacz ten nie będzie odtworzony po modyfikacji tabeli. - + Cannot not update view %1 according to table %2 modifications. The view will remain as it is. Nie można zaktualizować widoku %1 w związku z modyfikacjami tabeli %2. @@ -1018,7 +1036,7 @@ Widok pozostanie nienaruszony. Nie udało się zamknąć bazy danych: %1 - + Result set expired or no row available. Wyniki zapytania są nieaktualne, lub nie ma dostępnych wierszy. @@ -1034,28 +1052,28 @@ Widok pozostanie nienaruszony. QueryExecutor - + Execution interrupted. Wykonywanie przerwane. - + Database is not open. Baza danych nie jest otwarta. - + Only one query can be executed simultaneously. Tylko jedno zapytanie może być wykonywane w danym momencie. - - + + An error occured while executing the count(*) query, thus data paging will be disabled. Error details from the database: %1 Wystąpił błąd podczas wykonywania zapytania count(*), przez co stronicowanie danych będzie wyłączone. Szczegóły błędy z bazy danych: %1 - + SQLiteStudio was unable to extract metadata from the query. Results won't be editable. SQLiteStudio nie mogło uzyskać metadanych z zapytania. Nie będzie można edytować wyników zapytania. diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_pt_BR.ts b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_pt_BR.ts index bb040e6..8637f5e 100644 --- a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_pt_BR.ts +++ b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_pt_BR.ts @@ -1,6 +1,6 @@ - + AbstractDb @@ -38,19 +38,25 @@ - + + Could not disable foreign keys in the database. Details: %1 + chain executor + + + + Could not start a database transaction. Details: %1 chain executor - + Interrupted chain executor - + Could not commit a database transaction. Details: %1 chain executor @@ -152,25 +158,25 @@ - - + + Database file doesn't exist. - - - + + + No supporting plugin loaded. - + Database could not be initialized. - + No suitable database driver plugin found. @@ -226,21 +232,28 @@ Tables, indexes, triggers and views copied to database %3 will remain. Error while creating trigger in target database: %1 + + + + + Could not parse object '%1' in order to move or copy it. + + DbVersionConverter - + Target file exists, but could not be overwritten. - + Could not find proper database plugin to create target database. - + Error while converting database: %1 @@ -318,33 +331,33 @@ Tables, indexes, triggers and views copied to database %3 will remain. ExportWorker - + Error while exporting query results: %1 - + Error while counting data column width to export from query results: %1 - - + + Could not parse %1 in order to export it. It will be excluded from the export output. - + Error while reading data to export from table %1: %2 - + Error while counting data to export from table %1: %2 - + Error while counting data column width to export from table %1: %2 @@ -443,20 +456,20 @@ Tables, indexes, triggers and views copied to database %3 will remain. - - + + Error while importing data: %1 - + Interrupted. import process status update - + Could not import data row number %1. The row was ignored. Problem details: %2 @@ -484,13 +497,13 @@ Tables, indexes, triggers and views copied to database %3 will remain. - + min: %1 plugin dependency version - + max: %1 plugin dependency version @@ -827,7 +840,7 @@ Error details: %2 - + Could not attach database %1: %2 @@ -839,13 +852,13 @@ Error details: %2 - + Parser stack overflow - + Syntax error @@ -900,10 +913,15 @@ Error details: %2 - + Could not resolve data source for column: %1 + + + Could not resolve table for column '%1'. + + Could not initialize configuration file. Any configuration changes and queries history will be lost after application restart. Tried to initialize the file at following localizations: %1. @@ -952,39 +970,39 @@ Error details: %2 - + Table %1 is referencing table %2, but the foreign key definition will not be updated for new table definition due to problems while parsing DDL of the table %3. - + All columns indexed by the index %1 are gone. The index will not be recreated after table modification. - + There is problem with proper processing trigger %1. It may be not fully updated afterwards and will need your attention. - + Cannot not update trigger %1 according to table %2 modification. - - - + + + There is a problem with updating an %1 statement within %2 trigger. One of the %1 substatements which might be referring to table %3 cannot be properly modified. Manual update of the trigger may be necessary. - + All columns covered by the trigger %1 are gone. The trigger will not be recreated after table modification. - + Cannot not update view %1 according to table %2 modifications. The view will remain as it is. @@ -1008,28 +1026,28 @@ The view will remain as it is. QueryExecutor - + Execution interrupted. - + Database is not open. - + Only one query can be executed simultaneously. - - + + An error occured while executing the count(*) query, thus data paging will be disabled. Error details from the database: %1 - + SQLiteStudio was unable to extract metadata from the query. Results won't be editable. diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_ru.ts b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_ru.ts index 83ba986..7e8bb9d 100644 --- a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_ru.ts +++ b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_ru.ts @@ -1,6 +1,6 @@ - + AbstractDb @@ -38,19 +38,25 @@ Не открыта база данных для выполнения запросов. - + + Could not disable foreign keys in the database. Details: %1 + chain executor + + + + Could not start a database transaction. Details: %1 chain executor Невозможно начать транзакцию. Подробности: %1 - + Interrupted chain executor Прервано - + Could not commit a database transaction. Details: %1 chain executor Невозможно завершить транзакцию. Подробности: %1 @@ -152,26 +158,26 @@ Невозможно обновить базу данных %1 из-за ошибки: %2 - - + + Database file doesn't exist. Файл базы данных не существует. - - - + + + No supporting plugin loaded. Unclear error string. Checking the source didn't help. Модуль поддержки не загружен. - + Database could not be initialized. Невозможно инициализировать базу данных. - + No suitable database driver plugin found. Не найден подходящий драйвер базы данных. @@ -228,21 +234,28 @@ Tables, indexes, triggers and views copied to database %3 will remain. Error while creating trigger in target database: %1 Ошибка при создании триггера в целевой базе данных: %1 + + + + + Could not parse object '%1' in order to move or copy it. + + DbVersionConverter - + Target file exists, but could not be overwritten. Целевой файл существует, но не может быть перезаписан. - + Could not find proper database plugin to create target database. Невозможно найти подходящий модуль для создания целевой базы данных. - + Error while converting database: %1 Ошибка при конвертации базы данных: %1 @@ -320,33 +333,33 @@ Tables, indexes, triggers and views copied to database %3 will remain. ExportWorker - + Error while exporting query results: %1 Ошибка при экспорте результатов запроса: %1 - + Error while counting data column width to export from query results: %1 Ошибка при подсчёте ширины столбца данных для экспорта результатов запроса: %1 - - + + Could not parse %1 in order to export it. It will be excluded from the export output. Невозможно проанализировать структуру %1. Данный объект будет исключён при выполнении экспорта. - + Error while reading data to export from table %1: %2 Ошибка при считывании данных для экспорта из таблицы %1: %2 - + Error while counting data to export from table %1: %2 Ошибка при подсчёте количества данных для экспорта из таблицы %1: %2 - + Error while counting data column width to export from table %1: %2 Ошибка при подсчёте ширины столбца данных для экспорта из таблицы %1: %2 @@ -445,20 +458,20 @@ Tables, indexes, triggers and views copied to database %3 will remain. - - + + Error while importing data: %1 Ошибка при импорте данных: %1 - + Interrupted. import process status update Прервано. - + Could not import data row number %1. The row was ignored. Problem details: %2 Невозможно импортировать строку данных № %1. Строка пропущена. Подробности проблемы: %2 @@ -486,13 +499,13 @@ Tables, indexes, triggers and views copied to database %3 will remain. Невозможно загрузить модуль %1 (ошибка при инициализации модуля). - + min: %1 plugin dependency version минимальная: %1 - + max: %1 plugin dependency version максимальная: %1 @@ -829,7 +842,7 @@ Error details: %2 SQLite %1 не поддерживает оператор '%2' в выражениях. - + Could not attach database %1: %2 Не удалось присоединить базу данных %1: %2 @@ -841,13 +854,13 @@ Error details: %2 - + Parser stack overflow Переполнение стека анализатора - + Syntax error Синтаксическая ошибка @@ -902,10 +915,15 @@ Error details: %2 Заполняющий код не может быть пустым. - + Could not resolve data source for column: %1 Невозможно определить источник данных для столбца: %1 + + + Could not resolve table for column '%1'. + + Could not initialize configuration file. Any configuration changes and queries history will be lost after application restart. Tried to initialize the file at following localizations: %1. @@ -954,39 +972,39 @@ Error details: %2 Заполнение таблиц - + Table %1 is referencing table %2, but the foreign key definition will not be updated for new table definition due to problems while parsing DDL of the table %3. Таблица %1 ссылается на таблицу %2, но описание внешнего ключа не будет обновлено для описания новой таблицы из-за проблем с анализом DDL таблицы %3. - + All columns indexed by the index %1 are gone. The index will not be recreated after table modification. Все столбцы, проиндексированные индексом %1, удалены. Индекс не будет воссоздан после модификации таблицы. - + There is problem with proper processing trigger %1. It may be not fully updated afterwards and will need your attention. Возникла проблема при обработке триггера %1. Впоследствии он не будет полностью обновлён и потребует вашего внимания. - + Cannot not update trigger %1 according to table %2 modification. Невозможно обновить триггер %1 в соответствии с модификацией таблицы %2. - - - + + + There is a problem with updating an %1 statement within %2 trigger. One of the %1 substatements which might be referring to table %3 cannot be properly modified. Manual update of the trigger may be necessary. Возникла проблема при обновлении конструкции %1 внутри триггера %2. Одна из вложенных конструкций %1, которая возможно ссылается на таблицу %3, не может быть корректно модифицирована. Возможно необходима ручная правка триггера. - + All columns covered by the trigger %1 are gone. The trigger will not be recreated after table modification. Все столбцы, затронутые в триггере %1, удалены. Триггер не будет воссоздан после модификации таблицы. - + Cannot not update view %1 according to table %2 modifications. The view will remain as it is. Невозможно обновить представление %1 в соответствии с модификациями таблицы %2. @@ -1015,28 +1033,28 @@ The view will remain as it is. QueryExecutor - + Execution interrupted. Выполнение прервано. - + Database is not open. База данных не открыта. - + Only one query can be executed simultaneously. Одновременно может быть выполнен только один запрос. - - + + An error occured while executing the count(*) query, thus data paging will be disabled. Error details from the database: %1 Возникла ошибка при выполнении запроса count(*), поэтому разбивка данных по страницам отключена. Детали ошибки из базы данных: %1 - + SQLiteStudio was unable to extract metadata from the query. Results won't be editable. SQLiteStudio не удалось извлечь метаданные из запроса. Результаты нельзя будет редактировать. diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_sk.qm b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_sk.qm index 6dae38a..eb79951 100644 Binary files a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_sk.qm and b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_sk.qm differ diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_sk.ts b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_sk.ts index 1c29a80..4a617e4 100644 --- a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_sk.ts +++ b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_sk.ts @@ -38,19 +38,25 @@ - + + Could not disable foreign keys in the database. Details: %1 + chain executor + + + + Could not start a database transaction. Details: %1 chain executor - + Interrupted chain executor - + Could not commit a database transaction. Details: %1 chain executor @@ -152,25 +158,25 @@ Databáza %1 nemôže byť aktualizovaná kvôli chybe: %2 - - + + Database file doesn't exist. Databázový súbor neexistuje. - - - + + + No supporting plugin loaded. - + Database could not be initialized. - + No suitable database driver plugin found. @@ -226,21 +232,28 @@ Tables, indexes, triggers and views copied to database %3 will remain. Error while creating trigger in target database: %1 + + + + + Could not parse object '%1' in order to move or copy it. + + DbVersionConverter - + Target file exists, but could not be overwritten. Cieľový súbor existuje ale nemôže byť prepísaný. - + Could not find proper database plugin to create target database. Nieje možné nájsť správny databázový plugin pre vytvorenie cieľovej databázy. - + Error while converting database: %1 Vyskytla sa chyba počas konvertovania databázy: %1 @@ -318,33 +331,33 @@ Tables, indexes, triggers and views copied to database %3 will remain. ExportWorker - + Error while exporting query results: %1 - + Error while counting data column width to export from query results: %1 - - + + Could not parse %1 in order to export it. It will be excluded from the export output. - + Error while reading data to export from table %1: %2 - + Error while counting data to export from table %1: %2 - + Error while counting data column width to export from table %1: %2 @@ -443,20 +456,20 @@ Tables, indexes, triggers and views copied to database %3 will remain. - - + + Error while importing data: %1 Vyskytla sa chyba počas importu dát: %1 - + Interrupted. import process status update - + Could not import data row number %1. The row was ignored. Problem details: %2 @@ -484,13 +497,13 @@ Tables, indexes, triggers and views copied to database %3 will remain. Nemôžem načítať plugin %1 (nastala chyba pri jeho inicializácii). - + min: %1 plugin dependency version - + max: %1 plugin dependency version @@ -827,7 +840,7 @@ Error details: %2 - + Could not attach database %1: %2 @@ -839,13 +852,13 @@ Error details: %2 - + Parser stack overflow - + Syntax error Chyba syntaxe @@ -900,10 +913,15 @@ Error details: %2 - + Could not resolve data source for column: %1 + + + Could not resolve table for column '%1'. + + Could not initialize configuration file. Any configuration changes and queries history will be lost after application restart. Tried to initialize the file at following localizations: %1. @@ -952,39 +970,39 @@ Error details: %2 - + Table %1 is referencing table %2, but the foreign key definition will not be updated for new table definition due to problems while parsing DDL of the table %3. - + All columns indexed by the index %1 are gone. The index will not be recreated after table modification. - + There is problem with proper processing trigger %1. It may be not fully updated afterwards and will need your attention. - + Cannot not update trigger %1 according to table %2 modification. - - - + + + There is a problem with updating an %1 statement within %2 trigger. One of the %1 substatements which might be referring to table %3 cannot be properly modified. Manual update of the trigger may be necessary. - + All columns covered by the trigger %1 are gone. The trigger will not be recreated after table modification. - + Cannot not update view %1 according to table %2 modifications. The view will remain as it is. @@ -1008,28 +1026,28 @@ The view will remain as it is. QueryExecutor - + Execution interrupted. - + Database is not open. - + Only one query can be executed simultaneously. - - + + An error occured while executing the count(*) query, thus data paging will be disabled. Error details from the database: %1 Vyskytla sa chyba počas vykonávania dotazu count(*), dôsledkom čoho bolo zablokované stránkovanie. Detail chyby: %1 - + SQLiteStudio was unable to extract metadata from the query. Results won't be editable. diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_zh_CN.qm b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_zh_CN.qm index be651ee..3c6eeb3 100644 Binary files a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_zh_CN.qm and b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_zh_CN.qm differ diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_zh_CN.ts b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_zh_CN.ts index 448558d..3410fa0 100644 --- a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_zh_CN.ts +++ b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_zh_CN.ts @@ -1,6 +1,6 @@ - + AbstractDb @@ -38,19 +38,25 @@ - + + Could not disable foreign keys in the database. Details: %1 + chain executor + + + + Could not start a database transaction. Details: %1 chain executor - + Interrupted chain executor - + Could not commit a database transaction. Details: %1 chain executor @@ -152,25 +158,25 @@ - - + + Database file doesn't exist. - - - + + + No supporting plugin loaded. - + Database could not be initialized. - + No suitable database driver plugin found. @@ -226,21 +232,28 @@ Tables, indexes, triggers and views copied to database %3 will remain. Error while creating trigger in target database: %1 + + + + + Could not parse object '%1' in order to move or copy it. + + DbVersionConverter - + Target file exists, but could not be overwritten. - + Could not find proper database plugin to create target database. - + Error while converting database: %1 @@ -318,33 +331,33 @@ Tables, indexes, triggers and views copied to database %3 will remain. ExportWorker - + Error while exporting query results: %1 - + Error while counting data column width to export from query results: %1 - - + + Could not parse %1 in order to export it. It will be excluded from the export output. - + Error while reading data to export from table %1: %2 - + Error while counting data to export from table %1: %2 - + Error while counting data column width to export from table %1: %2 @@ -443,20 +456,20 @@ Tables, indexes, triggers and views copied to database %3 will remain. - - + + Error while importing data: %1 - + Interrupted. import process status update - + Could not import data row number %1. The row was ignored. Problem details: %2 @@ -484,13 +497,13 @@ Tables, indexes, triggers and views copied to database %3 will remain. - + min: %1 plugin dependency version - + max: %1 plugin dependency version @@ -827,7 +840,7 @@ Error details: %2 - + Could not attach database %1: %2 @@ -839,13 +852,13 @@ Error details: %2 - + Parser stack overflow - + Syntax error @@ -900,10 +913,15 @@ Error details: %2 - + Could not resolve data source for column: %1 + + + Could not resolve table for column '%1'. + + Could not initialize configuration file. Any configuration changes and queries history will be lost after application restart. Tried to initialize the file at following localizations: %1. @@ -952,39 +970,39 @@ Error details: %2 - + Table %1 is referencing table %2, but the foreign key definition will not be updated for new table definition due to problems while parsing DDL of the table %3. - + All columns indexed by the index %1 are gone. The index will not be recreated after table modification. - + There is problem with proper processing trigger %1. It may be not fully updated afterwards and will need your attention. - + Cannot not update trigger %1 according to table %2 modification. - - - + + + There is a problem with updating an %1 statement within %2 trigger. One of the %1 substatements which might be referring to table %3 cannot be properly modified. Manual update of the trigger may be necessary. - + All columns covered by the trigger %1 are gone. The trigger will not be recreated after table modification. - + Cannot not update view %1 according to table %2 modifications. The view will remain as it is. @@ -1008,28 +1026,28 @@ The view will remain as it is. QueryExecutor - + Execution interrupted. - + Database is not open. - + Only one query can be executed simultaneously. - - + + An error occured while executing the count(*) query, thus data paging will be disabled. Error details from the database: %1 - + SQLiteStudio was unable to extract metadata from the query. Results won't be editable. diff --git a/SQLiteStudio3/create_macosx_bundle.sh b/SQLiteStudio3/create_macosx_bundle.sh index d3ce15b..51b563a 100755 --- a/SQLiteStudio3/create_macosx_bundle.sh +++ b/SQLiteStudio3/create_macosx_bundle.sh @@ -15,7 +15,7 @@ if [ "$#" -eq 3 ] && [ "$3" != "dmg" ] && [ "$3" != "dist" ] && [ "$3" != "dist_ fi qt_deploy_bin="${2/qmake/macdeployqt}" -$qt_deploy_bin -v >/dev/null 2>&1 +ls $qt_deploy_bin >/dev/null 2>&1 if [ "$?" -ne 0 ]; then echo "macdeployqt program missing!" exit 1 @@ -35,20 +35,37 @@ mv SQLiteStudio.app/Contents/plugins SQLiteStudio.app/Contents/PlugIns cp -RP lib*SQLiteStudio*.dylib SQLiteStudio.app/Contents/Frameworks +# CLI paths qtcore_path=`otool -L sqlitestudiocli | grep QtCore | awk '{print $1;}'` -new_qtcore_path="@loader_path/../Frameworks/QtCore.framework/Versions/5/QtCore" +new_qtcore_path="@rpath/QtCore.framework/Versions/5/QtCore" cp -P sqlitestudiocli SQLiteStudio.app/Contents/MacOS -install_name_tool -change libcoreSQLiteStudio.1.dylib "@loader_path/../Frameworks/libcoreSQLiteStudio.1.dylib" SQLiteStudio.app/Contents/MacOS/sqlitestudiocli +install_name_tool -change libcoreSQLiteStudio.1.dylib "@rpath/libcoreSQLiteStudio.1.dylib" SQLiteStudio.app/Contents/MacOS/sqlitestudiocli install_name_tool -change $qtcore_path $new_qtcore_path SQLiteStudio.app/Contents/MacOS/sqlitestudiocli +# SQLiteStudio binary paths +install_name_tool -change libcoreSQLiteStudio.1.dylib "@rpath/libcoreSQLiteStudio.1.dylib" SQLiteStudio.app/Contents/MacOS/SQLiteStudio +install_name_tool -change libguiSQLiteStudio.1.dylib "@rpath/libguiSQLiteStudio.1.dylib" SQLiteStudio.app/Contents/MacOS/SQLiteStudio + +# Lib paths +install_name_tool -change libcoreSQLiteStudio.1.dylib "@rpath/libcoreSQLiteStudio.1.dylib" SQLiteStudio.app/Contents/Frameworks/libguiSQLiteStudio.1.dylib + cp -RP ../../../lib/*.dylib SQLiteStudio.app/Contents/Frameworks +# Plugin paths +for f in `ls SQLiteStudio.app/Contents/PlugIns` +do + PLUGIN_FILE=SQLiteStudio.app/Contents/PlugIns/$f + install_name_tool -change libcoreSQLiteStudio.1.dylib "@rpath/libcoreSQLiteStudio.1.dylib" $PLUGIN_FILE + install_name_tool -change libguiSQLiteStudio.1.dylib "@rpath/libguiSQLiteStudio.1.dylib" $PLUGIN_FILE +done + + if [ "$3" == "dmg" ]; then $qt_deploy_bin SQLiteStudio.app -dmg elif [ "$3" == "dist" ] || [ "$3" == "dist_plugins" ] || [ "$3" == "dist_full" ]; then if [ "$3" == "dist" ] || [ "$3" == "dist_full" ]; then - $qt_deploy_bin SQLiteStudio.app -dmg + $qt_deploy_bin SQLiteStudio.app -dmg -executable=SQLiteStudio.app/Contents/MacOS/SQLiteStudio -always-overwrite -verbose=3 2> /tmp/log.txt cd $1/SQLiteStudio VERSION=`SQLiteStudio.app/Contents/MacOS/sqlitestudiocli -v | awk '{print $2}'` @@ -75,11 +92,12 @@ elif [ "$3" == "dist" ] || [ "$3" == "dist_plugins" ] || [ "$3" == "dist_full" ] # Plugins mkdir Contents Contents/PlugIns - SQLiteStudio.app/Contents/MacOS/sqlitestudio --list-plugins | while read line + SQLiteStudio.app/Contents/MacOS/SQLiteStudio --list-plugins | while read line do PLUGIN=`echo $line | awk '{print $1}'` PLUGIN_VER=`echo $line | awk '{print $2}'` - if [ -f SQLiteStudio.app/Contents/PlugIns/lib$PLUGIN.dylib ]; then + PLUGIN_FILE=SQLiteStudio.app/Contents/PlugIns/lib$PLUGIN.dylib + if [ -f $PLUGIN_FILE ]; then echo "Building plugin package: $PLUGIN-$PLUGIN_VER.tar.gz" cp SQLiteStudio.app/Contents/PlugIns/lib$PLUGIN.dylib Contents/PlugIns zip -r $PLUGIN\-$PLUGIN_VER.zip Contents @@ -91,3 +109,4 @@ elif [ "$3" == "dist" ] || [ "$3" == "dist_plugins" ] || [ "$3" == "dist_full" ] else $qt_deploy_bin SQLiteStudio.app fi + diff --git a/SQLiteStudio3/create_win32_portable.bat b/SQLiteStudio3/create_win32_portable.bat index 3dfa147..6d48245 100644 --- a/SQLiteStudio3/create_win32_portable.bat +++ b/SQLiteStudio3/create_win32_portable.bat @@ -1,6 +1,6 @@ @echo off -set QT_DIR=c:\Qt\5.4\mingw491_32\bin +set QT_DIR=C:\Qt\5.6\mingw49_32\bin set ZIP="c:\Program Files\7-Zip\7z.exe" set QMAKE=%QT_DIR%\qmake.exe diff --git a/SQLiteStudio3/guiSQLiteStudio/common/centerediconitemdelegate.cpp b/SQLiteStudio3/guiSQLiteStudio/common/centerediconitemdelegate.cpp new file mode 100644 index 0000000..83d8cc3 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/common/centerediconitemdelegate.cpp @@ -0,0 +1,35 @@ +#include "centerediconitemdelegate.h" +#include +#include + +CenteredIconItemDelegate::CenteredIconItemDelegate(QObject* parent) : + QStyledItemDelegate(parent) +{ +} + +void CenteredIconItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + if (!index.isValid()) + return; + + QStyleOptionViewItem opt = option; + initStyleOption(&opt, index); + + // disable default icon + opt.icon = QIcon(); + if (opt.features.testFlag(QStyleOptionViewItem::HasDecoration)) + opt.features ^= QStyleOptionViewItem::HasDecoration; + + // draw default item + QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &opt, painter, 0); + + const QRect r = option.rect; + + // get pixmap + QIcon icon = qvariant_cast(index.data(Qt::DecorationRole)); + QPixmap pix = icon.pixmap(r.size()); + + // draw pixmap at center of item + const QPoint p = QPoint((r.width() - pix.width()) / 2, (r.height() - pix.height()) / 2); + painter->drawPixmap(r.topLeft() + p, pix); +} diff --git a/SQLiteStudio3/guiSQLiteStudio/common/centerediconitemdelegate.h b/SQLiteStudio3/guiSQLiteStudio/common/centerediconitemdelegate.h new file mode 100644 index 0000000..a1e0103 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/common/centerediconitemdelegate.h @@ -0,0 +1,14 @@ +#ifndef CENTEREDICONITEMDELEGATE_H +#define CENTEREDICONITEMDELEGATE_H + +#include + +class CenteredIconItemDelegate : public QStyledItemDelegate +{ + public: + explicit CenteredIconItemDelegate(QObject* parent = nullptr); + + void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; +}; + +#endif // CENTEREDICONITEMDELEGATE_H diff --git a/SQLiteStudio3/guiSQLiteStudio/common/extlineedit.cpp b/SQLiteStudio3/guiSQLiteStudio/common/extlineedit.cpp index bd0bffa..ccbc586 100644 --- a/SQLiteStudio3/guiSQLiteStudio/common/extlineedit.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/common/extlineedit.cpp @@ -55,10 +55,17 @@ void ExtLineEdit::setClearButtonEnabled(bool enable) qWarning() << "Could not find 'clear action' in QLineEdit, so 'valueErased()' signal won't be emitted from ExtLineEdit."; return; } - connect(clearAction, SIGNAL(triggered()), this, SIGNAL(valueErased())); + connect(clearAction, SIGNAL(triggered()), this, SLOT(checkForValueErased())); } } +void ExtLineEdit::checkForValueErased() +{ + if (text().isEmpty()) + return; + + emit valueErased(); +} bool ExtLineEdit::getExpanding() const { diff --git a/SQLiteStudio3/guiSQLiteStudio/common/extlineedit.h b/SQLiteStudio3/guiSQLiteStudio/common/extlineedit.h index b3bffbb..df2eaf6 100644 --- a/SQLiteStudio3/guiSQLiteStudio/common/extlineedit.h +++ b/SQLiteStudio3/guiSQLiteStudio/common/extlineedit.h @@ -37,6 +37,7 @@ class GUI_API_EXPORT ExtLineEdit : public QLineEdit private slots: void handleTextChanged(); + void checkForValueErased(); signals: void valueErased(); diff --git a/SQLiteStudio3/guiSQLiteStudio/common/exttableview.cpp b/SQLiteStudio3/guiSQLiteStudio/common/exttableview.cpp new file mode 100644 index 0000000..f12e557 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/common/exttableview.cpp @@ -0,0 +1,14 @@ +#include "exttableview.h" +#include + +ExtTableView::ExtTableView(QWidget* parent) : + QTableView(parent) +{ + +} + +void ExtTableView::mouseDoubleClickEvent(QMouseEvent* e) +{ + QModelIndex index = indexAt(e->pos()); + emit doubleClicked(index); +} diff --git a/SQLiteStudio3/guiSQLiteStudio/common/exttableview.h b/SQLiteStudio3/guiSQLiteStudio/common/exttableview.h new file mode 100644 index 0000000..06e597c --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/common/exttableview.h @@ -0,0 +1,15 @@ +#ifndef EXTTABLEVIEW_H +#define EXTTABLEVIEW_H + +#include + +class ExtTableView : public QTableView +{ + public: + explicit ExtTableView(QWidget* parent = nullptr); + + protected: + void mouseDoubleClickEvent(QMouseEvent* e); +}; + +#endif // EXTTABLEVIEW_H diff --git a/SQLiteStudio3/guiSQLiteStudio/common/exttablewidget.cpp b/SQLiteStudio3/guiSQLiteStudio/common/exttablewidget.cpp new file mode 100644 index 0000000..8bba429 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/common/exttablewidget.cpp @@ -0,0 +1,15 @@ +#include "exttablewidget.h" + +#include + +ExtTableWidget::ExtTableWidget(QWidget* parent) : + QTableWidget(parent) +{ + +} + +void ExtTableWidget::mouseDoubleClickEvent(QMouseEvent* e) +{ + QModelIndex index = indexAt(e->pos()); + emit doubleClicked(index); +} diff --git a/SQLiteStudio3/guiSQLiteStudio/common/exttablewidget.h b/SQLiteStudio3/guiSQLiteStudio/common/exttablewidget.h new file mode 100644 index 0000000..719e064 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/common/exttablewidget.h @@ -0,0 +1,15 @@ +#ifndef EXTTABLEWIDGET_H +#define EXTTABLEWIDGET_H + +#include + +class ExtTableWidget : public QTableWidget +{ + public: + explicit ExtTableWidget(QWidget* parent = nullptr); + + protected: + void mouseDoubleClickEvent(QMouseEvent* e); +}; + +#endif // EXTTABLEWIDGET_H diff --git a/SQLiteStudio3/guiSQLiteStudio/common/numericspinbox.cpp b/SQLiteStudio3/guiSQLiteStudio/common/numericspinbox.cpp index e1b6620..ff49cd2 100644 --- a/SQLiteStudio3/guiSQLiteStudio/common/numericspinbox.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/common/numericspinbox.cpp @@ -112,6 +112,15 @@ QAbstractSpinBox::StepEnabled NumericSpinBox::stepEnabled() const QVariant NumericSpinBox::getFixedVariant(const QVariant& value) { + if (allowEmpty) + { + if (value.userType() == QVariant::String && value.toString().isEmpty() && !value.isNull()) + return ""; + + if (value.isNull()) + return QString(); + } + bool ok; qint64 longVal = value.toLongLong(&ok); if (ok) diff --git a/SQLiteStudio3/guiSQLiteStudio/configmapper.cpp b/SQLiteStudio3/guiSQLiteStudio/configmapper.cpp index da1ff44..8543d37 100644 --- a/SQLiteStudio3/guiSQLiteStudio/configmapper.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/configmapper.cpp @@ -92,7 +92,6 @@ ConfigMapper::ConfigMapper(const QList cfgMain) : { } - void ConfigMapper::applyCommonConfigToWidget(QWidget *widget, const QVariant &value, CfgEntry* cfgEntry) { APPLY_CFG(widget, value, QCheckBox, setChecked, bool); @@ -221,6 +220,20 @@ QVariant ConfigMapper::getConfigValueFromWidget(QWidget* widget, CfgEntry* key) return value; } +QVariant ConfigMapper::getConfigValueFromWidget(QWidget* widget) +{ + QString keyStr = widget->property(CFG_MODEL_PROPERTY).toString(); + QHash allConfigEntries = getAllConfigEntries(); + if (!allConfigEntries.contains(keyStr)) + { + qWarning() << "Asked for config value from widget" << widget << "but it's config entry key was not found:" << keyStr; + return QVariant(); + } + + CfgEntry* key = allConfigEntries[keyStr]; + return getConfigValueFromWidget(widget, key); +} + void ConfigMapper::loadToWidget(QWidget *topLevelWidget) { QHash allConfigEntries = getAllConfigEntries(); @@ -231,10 +244,13 @@ void ConfigMapper::loadToWidget(QWidget *topLevelWidget) config = CFG->getAll(); updatingEntry = true; - foreach (QWidget* widget, allConfigWidgets) + for (QWidget* widget : allConfigWidgets) applyConfigToWidget(widget, allConfigEntries, config); updatingEntry = false; + + for (QWidget* widget : allConfigWidgets) + handleDependencySettings(widget); } void ConfigMapper::loadToWidget(CfgEntry* config, QWidget* widget) @@ -247,6 +263,8 @@ void ConfigMapper::loadToWidget(CfgEntry* config, QWidget* widget) applyCommonConfigToWidget(widget, configValue, config); updatingEntry = false; + + handleDependencySettings(widget); } void ConfigMapper::saveFromWidget(QWidget *widget, bool noTransaction) @@ -310,6 +328,20 @@ void ConfigMapper::applyConfigToWidget(QWidget* widget, CfgEntry* cfgEntry, cons applyCommonConfigToWidget(widget, configValue, cfgEntry); } +void ConfigMapper::applyConfigDefaultValueToWidget(QWidget* widget) +{ + QString keyStr = widget->property(CFG_MODEL_PROPERTY).toString(); + QHash allConfigEntries = getAllConfigEntries(); + if (!allConfigEntries.contains(keyStr)) + { + qWarning() << "Asked to apply config value to widget" << widget << "but it's config entry key was not found:" << keyStr; + return; + } + + CfgEntry* key = allConfigEntries[keyStr]; + applyConfigToWidget(widget, key, key->getDefultValue()); +} + void ConfigMapper::handleSpecialWidgets(QWidget* widget, const QHash& allConfigEntries) { handleConfigComboBox(widget, allConfigEntries); @@ -474,7 +506,7 @@ QList ConfigMapper::getAllConfigWidgets(QWidget *parent) foreach (QObject* obj, parent->children()) { widget = qobject_cast(obj); - if (!widget) + if (!widget || widgetsToIgnore.contains(widget)) continue; results += getAllConfigWidgets(widget); @@ -486,6 +518,60 @@ QList ConfigMapper::getAllConfigWidgets(QWidget *parent) return results; } +void ConfigMapper::handleDependencySettings(QWidget* widget) +{ + QString boolDependency = widget->property(CFG_BOOL_DEPENDENCY_PROPERTY).toString(); + if (!boolDependency.isNull()) + { + handleBoolDependencySettings(boolDependency, widget); + return; + } +} + +void ConfigMapper::handleBoolDependencySettings(const QString& boolDependency, QWidget* widget) +{ + QHash allConfigEntries = getAllConfigEntries(); + if (!allConfigEntries.contains(boolDependency)) + { + qWarning() << "Config widget" << widget->objectName() << "has dependency defined for" << boolDependency << "but that dependency config entry cannot be found."; + return; + } + + CfgEntry* cfg = allConfigEntries[boolDependency]; + QVariant cfgValue = cfg->get(); + if (cfgValue.userType() != QVariant::Bool) + { + qWarning() << "Config widget" << widget->objectName() << "has bool dependency defined for" << boolDependency << "but that dependency has different type:" << cfgValue.userType(); + return; + } + + bool value = cfgValue.toBool(); + widget->setEnabled(value); + + QWidget* dependWidget = configEntryToWidgets[cfg]; + boolDependencyToDependingWidget[dependWidget] = widget; +} + +void ConfigMapper::handleDependencyChange(QWidget* widget) +{ + if (handleBoolDependencyChange(widget)) + return; +} + +bool ConfigMapper::handleBoolDependencyChange(QWidget* widget) +{ + if (!boolDependencyToDependingWidget.contains(widget)) + return false; + + QWidget* depWid = boolDependencyToDependingWidget[widget]; + bool value = getConfigValueFromWidget(widget).toBool(); + depWid->setEnabled(value); + if (!value) + applyConfigDefaultValueToWidget(depWid); + + return true; +} + bool ConfigMapper::isPersistant() const { for (CfgMain* cfgMain : cfgMainList) @@ -520,11 +606,21 @@ void ConfigMapper::clearExtraWidgets() extraWidgets.clear(); } +void ConfigMapper::ignoreWidget(QWidget* w) +{ + widgetsToIgnore << w; +} + +void ConfigMapper::removeIgnoredWidget(QWidget* w) +{ + widgetsToIgnore.removeOne(w); +} + void ConfigMapper::handleModified() { + QWidget* widget = dynamic_cast(sender()); if (realTimeUpdates && !updatingEntry) { - QWidget* widget = dynamic_cast(sender()); if (widget && widgetToConfigEntry.contains(widget)) { updatingEntry = true; @@ -532,6 +628,9 @@ void ConfigMapper::handleModified() updatingEntry = false; } } + + handleDependencyChange(widget); + emit modified(); } @@ -639,6 +738,11 @@ void ConfigMapper::unbindFromConfig() realTimeUpdates = false; } +void ConfigMapper::removeMainCfgEntry(CfgMain* cfgMain) +{ + cfgMainList.removeOne(cfgMain); +} + QWidget* ConfigMapper::getBindWidgetForConfig(CfgEntry* key) const { if (configEntryToWidgets.contains(key)) diff --git a/SQLiteStudio3/guiSQLiteStudio/configmapper.h b/SQLiteStudio3/guiSQLiteStudio/configmapper.h index 049d25a..47c1087 100644 --- a/SQLiteStudio3/guiSQLiteStudio/configmapper.h +++ b/SQLiteStudio3/guiSQLiteStudio/configmapper.h @@ -4,6 +4,7 @@ #include "common/bihash.h" #include "guiSQLiteStudio_global.h" #include +#include class CfgMain; class CfgEntry; @@ -22,6 +23,7 @@ class GUI_API_EXPORT ConfigMapper : public QObject void loadToWidget(CfgEntry* config, QWidget* widget); void saveFromWidget(QWidget* widget, bool noTransaction = false); void setInternalCustomConfigWidgets(const QList& value); + bool isPersistant() const; /** * @brief Scans widget and binds widgets to proper config objects. @@ -49,6 +51,7 @@ class GUI_API_EXPORT ConfigMapper : public QObject * This simply revokes what was done with bindToConfig(). */ void unbindFromConfig(); + void removeMainCfgEntry(CfgMain* cfgMain); QWidget* getBindWidgetForConfig(CfgEntry* key) const; CfgEntry* getBindConfigForWidget(QWidget* widget) const; @@ -69,10 +72,13 @@ class GUI_API_EXPORT ConfigMapper : public QObject void addExtraWidget(QWidget* w); void addExtraWidgets(const QList& list); void clearExtraWidgets(); + void ignoreWidget(QWidget* w); + void removeIgnoredWidget(QWidget* w); private: void applyConfigToWidget(QWidget *widget, const QHash& allConfigEntries, const QHash &config); void applyConfigToWidget(QWidget *widget, CfgEntry* cfgEntry, const QVariant& configValue); + void applyConfigDefaultValueToWidget(QWidget *widget); void handleSpecialWidgets(QWidget *widget, const QHash& allConfigEntries); void handleConfigComboBox(QWidget *widget, const QHash& allConfigEntries); void connectCommonNotifierToWidget(QWidget *widget, CfgEntry* key); @@ -86,12 +92,17 @@ class GUI_API_EXPORT ConfigMapper : public QObject QVariant getCommonConfigValueFromWidget(QWidget *widget, CfgEntry* key, bool& ok); QVariant getCustomConfigValueFromWidget(QWidget *widget, CfgEntry* key, bool& ok); QVariant getConfigValueFromWidget(QWidget *widget, CfgEntry* key); + QVariant getConfigValueFromWidget(QWidget *widget); CfgEntry* getConfigEntry(QWidget* widget, const QHash& allConfigEntries); CfgEntry* getEntryForProperty(QWidget* widget, const char* propertyName, const QHash& allConfigEntries); QHash getAllConfigEntries(); QList getAllConfigWidgets(QWidget* parent); - bool isPersistant() const; + void handleDependencySettings(QWidget* widget); + void handleBoolDependencySettings(const QString& boolDependency, QWidget* widget); + void handleDependencyChange(QWidget* widget); + bool handleBoolDependencyChange(QWidget* widget); + QWidget* configDialogWidget = nullptr; QList cfgMainList; QList internalCustomConfigWidgets; bool realTimeUpdates = false; @@ -100,9 +111,12 @@ class GUI_API_EXPORT ConfigMapper : public QObject QHash specialConfigEntryToWidgets; bool updatingEntry = false; QList extraWidgets; + QList widgetsToIgnore; // main mapper will ignore plugin's forms, they have their own mappers QHash allEntries; + QHash boolDependencyToDependingWidget; static constexpr const char* CFG_MODEL_PROPERTY = "cfg"; + static constexpr const char* CFG_BOOL_DEPENDENCY_PROPERTY = "boolDependency"; static constexpr const char* CFG_NOTIFY_PROPERTY = "notify"; static constexpr const char* CFG_PREVIEW_PROPERTY = "preview"; diff --git a/SQLiteStudio3/guiSQLiteStudio/constraints/columndefaultpanel.cpp b/SQLiteStudio3/guiSQLiteStudio/constraints/columndefaultpanel.cpp index 4f402b2..9322117 100644 --- a/SQLiteStudio3/guiSQLiteStudio/constraints/columndefaultpanel.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/constraints/columndefaultpanel.cpp @@ -106,6 +106,7 @@ void ColumnDefaultPanel::constraintAvailable() readConstraint(); updateVirtualSql(); + validateOnly(); } void ColumnDefaultPanel::storeConfiguration() @@ -237,7 +238,7 @@ void ColumnDefaultPanel::readConstraint() } else if (!constr->id.isNull()) { - ui->exprEdit->setPlainText(constr->id); + ui->exprEdit->setPlainText(wrapObjIfNeeded(constr->id, db->getDialect(), true)); currentMode = Mode::LITERAL; } else if (!constr->ctime.isNull()) diff --git a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlqueryitem.cpp b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlqueryitem.cpp index 9b8dd03..be26d9f 100644 --- a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlqueryitem.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlqueryitem.cpp @@ -3,6 +3,7 @@ #include "sqlquerymodel.h" #include "iconmanager.h" #include "uiconfig.h" +#include "sqlqueryview.h" #include #include @@ -382,6 +383,9 @@ QVariant SqlQueryItem::data(int role) const } case Qt::ToolTipRole: { + if (!CFG_UI.General.ShowDataViewTooltips.get() || getModel()->getView()->getSimpleBrowserMode()) + return QVariant(); + return getToolTip(); } } diff --git a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlqueryitemdelegate.cpp b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlqueryitemdelegate.cpp index 920ddda..19090ad 100644 --- a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlqueryitemdelegate.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlqueryitemdelegate.cpp @@ -6,12 +6,17 @@ #include "sqlqueryview.h" #include "uiconfig.h" #include "common/utils_sql.h" +#include "schemaresolver.h" #include #include #include #include #include #include +#include +#include +#include +#include SqlQueryItemDelegate::SqlQueryItemDelegate(QObject *parent) : QStyledItemDelegate(parent) @@ -66,7 +71,7 @@ QString SqlQueryItemDelegate::displayText(const QVariant& value, const QLocale& UNUSED(locale); if (value.type() == QVariant::Double) - return value.toString(); + return doubleToString(value.toDouble()); return QStyledItemDelegate::displayText(value, locale); } @@ -74,12 +79,14 @@ QString SqlQueryItemDelegate::displayText(const QVariant& value, const QLocale& void SqlQueryItemDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const { QComboBox* cb = dynamic_cast(editor); - if (!cb) { + QLineEdit* le = dynamic_cast(editor); + if (cb) { + setEditorDataForFk(cb, index); + } else if (le) { + setEditorDataForLineEdit(le, index); + } else { QStyledItemDelegate::setEditorData(editor, index); - return; } - - setEditorDataForFk(cb, index); } void SqlQueryItemDelegate::setEditorDataForFk(QComboBox* cb, const QModelIndex& index) const @@ -93,7 +100,7 @@ void SqlQueryItemDelegate::setEditorDataForFk(QComboBox* cb, const QModelIndex& cb->addItem(modelData.toString(), modelData); idx = cb->count() - 1; - QTableView* view = dynamic_cast(cb->view()); + SqlQueryView* view = dynamic_cast(cb->view()); view->resizeColumnsToContents(); view->setMinimumWidth(view->horizontalHeader()->length()); } @@ -103,23 +110,72 @@ void SqlQueryItemDelegate::setEditorDataForFk(QComboBox* cb, const QModelIndex& void SqlQueryItemDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { QComboBox* cb = dynamic_cast(editor); - if (!cb) { + QLineEdit* le = dynamic_cast(editor); + if (cb) { + setModelDataForFk(cb, model, index); + } else if (le) { + setModelDataForLineEdit(le, model, index); + } else { QStyledItemDelegate::setModelData(editor, model, index); - return; } - setModelDataForFk(cb, model, index); + SqlQueryModel* queryModel = const_cast(dynamic_cast(index.model())); + queryModel->notifyItemEditionEnded(index); } void SqlQueryItemDelegate::setModelDataForFk(QComboBox* cb, QAbstractItemModel* model, const QModelIndex& index) const { - QVariant comboData = cb->currentData(); - if (cb->currentText() != cb->itemText(cb->currentIndex())) + SqlQueryModel* cbModel = dynamic_cast(cb->model()); + if (cbModel->isExecutionInProgress() || !cbModel->isAllDataLoaded()) + return; + + int idx = cb->currentIndex(); + if (idx < 0 || idx >= cbModel->rowCount()) + { + model->setData(index, cb->currentText()); + return; + } + + QVariant comboData = cbModel->getRow(idx)[0]->getValue(); + if (cb->currentText() != comboData.toString()) comboData = cb->currentText(); model->setData(index, comboData); } +void SqlQueryItemDelegate::setModelDataForLineEdit(QLineEdit* editor, QAbstractItemModel* model, const QModelIndex& index) const +{ + QString value = editor->text(); + bool ok; + QVariant variant = value.toLongLong(&ok); + if (ok) + { + model->setData(index, variant, Qt::EditRole); + return; + } + + variant = value.toDouble(&ok); + if (ok) + { + model->setData(index, variant, Qt::EditRole); + return; + } + + model->setData(index, value, Qt::EditRole); +} + +void SqlQueryItemDelegate::setEditorDataForLineEdit(QLineEdit* le, const QModelIndex& index) const +{ + QVariant value = index.data(Qt::EditRole); + if (value.userType() == QVariant::Double) + { + le->setText(doubleToString(value.toDouble())); + return; + } + + le->setText(value.toString()); +} + SqlQueryItem* SqlQueryItemDelegate::getItem(const QModelIndex &index) const { const SqlQueryModel* queryModel = dynamic_cast(index.model()); @@ -137,16 +193,25 @@ QWidget* SqlQueryItemDelegate::getEditor(int type, QWidget* parent) const QString SqlQueryItemDelegate::getSqlForFkEditor(SqlQueryItem* item) const { - QString sql = QStringLiteral("SELECT %1 FROM %2%3"); - QStringList selCols; - QStringList fkTables; - QStringList fkCols; + static_qstring(sql, "SELECT %1 FROM %2%3"); + static_qstring(srcColTpl, "%1 AS %2"); + static_qstring(dbColTpl, "%1.%2 AS %3"); + static_qstring(conditionTpl, "%1.%2 = %3.%4"); + static_qstring(conditionPrefixTpl, " WHERE %1"); + static_qstring(cellLimitTpl, "substr(%2, 0, %1)"); + + QStringList selectedCols; + QStringList fkConfitionTables; + QStringList fkConditionCols; + QStringList srcCols; Db* db = item->getModel()->getDb(); Dialect dialect = db->getDialect(); + SchemaResolver resolver(db); QList fkList = item->getColumn()->getFkConstraints(); int i = 0; QString src; + QString fullSrcCol; QString col; for (SqlQueryModelColumn::ConstraintFk* fk : fkList) { @@ -154,100 +219,138 @@ QString SqlQueryItemDelegate::getSqlForFkEditor(SqlQueryItem* item) const src = wrapObjIfNeeded(fk->foreignTable, dialect); if (i == 0) { - selCols << QString("%1.%2 AS %3").arg(src, col, + selectedCols << dbColTpl.arg(src, col, wrapObjIfNeeded(item->getColumn()->column, dialect)); } - selCols << src + ".*"; - fkCols << col; - fkTables << src; + srcCols = resolver.getTableColumns(src); + for (const QString& srcCol : srcCols) + { + if (fk->foreignColumn.compare(srcCol, Qt::CaseInsensitive) == 0) + continue; // Exclude matching column. We don't want the same column several times. + + fullSrcCol = src + "." + srcCol; + selectedCols << srcColTpl.arg(cellLimitTpl.arg(CELL_LENGTH_LIMIT).arg(fullSrcCol), wrapObjName(fullSrcCol, dialect)); + } + + fkConditionCols << col; + fkConfitionTables << src; i++; } QStringList conditions; - QString firstSrc = wrapObjIfNeeded(fkTables.first(), dialect); - QString firstCol = wrapObjIfNeeded(fkCols.first(), dialect); - for (i = 1; i < fkTables.size(); i++) + QString firstSrc = wrapObjIfNeeded(fkConfitionTables.first(), dialect); + QString firstCol = wrapObjIfNeeded(fkConditionCols.first(), dialect); + for (i = 1; i < fkConfitionTables.size(); i++) { - src = wrapObjIfNeeded(fkTables[i], dialect); - col = wrapObjIfNeeded(fkCols[i], dialect); - conditions << QString("%1.%2 = %3.%4").arg(firstSrc, firstCol, src, col); + src = wrapObjIfNeeded(fkConfitionTables[i], dialect); + col = wrapObjIfNeeded(fkConditionCols[i], dialect); + conditions << conditionTpl.arg(firstSrc, firstCol, src, col); } QString conditionsStr; if (!conditions.isEmpty()) { - conditionsStr = " WHERE " + conditions.join(", "); + conditionsStr = conditionPrefixTpl.arg(conditions.join(", ")); } - return sql.arg(selCols.join(", "), fkTables.join(", "), conditionsStr); + return sql.arg(selectedCols.join(", "), fkConfitionTables.join(", "), conditionsStr); } -void SqlQueryItemDelegate::copyToModel(const SqlQueryPtr& results, QStandardItemModel* model) const +qlonglong SqlQueryItemDelegate::getRowCountForFkEditor(Db* db, const QString& query) const { - QList rows = results->getAll(); - int colCount = results->columnCount(); - int rowCount = rows.size() + 1; + static_qstring(tpl, "SELECT count(*) FROM (%1)"); - model->setColumnCount(colCount); - model->setRowCount(rowCount); - int colIdx = 0; - int rowIdx = 0; - for (const QString& colName : results->getColumnNames()) - { - model->setHeaderData(colIdx, Qt::Horizontal, colName); - - QStandardItem *item = new QStandardItem(); - QFont font = item->font(); - font.setItalic(true); - item->setFont(font); - item->setForeground(QBrush(CFG_UI.Colors.DataNullFg.get())); - item->setData(QVariant(QVariant::String), Qt::EditRole); - item->setData(QVariant(QVariant::String), Qt::UserRole); - model->setItem(0, colIdx, item); - colIdx++; - } - rowIdx++; + QString sql = tpl.arg(query); + SqlQueryPtr result = db->exec(sql); + return result->getSingleCell().toLongLong(); +} - for (const SqlResultsRowPtr& row : rows) - { - colIdx = 0; - for (const QVariant& val : row->valueList()) - { - QStandardItem *item = new QStandardItem(); - item->setText(val.toString()); - item->setData(val, Qt::UserRole); - model->setItem(rowIdx, colIdx, item); - colIdx++; - } - rowIdx++; - } +void SqlQueryItemDelegate::fkDataReady() +{ + SqlQueryModel* model = dynamic_cast(sender()); + SqlQueryView* queryView = model->getView(); + + queryView->resizeColumnsToContents(); + queryView->resizeRowsToContents(); + + int wd = queryView->horizontalHeader()->length(); + if (model->rowCount() > 10) // 10 is default visible item count for combobox + wd += queryView->verticalScrollBar()->sizeHint().width(); + + queryView->setMinimumWidth(wd); + + // Set selected combo value to initial value from the cell + QComboBox* cb = modelToFkCombo[model]; + QVariant value = modelToFkInitialValue[model]; + QModelIndexList idxList = model->findIndexes(SqlQueryItem::DataRole::VALUE, value, 1); + + int idx = 0; + if (idxList.size() > 0) + idx = idxList.first().row(); + + cb->setCurrentIndex(idx); } QWidget* SqlQueryItemDelegate::getFkEditor(SqlQueryItem* item, QWidget* parent) const { QString sql = getSqlForFkEditor(item); + Db* db = item->getModel()->getDb(); + qlonglong rowCount = getRowCountForFkEditor(db, sql); + if (rowCount > MAX_ROWS_FOR_FK) + { + notifyWarn(tr("Foreign key for column %2 has more than %1 possible values. It's too much to display in drop down list. You need to edit value manually.") + .arg(MAX_ROWS_FOR_FK).arg(item->getColumn()->column)); + + return getEditor(item->getValue().userType(), parent); + } + QComboBox *cb = new QComboBox(parent); cb->setEditable(true); - QTableView* queryView = new QTableView(); - QStandardItemModel* model = new QStandardItemModel(queryView); - Db* db = item->getModel()->getDb(); - SqlQueryPtr results = db->exec(sql); - copyToModel(results, model); + // Prepare combo dropdown view. + SqlQueryView* queryView = new SqlQueryView(); + queryView->setSimpleBrowserMode(true); + connect(queryView->horizontalHeader(), &QHeaderView::sectionResized, [queryView](int, int, int) + { + int wd = queryView->horizontalHeader()->length(); + if (queryView->verticalScrollBar()->isVisible()) + wd += queryView->verticalScrollBar()->width(); + + queryView->setMinimumWidth(wd); + }); + SqlQueryModel* model = new SqlQueryModel(queryView); + model->setView(queryView); + + // Mapping of model to cb, so we can update combo when data arrives. + modelToFkInitialValue[model] = item->getValue(); + modelToFkCombo[model] = cb; + connect(cb, &QComboBox::destroyed, [this, model](QObject*) + { + modelToFkCombo.remove(model); + modelToFkInitialValue.remove(model); + }); + + // When execution is done, update combo. + connect(model, SIGNAL(executionSuccessful()), this, SLOT(fkDataReady())); + + // Setup combo, model, etc. cb->setModel(model); cb->setView(queryView); cb->setModelColumn(0); + model->setHardRowLimit(MAX_ROWS_FOR_FK); + model->setDb(db); + model->setQuery(sql); + model->executeQuery(); + queryView->verticalHeader()->setVisible(false); queryView->horizontalHeader()->setVisible(true); queryView->setSelectionMode(QAbstractItemView::SingleSelection); queryView->setSelectionBehavior(QAbstractItemView::SelectRows); - queryView->resizeColumnsToContents(); - queryView->resizeRowsToContents(); - queryView->setMinimumWidth(queryView->horizontalHeader()->length()); return cb; } + diff --git a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlqueryitemdelegate.h b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlqueryitemdelegate.h index d79ebaf..82d12c3 100644 --- a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlqueryitemdelegate.h +++ b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlqueryitemdelegate.h @@ -4,10 +4,12 @@ #include "guiSQLiteStudio_global.h" #include "db/sqlquery.h" #include +#include class SqlQueryItem; class QComboBox; class QStandardItemModel; +class SqlQueryModel; class GUI_API_EXPORT SqlQueryItemDelegate : public QStyledItemDelegate { @@ -25,10 +27,22 @@ class GUI_API_EXPORT SqlQueryItemDelegate : public QStyledItemDelegate SqlQueryItem* getItem(const QModelIndex &index) const; QWidget* getEditor(int type, QWidget* parent) const; QWidget* getFkEditor(SqlQueryItem* item, QWidget* parent) const; + void setEditorDataForLineEdit(QLineEdit* le, const QModelIndex& index) const; void setEditorDataForFk(QComboBox* cb, const QModelIndex& index) const; void setModelDataForFk(QComboBox* editor, QAbstractItemModel* model, const QModelIndex& index) const; + void setModelDataForLineEdit(QLineEdit* editor, QAbstractItemModel* model, const QModelIndex& index) const; QString getSqlForFkEditor(SqlQueryItem* item) const; - void copyToModel(const SqlQueryPtr& results, QStandardItemModel* model) const; + qlonglong getRowCountForFkEditor(Db* db, const QString& query) const; + + QSet editorsWithAsyncExecution; + mutable QHash modelToFkCombo; + mutable QHash modelToFkInitialValue; + + static const qlonglong MAX_ROWS_FOR_FK = 10000L; + static const int CELL_LENGTH_LIMIT = 30; + + private slots: + void fkDataReady(); }; #endif // SQLQUERYITEMDELEGATE_H diff --git a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlquerymodel.cpp b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlquerymodel.cpp index 6717c14..15cf1bf 100644 --- a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlquerymodel.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlquerymodel.cpp @@ -11,6 +11,7 @@ #include "datagrid/sqlqueryview.h" #include "datagrid/sqlqueryrownummodel.h" #include "services/dbmanager.h" +#include "querygenerator.h" #include #include #include @@ -19,6 +20,9 @@ #include #include #include +#include + +QSet SqlQueryModel::existingModels; SqlQueryModel::SqlQueryModel(QObject *parent) : QStandardItemModel(parent) @@ -29,10 +33,13 @@ SqlQueryModel::SqlQueryModel(QObject *parent) : connect(queryExecutor, SIGNAL(executionFailed(int,QString)), this, SLOT(handleExecFailed(int,QString))); connect(queryExecutor, SIGNAL(resultsCountingFinished(quint64,quint64,int)), this, SLOT(resultsCountingFinished(quint64,quint64,int))); setItemPrototype(new SqlQueryItem()); + existingModels << this; } SqlQueryModel::~SqlQueryModel() { + existingModels.remove(this); + delete queryExecutor; queryExecutor = nullptr; } @@ -109,7 +116,7 @@ void SqlQueryModel::executeQueryInternal() emit executionStarted(); queryExecutor->setQuery(query); - queryExecutor->setResultsPerPage(CFG_UI.General.NumberOfRowsPerPage.get()); + queryExecutor->setResultsPerPage(getRowsPerPage()); queryExecutor->setExplainMode(explain); queryExecutor->setPreloadResults(true); queryExecutor->exec(); @@ -345,30 +352,7 @@ void SqlQueryModel::commitInternal(const QList& items) return; } - dbNameToAttachNameMapForCommit.clear(); - QList dbListToDetach; - QString attachName; - for (const QString& reqAttach : queryExecutor->getRequiredDbAttaches()) - { - Db* attachDb = DBLIST->getByName(reqAttach, Qt::CaseInsensitive); - if (!attachDb) - { - qCritical() << "Could not resolve database" << reqAttach << ", while it's a required attach name for SqlQueryModel to commit edited data!" - << "This may result in errors when commiting some data modifications."; - continue; - } - - attachName = db->attach(attachDb); - if (attachName.isNull()) - { - qCritical() << "Could not attach database" << reqAttach << ", while it's a required attach name for SqlQueryModel to commit edited data!" - << "This may result in errors when commiting some data modifications."; - continue; - } - - dbNameToAttachNameMapForCommit[reqAttach] = attachName; - dbListToDetach << attachDb; - } + attachDependencyTables(); if (!db->begin()) { @@ -448,10 +432,7 @@ void SqlQueryModel::commitInternal(const QList& items) } } - dbNameToAttachNameMapForCommit.clear(); - for (Db* dbToDetach : dbListToDetach) - db->detach(dbToDetach); - + detachDependencyTables(); // Updating added/deleted counts, to honor rows not deleted because of some errors numberOfItemsAdded -= groupItemsByRows(findItems(SqlQueryItem::DataRole::NEW_ROW, true)).size(); @@ -492,6 +473,76 @@ void SqlQueryModel::reloadInternal() executeQueryInternal(); } +StrHash SqlQueryModel::attachDependencyTables() +{ + dbNameToAttachNameMapForCommit.clear(); + dbListToDetach.clear(); + + QString attachName; + for (const QString& reqAttach : queryExecutor->getRequiredDbAttaches()) + { + Db* attachDb = DBLIST->getByName(reqAttach, Qt::CaseInsensitive); + if (!attachDb) + { + qCritical() << "Could not resolve database" << reqAttach << ", while it's a required attach name for SqlQueryModel to commit edited data!" + << "This may result in errors when commiting some data modifications."; + continue; + } + + attachName = db->attach(attachDb); + if (attachName.isNull()) + { + qCritical() << "Could not attach database" << reqAttach << ", while it's a required attach name for SqlQueryModel to commit edited data!" + << "This may result in errors when commiting some data modifications."; + continue; + } + + dbNameToAttachNameMapForCommit[reqAttach] = attachName; + dbListToDetach << attachDb; + } + + return dbNameToAttachNameMapForCommit; +} + +void SqlQueryModel::detachDependencyTables() +{ + for (Db* dbToDetach : dbListToDetach) + db->detach(dbToDetach); + + dbNameToAttachNameMapForCommit.clear(); + dbListToDetach.clear(); +} + +QString SqlQueryModel::generateSelectQueryForItems(const QList& items) +{ + QHash values = toValuesGroupedByColumns(items); + + QueryGenerator generator; + BiStrHash attachMap = BiStrHash(attachDependencyTables().toQHash()); + QString sql = generator.generateSelectFromSelect(db, getQuery(), values, attachMap); + detachDependencyTables(); + + return sql; +} + +QString SqlQueryModel::generateInsertQueryForItems(const QList& items) +{ + UNUSED(items); + return QString(); +} + +QString SqlQueryModel::generateUpdateQueryForItems(const QList& items) +{ + UNUSED(items); + return QString(); +} + +QString SqlQueryModel::generateDeleteQueryForItems(const QList& items) +{ + UNUSED(items); + return QString(); +} + SqlQueryView* SqlQueryModel::getView() const { return view; @@ -681,11 +732,12 @@ QList SqlQueryModel::getTableColumnModels(const QString& return getTableColumnModels("main", table); } -void SqlQueryModel::loadData(SqlQueryPtr results) +bool SqlQueryModel::loadData(SqlQueryPtr results) { if (rowCount() > 0) clear(); + allDataLoaded = false; view->horizontalHeader()->show(); // Read columns first. It will be needed later. @@ -694,11 +746,10 @@ void SqlQueryModel::loadData(SqlQueryPtr results) // Load data SqlResultsRowPtr row; int rowIdx = 0; - int rowsPerPage = CFG_UI.General.NumberOfRowsPerPage.get(); + int rowsPerPage = getRowsPerPage(); rowNumBase = getCurrentPage() * rowsPerPage + 1; updateColumnHeaderLabels(); - QList itemList; QList> rowList; while (results->hasNext() && rowIdx < rowsPerPage) { @@ -706,12 +757,14 @@ void SqlQueryModel::loadData(SqlQueryPtr results) if (!row) break; - itemList = loadRow(row); - //insertRow(rowIdx, itemList); - rowList << itemList; + rowList << loadRow(row); if ((rowIdx % 50) == 0) + { qApp->processEvents(); + if (!existingModels.contains(this)) + return false; + } rowIdx++; } @@ -719,6 +772,9 @@ void SqlQueryModel::loadData(SqlQueryPtr results) rowIdx = 0; for (const QList& row : rowList) insertRow(rowIdx++, row); + + allDataLoaded = true; + return true; } QList SqlQueryModel::loadRow(SqlResultsRowPtr row) @@ -846,6 +902,20 @@ void SqlQueryModel::updateRowIdForAllItems(const AliasedTable& table, const RowI } } +QHash SqlQueryModel::toValuesGroupedByColumns(const QList& items) +{ + QHash values; + for (SqlQueryItem* item : items) + values[item->getColumn()->displayName] << item->getFullValue(); + + return values; +} + +bool SqlQueryModel::supportsModifyingQueriesInMenu() const +{ + return false; +} + void SqlQueryModel::readColumns() { columns.clear(); @@ -1048,7 +1118,9 @@ void SqlQueryModel::handleExecFinished(SqlQueryPtr results) } storeStep1NumbersFromExecution(); - loadData(results); + if (!loadData(results)) + return; + storeStep2NumbersFromExecution(); requiredDbAttaches = queryExecutor->getRequiredDbAttaches(); @@ -1061,7 +1133,7 @@ void SqlQueryModel::handleExecFinished(SqlQueryPtr results) reloading = false; - bool rowsCountedManually = queryExecutor->isRowCountingRequired() || rowCount() < CFG_UI.General.NumberOfRowsPerPage.get(); + bool rowsCountedManually = queryExecutor->isRowCountingRequired() || rowCount() < getRowsPerPage(); bool countRes = false; if (rowsCountedManually) { @@ -1245,7 +1317,7 @@ void SqlQueryModel::storeStep2NumbersFromExecution() { if (!queryExecutor->getSkipRowCounting()) { - if (queryExecutor->isRowCountingRequired() || rowCount() < CFG_UI.General.NumberOfRowsPerPage.get()) + if (queryExecutor->isRowCountingRequired() || rowCount() < getRowsPerPage()) totalRowsReturned = rowCount(); } } @@ -1413,7 +1485,7 @@ void SqlQueryModel::recalculateRowsAndPages(int rowsDelta) { totalRowsReturned += rowsDelta; - int rowsPerPage = CFG_UI.General.NumberOfRowsPerPage.get(); + int rowsPerPage = getRowsPerPage(); totalPages = (int)qCeil(((double)totalRowsReturned) / ((double)rowsPerPage)); emit totalRowsAndPagesAvailable(); @@ -1440,6 +1512,35 @@ int SqlQueryModel::getInsertRowIndex() return row; } +void SqlQueryModel::notifyItemEditionEnded(const QModelIndex& idx) +{ + emit itemEditionEnded(itemFromIndex(idx)); +} + +int SqlQueryModel::getRowsPerPage() const +{ + int rowsPerPage = CFG_UI.General.NumberOfRowsPerPage.get(); + if (hardRowLimit > -1) + rowsPerPage = hardRowLimit; + + return rowsPerPage; +} + +bool SqlQueryModel::isAllDataLoaded() const +{ + return allDataLoaded; +} + +int SqlQueryModel::getHardRowLimit() const +{ + return hardRowLimit; +} + +void SqlQueryModel::setHardRowLimit(int value) +{ + hardRowLimit = value; +} + bool SqlQueryModel::getSimpleExecutionMode() const { return simpleExecutionMode; diff --git a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlquerymodel.h b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlquerymodel.h index f55185a..6af937b 100644 --- a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlquerymodel.h +++ b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlquerymodel.h @@ -8,9 +8,10 @@ #include "parser/ast/sqlitecreatetable.h" #include "common/column.h" #include "guiSQLiteStudio_global.h" +#include "sqlqueryitemdelegate.h" +#include "common/strhash.h" #include #include -#include class SqlQueryItem; class FormView; @@ -30,6 +31,8 @@ class GUI_API_EXPORT SqlQueryModel : public QStandardItemModel }; Q_DECLARE_FLAGS(Features, Feature) + friend class SqlQueryItemDelegate; + explicit SqlQueryModel(QObject *parent = 0); virtual ~SqlQueryModel(); @@ -58,6 +61,12 @@ class GUI_API_EXPORT SqlQueryModel : public QStandardItemModel QVariant headerData(int section, Qt::Orientation orientation, int role) const; bool isExecutionInProgress() const; void loadFullDataForEntireRow(int row); + StrHash attachDependencyTables(); + void detachDependencyTables(); + virtual QString generateSelectQueryForItems(const QList& items); + virtual QString generateInsertQueryForItems(const QList& items); + virtual QString generateUpdateQueryForItems(const QList& items); + virtual QString generateDeleteQueryForItems(const QList& items); virtual Features features() const; @@ -105,6 +114,7 @@ class GUI_API_EXPORT SqlQueryModel : public QStandardItemModel int getCurrentPage(bool includeOneBeingLoaded = false) const; void gotoPage(int newPage); bool canReload(); + virtual bool supportsModifyingQueriesInMenu() const; QueryExecutor::SortList getSortOrder() const; void setSortOrder(const QueryExecutor::SortList& newSortOrder); @@ -125,6 +135,11 @@ class GUI_API_EXPORT SqlQueryModel : public QStandardItemModel bool getSimpleExecutionMode() const; void setSimpleExecutionMode(bool value); + int getHardRowLimit() const; + void setHardRowLimit(int value); + + bool isAllDataLoaded() const; + protected: class CommitUpdateQueryBuilder : public RowIdConditionBuilder { @@ -208,6 +223,7 @@ class GUI_API_EXPORT SqlQueryModel : public QStandardItemModel void updateItem(SqlQueryItem* item, const QVariant& value, int columnIndex, const RowId& rowId); RowId getNewRowId(const RowId& currentRowId, const QList items); void updateRowIdForAllItems(const AliasedTable& table, const RowId& rowId, const RowId& newRowId); + QHash toValuesGroupedByColumns(const QList& items); QueryExecutor* queryExecutor = nullptr; Db* db = nullptr; @@ -235,7 +251,13 @@ class GUI_API_EXPORT SqlQueryModel : public QStandardItemModel QList constraints; }; - void loadData(SqlQueryPtr results); + /** + * @brief Loads data from queyr execution into UI cells. + * @param results Execution results from query executor. + * @return Whether to continue execution or not. + */ + bool loadData(SqlQueryPtr results); + QList loadRow(SqlResultsRowPtr row); RowId getRowIdValue(SqlResultsRowPtr row, int columnIdx); void readColumns(); @@ -263,6 +285,8 @@ class GUI_API_EXPORT SqlQueryModel : public QStandardItemModel QString getDatabaseForCommit(const QString& database); void recalculateRowsAndPages(int rowsDelta); int getInsertRowIndex(); + void notifyItemEditionEnded(const QModelIndex& idx); + int getRowsPerPage() const; QString query; bool explain = false; @@ -336,6 +360,14 @@ class GUI_API_EXPORT SqlQueryModel : public QStandardItemModel quint32 resultsCountingAsyncId = 0; QStringList requiredDbAttaches; StrHash dbNameToAttachNameMapForCommit; + QList dbListToDetach; + + /** + * @brief Sets row count limit, despite user configured limit. + * + * -1 to not apply hard limit (use user configured row limit), any other value is the limit. + */ + int hardRowLimit = -1; /** * @brief rowIdColumns @@ -358,6 +390,17 @@ class GUI_API_EXPORT SqlQueryModel : public QStandardItemModel QList rowsDeletedSuccessfullyInTheCommit; + bool allDataLoaded = false; + + /** + * @brief Set of existing model objects, updated for each construction and destruction. + * + * This is used by loadData() to determinathe whether processEvents() caused deletion of the model. + * We need to keep processEvents() call so the UI is responsive to Interrupt button, + * but this causes crash when model is deleted in the events processing (like when FK combobox is deleted faster than data is loaded). + */ + static QSet existingModels; + private slots: void handleExecFinished(SqlQueryPtr results); void handleExecFailed(int code, QString errorMessage); @@ -457,6 +500,7 @@ class GUI_API_EXPORT SqlQueryModel : public QStandardItemModel void aboutToCommit(int totalSteps); void commitingStepFinished(int step); void commitFinished(); + void itemEditionEnded(SqlQueryItem* item); }; Q_DECLARE_OPERATORS_FOR_FLAGS(SqlQueryModel::Features) diff --git a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlqueryview.cpp b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlqueryview.cpp index e610431..50a0480 100644 --- a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlqueryview.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlqueryview.cpp @@ -15,6 +15,8 @@ #include "windows/editorwindow.h" #include "mainwindow.h" #include "common/utils_sql.h" +#include "querygenerator.h" +#include "services/codeformatter.h" #include #include #include @@ -84,6 +86,10 @@ void SqlQueryView::createActions() createAction(ROLLBACK, ICONS.ROLLBACK, tr("Rollback"), this, SLOT(rollback()), this); createAction(SELECTIVE_COMMIT, ICONS.COMMIT, tr("Commit selected cells"), this, SLOT(selectiveCommit()), this); createAction(SELECTIVE_ROLLBACK, ICONS.ROLLBACK, tr("Rollback selected cells"), this, SLOT(selectiveRollback()), this); + createAction(GENERATE_SELECT, "SELECT", this, SLOT(generateSelect()), this); + createAction(GENERATE_INSERT, "INSERT", this, SLOT(generateInsert()), this); + createAction(GENERATE_UPDATE, "UPDATE", this, SLOT(generateUpdate()), this); + createAction(GENERATE_DELETE, "DELETE", this, SLOT(generateDelete()), this); createAction(SORT_DIALOG, ICONS.SORT_COLUMNS, tr("Define columns to sort by"), this, SLOT(openSortDialog()), this); createAction(RESET_SORTING, ICONS.SORT_RESET, tr("Remove custom sorting"), this, SLOT(resetSorting()), this); createAction(INSERT_ROW, ICONS.INSERT_ROW, tr("Insert row"), this, SIGNAL(requestForRowInsert()), this); @@ -141,11 +147,22 @@ void SqlQueryView::setupActionsForMenu(SqlQueryItem* currentItem, const QListaddSeparator(); } - if (selectedItems.size() == 1 && selectedItems.first() == currentItem) + if (selCount == 1 && selectedItems.first() == currentItem) addFkActionsToContextMenu(currentItem); if (selCount > 0) { + QMenu* generateQueryMenu = contextMenu->addMenu(ICONS.GENERATE_QUERY, tr("Generate query for selected cells")); + generateQueryMenu->addAction(actionMap[GENERATE_SELECT]); + if (getModel()->supportsModifyingQueriesInMenu()) + { + generateQueryMenu->addAction(actionMap[GENERATE_INSERT]); + generateQueryMenu->addAction(actionMap[GENERATE_UPDATE]); + generateQueryMenu->addAction(actionMap[GENERATE_DELETE]); + } + + + contextMenu->addSeparator(); contextMenu->addAction(actionMap[COPY]); //contextMenu->addAction(actionMap[COPY_AS]); // TODO uncomment when implemented contextMenu->addAction(actionMap[PASTE]); @@ -233,6 +250,9 @@ QModelIndex SqlQueryView::getCurrentIndex() const void SqlQueryView::itemActivated(const QModelIndex& index) { + if (simpleBrowserMode) + return; + if (!index.isValid()) return; @@ -246,6 +266,31 @@ void SqlQueryView::itemActivated(const QModelIndex& index) edit(getCurrentIndex()); } +void SqlQueryView::generateSelect() +{ + QString sql = getModel()->generateSelectQueryForItems(getSelectedItems()); + MAINWINDOW->openSqlEditor(getModel()->getDb(), sql); + +} + +void SqlQueryView::generateInsert() +{ + QString sql = getModel()->generateInsertQueryForItems(getSelectedItems()); + MAINWINDOW->openSqlEditor(getModel()->getDb(), sql); +} + +void SqlQueryView::generateUpdate() +{ + QString sql = getModel()->generateUpdateQueryForItems(getSelectedItems()); + MAINWINDOW->openSqlEditor(getModel()->getDb(), sql); +} + +void SqlQueryView::generateDelete() +{ + QString sql = getModel()->generateDeleteQueryForItems(getSelectedItems()); + MAINWINDOW->openSqlEditor(getModel()->getDb(), sql); +} + bool SqlQueryView::editInEditorIfNecessary(SqlQueryItem* item) { if (item->getColumn()->dataType.getType() == DataType::BLOB) @@ -258,6 +303,9 @@ bool SqlQueryView::editInEditorIfNecessary(SqlQueryItem* item) void SqlQueryView::paste(const QList >& data) { + if (simpleBrowserMode) + return; + QList selectedItems = getSelectedItems(); if (selectedItems.isEmpty()) { @@ -345,23 +393,27 @@ void SqlQueryView::goToReferencedRow(const QString& table, const QString& column if (!db || !db->isValid()) return; - EditorWindow* win = MAINWINDOW->openSqlEditor(); - if (!win->setCurrentDb(db)) - { - qCritical() << "Created EditorWindow had not got requested database:" << db->getName(); - win->close(); - return; - } - - static QString sql = QStringLiteral("SELECT * FROM %1 WHERE %2 = %3"); + static_qstring(sqlTpl, "SELECT * FROM %1 WHERE %2 = %3"); QString valueStr = wrapValueIfNeeded(value.toString()); + EditorWindow* win = MAINWINDOW->openSqlEditor(db, sqlTpl.arg(table, column, valueStr)); + if (!win) + return; win->getMdiWindow()->rename(tr("Referenced row (%1)").arg(table)); - win->setContents(sql.arg(table, column, valueStr)); win->execute(); } +bool SqlQueryView::getSimpleBrowserMode() const +{ + return simpleBrowserMode; +} + +void SqlQueryView::setSimpleBrowserMode(bool value) +{ + simpleBrowserMode = value; +} + void SqlQueryView::updateCommitRollbackActions(bool enabled) { actionMap[COMMIT]->setEnabled(enabled); @@ -370,6 +422,9 @@ void SqlQueryView::updateCommitRollbackActions(bool enabled) void SqlQueryView::customContextMenuRequested(const QPoint& pos) { + if (simpleBrowserMode) + return; + SqlQueryItem* currentItem = getCurrentItem(); QList selectedItems = getSelectedItems(); @@ -386,6 +441,9 @@ void SqlQueryView::customContextMenuRequested(const QPoint& pos) void SqlQueryView::headerContextMenuRequested(const QPoint& pos) { + if (simpleBrowserMode) + return; + headerContextMenu->popup(horizontalHeader()->mapToGlobal(pos)); } @@ -438,6 +496,9 @@ void SqlQueryView::setCurrentRow(int row) void SqlQueryView::copy() { + if (simpleBrowserMode) + return; + QList selectedItems = getSelectedItems(); QList > groupedItems = SqlQueryModel::groupItemsByRows(selectedItems); @@ -454,7 +515,11 @@ void SqlQueryView::copy() foreach (SqlQueryItem* item, itemsInRows) { itemValue = item->getFullValue(); - cells << itemValue.toString(); + if (itemValue.userType() == QVariant::Double) + cells << doubleToString(itemValue.toDouble()); + else + cells << itemValue.toString(); + theDataRow << itemValue; } @@ -483,6 +548,9 @@ void SqlQueryView::copy() void SqlQueryView::paste() { + if (simpleBrowserMode) + return; + const QMimeData* mimeData = qApp->clipboard()->mimeData(); if (mimeData->hasFormat(mimeDataId)) { @@ -529,6 +597,9 @@ void SqlQueryView::pasteAs() void SqlQueryView::setNull() { + if (simpleBrowserMode) + return; + for (SqlQueryItem* selItem : getSelectedItems()) { if (selItem->getColumn()->editionForbiddenReason.size() > 0) continue; @@ -539,6 +610,9 @@ void SqlQueryView::setNull() void SqlQueryView::erase() { + if (simpleBrowserMode) + return; + for (SqlQueryItem* selItem : getSelectedItems()) { if (selItem->getColumn()->editionForbiddenReason.size() > 0) continue; @@ -549,26 +623,41 @@ void SqlQueryView::erase() void SqlQueryView::commit() { + if (simpleBrowserMode) + return; + getModel()->commit(); } void SqlQueryView::rollback() { + if (simpleBrowserMode) + return; + getModel()->rollback(); } void SqlQueryView::selectiveCommit() { + if (simpleBrowserMode) + return; + getModel()->commit(getSelectedItems()); } void SqlQueryView::selectiveRollback() { + if (simpleBrowserMode) + return; + getModel()->rollback(getSelectedItems()); } void SqlQueryView::openValueEditor(SqlQueryItem* item) { + if (simpleBrowserMode) + return; + if (!item) { qWarning() << "Tried to open value editor while there's no current item. It should not be called in that case."; diff --git a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlqueryview.h b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlqueryview.h index a1c84bb..b0df4d7 100644 --- a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlqueryview.h +++ b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlqueryview.h @@ -5,6 +5,7 @@ #include "common/extactioncontainer.h" #include "db/queryexecutor.h" #include "guiSQLiteStudio_global.h" +#include "common/table.h" #include class SqlQueryItemDelegate; @@ -53,7 +54,11 @@ class GUI_API_EXPORT SqlQueryView : public QTableView, public ExtActionContainer SELECTIVE_ROLLBACK, OPEN_VALUE_EDITOR, SORT_DIALOG, - RESET_SORTING + RESET_SORTING, + GENERATE_SELECT, + GENERATE_INSERT, + GENERATE_UPDATE, + GENERATE_DELETE }; enum ToolBar @@ -70,6 +75,8 @@ class GUI_API_EXPORT SqlQueryView : public QTableView, public ExtActionContainer QToolBar* getToolBar(int toolbar) const; void addAdditionalAction(QAction* action); QModelIndex getCurrentIndex() const; + bool getSimpleBrowserMode() const; + void setSimpleBrowserMode(bool value); private: void init(); @@ -94,6 +101,7 @@ class GUI_API_EXPORT SqlQueryView : public QTableView, public ExtActionContainer QPushButton* cancelButton = nullptr; QProgressBar* busyBar = nullptr; QList additionalActions; + bool simpleBrowserMode = false; private slots: void updateCommitRollbackActions(bool enabled); @@ -104,6 +112,10 @@ class GUI_API_EXPORT SqlQueryView : public QTableView, public ExtActionContainer void sortingUpdated(const QueryExecutor::SortList& sortOrder); void updateFont(); void itemActivated(const QModelIndex& index); + void generateSelect(); + void generateInsert(); + void generateUpdate(); + void generateDelete(); public slots: void executionStarted(); diff --git a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqltablemodel.cpp b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqltablemodel.cpp index 7b858e6..20c878b 100644 --- a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqltablemodel.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqltablemodel.cpp @@ -5,6 +5,7 @@ #include #include #include +#include SqlTableModel::SqlTableModel(QObject *parent) : SqlQueryModel(parent) @@ -139,6 +140,11 @@ bool SqlTableModel::commitDeletedRow(const QList& itemsInRow) return true; } +bool SqlTableModel::supportsModifyingQueriesInMenu() const +{ + return true; +} + void SqlTableModel::applySqlFilter(const QString& value) { if (value.isEmpty()) @@ -192,6 +198,38 @@ void SqlTableModel::resetFilter() executeQuery(); } +QString SqlTableModel::generateSelectQueryForItems(const QList& items) +{ + QHash values = toValuesGroupedByColumns(items); + + QueryGenerator generator; + return generator.generateSelectFromTable(db, database, table, values); +} + +QString SqlTableModel::generateInsertQueryForItems(const QList& items) +{ + QHash values = toValuesGroupedByColumns(items); + + QueryGenerator generator; + return generator.generateInsertToTable(db, database, table, values); +} + +QString SqlTableModel::generateUpdateQueryForItems(const QList& items) +{ + QHash values = toValuesGroupedByColumns(items); + + QueryGenerator generator; + return generator.generateUpdateOfTable(db, database, table, values); +} + +QString SqlTableModel::generateDeleteQueryForItems(const QList& items) +{ + QHash values = toValuesGroupedByColumns(items); + + QueryGenerator generator; + return generator.generateDeleteFromTable(db, database, table, values); +} + void SqlTableModel::updateRowAfterInsert(const QList& itemsInRow, const QList& modelColumns, RowId rowId) { Dialect dialect = db->getDialect(); diff --git a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqltablemodel.h b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqltablemodel.h index 8b76acc..da43b03 100644 --- a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqltablemodel.h +++ b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqltablemodel.h @@ -19,6 +19,11 @@ class GUI_API_EXPORT SqlTableModel : public SqlQueryModel void applyStringFilter(const QString& value); void applyRegExpFilter(const QString& value); void resetFilter(); + QString generateSelectQueryForItems(const QList& items); + QString generateInsertQueryForItems(const QList& items); + QString generateUpdateQueryForItems(const QList& items); + QString generateDeleteQueryForItems(const QList& items); + bool supportsModifyingQueriesInMenu() const; protected: bool commitAddedRow(const QList& itemsInRow); diff --git a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlviewmodel.cpp b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlviewmodel.cpp new file mode 100644 index 0000000..653e4b5 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlviewmodel.cpp @@ -0,0 +1,20 @@ +#include "sqlviewmodel.h" +#include "querygenerator.h" + +SqlViewModel::SqlViewModel(QObject *parent) : + SqlQueryModel(parent) +{ +} + +QString SqlViewModel::generateSelectQueryForItems(const QList& items) +{ + QHash values = toValuesGroupedByColumns(items); + + QueryGenerator generator; + return generator.generateSelectFromView(db, view, values); +} + +void SqlViewModel::setView(const QString& view) +{ + this->view = view; +} diff --git a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlviewmodel.h b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlviewmodel.h new file mode 100644 index 0000000..19efbce --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlviewmodel.h @@ -0,0 +1,18 @@ +#ifndef SQLVIEWMODEL_H +#define SQLVIEWMODEL_H + +#include "sqlquerymodel.h" + +class SqlViewModel : public SqlQueryModel +{ + public: + SqlViewModel(QObject *parent = 0); + + QString generateSelectQueryForItems(const QList& items); + void setView(const QString& view); + + private: + QString view; +}; + +#endif // SQLVIEWMODEL_H diff --git a/SQLiteStudio3/guiSQLiteStudio/dataview.cpp b/SQLiteStudio3/guiSQLiteStudio/dataview.cpp index f2aba69..69ca9cd 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dataview.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dataview.cpp @@ -75,6 +75,7 @@ void DataView::initSlots() connect(model, SIGNAL(totalRowsAndPagesAvailable()), this, SLOT(totalRowsAndPagesAvailable())); connect(gridView->horizontalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(columnsHeaderClicked(int))); connect(this, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int))); + connect(model, SIGNAL(itemEditionEnded(SqlQueryItem*)), this, SLOT(adjustColumnWidth(SqlQueryItem*))); } void DataView::initFormView() @@ -265,10 +266,15 @@ void DataView::resizeColumnsInitiallyToContents() { int cols = gridView->model()->columnCount(); gridView->resizeColumnsToContents(); + int wd; for (int i = 0; i < cols ; i++) { - if (gridView->columnWidth(i) > CFG_UI.General.MaxInitialColumnWith.get()) + wd = gridView->columnWidth(i); + if (wd > CFG_UI.General.MaxInitialColumnWith.get()) gridView->setColumnWidth(i, CFG_UI.General.MaxInitialColumnWith.get()); + else if (wd < 60) + gridView->setColumnWidth(i, 60); + } } @@ -524,6 +530,17 @@ void DataView::hideGridCommitCover() QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); } +void DataView::adjustColumnWidth(SqlQueryItem* item) +{ + if (!item) + return; + + int col = item->column(); + gridView->resizeColumnToContents(col); + if (gridView->columnWidth(col) > CFG_UI.General.MaxInitialColumnWith.get()) + gridView->setColumnWidth(col, CFG_UI.General.MaxInitialColumnWith.get()); +} + void DataView::updateCommitRollbackActions(bool enabled) { gridView->getAction(SqlQueryView::COMMIT)->setEnabled(enabled); diff --git a/SQLiteStudio3/guiSQLiteStudio/dataview.h b/SQLiteStudio3/guiSQLiteStudio/dataview.h index ce1b982..fcab9f2 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dataview.h +++ b/SQLiteStudio3/guiSQLiteStudio/dataview.h @@ -9,6 +9,7 @@ class QToolBar; class SqlQueryView; class SqlQueryModel; +class SqlQueryItem; class FormView; class ExtLineEdit; class QLabel; @@ -203,6 +204,7 @@ class GUI_API_EXPORT DataView : public QTabWidget, public ExtActionContainer void coverForGridCommit(int total); void updateGridCommitCover(int value); void hideGridCommitCover(); + void adjustColumnWidth(SqlQueryItem* item); }; int qHash(DataView::ActionGroup action); diff --git a/SQLiteStudio3/guiSQLiteStudio/dbobjectdialogs.cpp b/SQLiteStudio3/guiSQLiteStudio/dbobjectdialogs.cpp index 25686b5..43af10e 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dbobjectdialogs.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dbobjectdialogs.cpp @@ -227,6 +227,113 @@ bool DbObjectDialogs::dropObject(const QString& database, const QString& name) return true; } +bool DbObjectDialogs::dropObjects(const QStringList& names) +{ + QHash objects; + objects["main"] = names; + return dropObjects(objects); +} + +QHash> DbObjectDialogs::groupObjects(const QHash& objects) +{ + QHash> groupedObjects; + for (QHash::const_iterator it = objects.begin(); it != objects.end(); ++it) + { + for (const QString& name : it.value()) + { + QString typeForSql; + switch (getObjectType(it.key(), name)) + { + case Type::TABLE: + typeForSql = "TABLE"; + break; + case Type::INDEX: + typeForSql = "INDEX"; + break; + case Type::TRIGGER: + typeForSql = "TRIGGER"; + break; + case Type::VIEW: + typeForSql = "VIEW"; + break; + default: + { + qCritical() << "Unknown object type while trying to drop object. Object name:" << it.key() << "." << name; + return QHash>(); + } + } + groupedObjects[it.key()][typeForSql] << name; + } + } + return groupedObjects; +} + +bool DbObjectDialogs::dropObjects(const QHash& objects) +{ + static const QString dropSql2 = "DROP %1 IF EXISTS %2;"; + static const QString dropSql3 = "DROP %1 IF EXISTS %2.%3;"; + + Dialect dialect = db->getDialect(); + QStringList names = concat(objects.values()); + QHash> groupedObjects = groupObjects(objects); + + if (!noConfirmation) + { + QMessageBox::StandardButton resp = QMessageBox::question(parentWidget, tr("Delete objects"), + tr("Are you sure you want to delete following objects:\n%1").arg(names.join(", "))); + if (resp != QMessageBox::Yes) + return false; + } + + if (!db->begin()) + { + notifyError(tr("Cannot start transaction. Details: %1").arg(db->getErrorText())); + return false; + } + + // Iterate through dbNames, then through db object types and finally through object names. Drop them. + SqlQueryPtr results; + QString finalSql; + QString dbName; + QHash typeToNames; + for (QHash>::const_iterator dbIt = groupedObjects.begin(); dbIt != groupedObjects.end(); ++dbIt) + { + dbName = wrapObjIfNeeded(dbIt.key(), dialect); + typeToNames = dbIt.value(); + for (QHash::const_iterator typeIt = typeToNames.begin(); typeIt != typeToNames.end(); ++typeIt) + { + for (const QString& name : typeIt.value()) + { + if (dialect == Dialect::Sqlite3) + finalSql = dropSql3.arg(typeIt.key(), dbName, wrapObjIfNeeded(name, dialect)); + else + finalSql = dropSql2.arg(typeIt.key(), wrapObjIfNeeded(name, dialect)); + + results = db->exec(finalSql); + if (results->isError()) + { + notifyError(tr("Error while dropping %1: %2").arg(name).arg(results->getErrorText())); + qCritical() << "Error while dropping object " << dbIt.key() << "." << name << ":" << results->getErrorText(); + return false; + } + + CFG->addDdlHistory(finalSql, db->getName(), db->getPath()); + } + } + } + + if (!db->commit()) + { + notifyError(tr("Cannot commit transaction. Details: %1").arg(db->getErrorText())); + return false; + } + + if (!noSchemaRefreshing) + DBTREE->refreshSchema(db); + + return true; +} + DbObjectDialogs::Type DbObjectDialogs::getObjectType(const QString& database, const QString& name) { static const QString typeSql = "SELECT type FROM %1.sqlite_master WHERE name = ?;"; diff --git a/SQLiteStudio3/guiSQLiteStudio/dbobjectdialogs.h b/SQLiteStudio3/guiSQLiteStudio/dbobjectdialogs.h index f9a36ee..5be09cc 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dbobjectdialogs.h +++ b/SQLiteStudio3/guiSQLiteStudio/dbobjectdialogs.h @@ -39,6 +39,8 @@ class GUI_API_EXPORT DbObjectDialogs : public QObject void editObject(const QString& database, const QString& name); bool dropObject(const QString& name); bool dropObject(const QString& database, const QString& name); + bool dropObjects(const QStringList& names); + bool dropObjects(const QHash& objects); bool getNoConfirmation() const; void setNoConfirmation(bool value); @@ -57,6 +59,7 @@ class GUI_API_EXPORT DbObjectDialogs : public QObject }; Type getObjectType(const QString& database, const QString& name); + QHash > groupObjects(const QHash& objects); Db* db = nullptr; QWidget* parentWidget = nullptr; diff --git a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtree.cpp b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtree.cpp index 62d7368..fbe0a38 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtree.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtree.cpp @@ -24,6 +24,9 @@ #include "services/importmanager.h" #include "windows/editorwindow.h" #include "uiconfig.h" +#include "themetuner.h" +#include "dialogs/dbconverterdialog.h" +#include "querygenerator.h" #include #include #include @@ -34,8 +37,7 @@ #include #include #include -#include -#include +#include CFG_KEYS_DEFINE(DbTree) QHash> DbTree::allowedTypesInside; @@ -140,6 +142,10 @@ void DbTree::createActions() createAction(REFRESH_SCHEMAS, ICONS.DATABASE_RELOAD, tr("Refresh all database schemas"), this, SLOT(refreshSchemas()), this); createAction(REFRESH_SCHEMA, ICONS.DATABASE_RELOAD, tr("Refresh selected database schema"), this, SLOT(refreshSchema()), this); createAction(ERASE_TABLE_DATA, ICONS.ERASE_TABLE_DATA, tr("Erase table data"), this, SLOT(eraseTableData()), this); + createAction(GENERATE_SELECT, "SELECT", this, SLOT(generateSelectForTable()), this); + createAction(GENERATE_INSERT, "INSERT", this, SLOT(generateInsertForTable()), this); + createAction(GENERATE_UPDATE, "UPDATE", this, SLOT(generateUpdateForTable()), this); + createAction(GENERATE_DELETE, "DELETE", this, SLOT(generateDeleteForTable()), this); } void DbTree::updateActionStates(const QStandardItem *item) @@ -194,6 +200,7 @@ void DbTree::updateActionStates(const QStandardItem *item) case DbTreeItem::Type::TABLE: enabled << EDIT_TABLE << DEL_TABLE << EXPORT_TABLE << IMPORT_TABLE << POPULATE_TABLE << ADD_COLUMN << CREATE_SIMILAR_TABLE; enabled << RESET_AUTOINCREMENT << ADD_INDEX << ADD_TRIGGER << ERASE_TABLE_DATA; + enabled << GENERATE_SELECT << GENERATE_INSERT << GENERATE_UPDATE << GENERATE_DELETE; break; case DbTreeItem::Type::VIRTUAL_TABLE: // TODO change below when virtual tables can be edited @@ -329,6 +336,12 @@ void DbTree::setupActionsForMenu(DbTreeItem* currItem, QMenu* contextMenu) groupEntry += RENAME_GROUP; groupEntry += DELETE_GROUP; + ActionEntry genQueryEntry(ICONS.GENERATE_QUERY, tr("Generate query for table")); + genQueryEntry += GENERATE_SELECT; + genQueryEntry += GENERATE_INSERT; + genQueryEntry += GENERATE_UPDATE; + genQueryEntry += GENERATE_DELETE; + if (currItem) { DbTreeItem* parentItem = currItem->parentDbTreeItem(); @@ -392,6 +405,7 @@ void DbTree::setupActionsForMenu(DbTreeItem* currItem, QMenu* contextMenu) actions += ActionEntry(ADD_INDEX); actions += ActionEntry(ADD_TRIGGER); actions += ActionEntry(_separator); + actions += genQueryEntry; actions += ActionEntry(IMPORT_TABLE); actions += ActionEntry(EXPORT_TABLE); actions += ActionEntry(POPULATE_TABLE); @@ -635,11 +649,13 @@ bool DbTree::areDbTreeItemsValidForItem(QList srcItems, const DbTre for (DbTreeItem* srcItem : srcItems) { - if (srcItem) - srcTypes << srcItem->getType(); - else + if (!srcItem) + { srcTypes << DbTreeItem::Type::ITEM_PROTOTYPE; + continue; + } + srcTypes << srcItem->getType(); if (srcItem->getDb()) srcDbs << srcItem->getDb(); } @@ -653,6 +669,18 @@ bool DbTree::areDbTreeItemsValidForItem(QList srcItems, const DbTre return false; } + // Support for d&d reordering of db objects + static const QHash reorderingTypeToParent = { + {DbTreeItem::Type::TABLE, DbTreeItem::Type::TABLES}, + {DbTreeItem::Type::TRIGGER, DbTreeItem::Type::TRIGGERS}, + {DbTreeItem::Type::VIEW, DbTreeItem::Type::VIEWS}, + {DbTreeItem::Type::INDEX, DbTreeItem::Type::INDEXES} + }; + + if (srcTypes.toSet().size() == 1 && srcDbs.size() == 1 && dstItem && *(srcDbs.begin()) == dstItem->getDb() && reorderingTypeToParent[srcTypes.first()] == dstType) + return true; + + // No other d&d within same db if (dstItem && dstItem->getDb() && srcDbs.contains(dstItem->getDb())) return false; @@ -706,6 +734,16 @@ Db* DbTree::getSelectedDb() return item->getDb(); } +QSet DbTree::getSelectedDatabases() +{ + QList items = ui->treeView->selectionItems(); + QSet dbList; + for (DbTreeItem* item : items) + dbList << item->getDb(); + + return dbList; +} + Db* DbTree::getSelectedOpenDb() { Db* db = getSelectedDb(); @@ -872,6 +910,72 @@ void DbTree::deleteItem(DbTreeItem* item) } } +void DbTree::deleteSelected(DbTreeItem::Type itemType) +{ + deleteSelected([itemType](DbTreeItem* item) + { + return item->getType() == itemType; + }); +} + +QHash> DbTree::groupByDb(const QList items) +{ + QHash> grouped; + for (DbTreeItem* item : items) + grouped[item->getDb()] << item; + + return grouped; +} + +QStringList DbTree::itemsToNames(const QList& items) +{ + QStringList names; + for (DbTreeItem* item : items) + names << item->text(); + + return names; +} + +QString DbTree::getSelectedTableName() const +{ + DbTreeItem* item = ui->treeView->currentItem(); + QString table = item->getTable(); + if (table.isNull()) + return QString(); + + return table; +} + +QString DbTree::getSelectedIndexName() const +{ + DbTreeItem* item = ui->treeView->currentItem(); + QString idx = item->getIndex(); + if (idx.isNull()) + return QString(); + + return idx; +} + +QString DbTree::getSelectedTriggerName() const +{ + DbTreeItem* item = ui->treeView->currentItem(); + QString trig = item->getTrigger(); + if (trig.isNull()) + return QString(); + + return trig; +} + +QString DbTree::getSelectedViewName() const +{ + DbTreeItem* item = ui->treeView->currentItem(); + QString view= item->getView(); + if (view.isNull()) + return QString(); + + return view; +} + void DbTree::refreshSchema(Db* db) { @@ -1012,15 +1116,29 @@ void DbTree::editDb() void DbTree::removeDb() { - Db* db = getSelectedDb(); - if (!db) + QList dbList = getSelectedDatabases().toList(); + if (dbList.isEmpty()) return; - QMessageBox::StandardButton result = QMessageBox::question(this, tr("Delete database"), tr("Are you sure you want to delete database '%1'?").arg(db->getName().left(ITEM_TEXT_LIMIT))); + QString msg; + if (dbList.size() == 1) + { + msg = tr("Are you sure you want to remove database '%1' from the list?").arg(dbList.first()->getName().left(ITEM_TEXT_LIMIT)); + } + else + { + QStringList dbNames; + for (Db* db : dbList) + dbNames << db->getName().left(ITEM_TEXT_LIMIT); + + msg = tr("Are you sure you want to remove following databases from the list:\n%1").arg(dbNames.join(",\n")); + } + QMessageBox::StandardButton result = QMessageBox::question(this, tr("Remove database"), msg); if (result != QMessageBox::Yes) return; - DBLIST->removeDb(db); + for (Db* db : dbList) + DBLIST->removeDb(db); } void DbTree::connectToDb() @@ -1097,8 +1215,7 @@ void DbTree::editTable() if (!db || !db->isValid()) return; - DbTreeItem* item = ui->treeView->currentItem(); - QString table = item->getTable(); + QString table = getSelectedTableName(); if (table.isNull()) { qWarning() << "Tried to edit table, while table wasn't selected in DbTree."; @@ -1110,20 +1227,7 @@ void DbTree::editTable() void DbTree::delTable() { - Db* db = getSelectedOpenDb(); - if (!db || !db->isValid()) - return; - - DbTreeItem* item = ui->treeView->currentItem(); - QString table = item->getTable(); - if (table.isNull()) - { - qWarning() << "Tried to drop table, while table wasn't selected in DbTree."; - return; - } - - DbObjectDialogs dialogs(db); - dialogs.dropObject(table); // TODO add database prefix when supported + deleteSelected(DbTreeItem::Type::TABLE); } void DbTree::addIndex() @@ -1145,8 +1249,7 @@ void DbTree::editIndex() if (!db || !db->isValid()) return; - DbTreeItem* item = ui->treeView->currentItem(); - QString index = item->getIndex(); + QString index = getSelectedIndexName(); DbObjectDialogs dialogs(db); dialogs.editIndex(index); @@ -1154,7 +1257,7 @@ void DbTree::editIndex() void DbTree::delIndex() { - delSelectedObject(); + deleteSelected(DbTreeItem::Type::INDEX); } void DbTree::addTrigger() @@ -1177,8 +1280,7 @@ void DbTree::editTrigger() if (!db || !db->isValid()) return; - DbTreeItem* item = ui->treeView->currentItem(); - QString trigger = item->getTrigger(); + QString trigger = getSelectedTriggerName(); DbObjectDialogs dialogs(db); dialogs.editTrigger(trigger); @@ -1186,7 +1288,7 @@ void DbTree::editTrigger() void DbTree::delTrigger() { - delSelectedObject(); + deleteSelected(DbTreeItem::Type::TRIGGER); } void DbTree::addView() @@ -1205,8 +1307,7 @@ void DbTree::editView() if (!db || !db->isValid()) return; - DbTreeItem* item = ui->treeView->currentItem(); - QString view = item->getView(); + QString view = getSelectedViewName(); if (view.isNull()) { qWarning() << "Tried to edit view, while view wasn't selected in DbTree."; @@ -1218,7 +1319,7 @@ void DbTree::editView() void DbTree::delView() { - delSelectedObject(); + deleteSelected(DbTreeItem::Type::VIEW); } void DbTree::exportTable() @@ -1334,11 +1435,12 @@ void DbTree::vacuumDb() if (!db || !db->isValid()) return; - SqlQueryPtr res = db->exec("VACUUM;"); - if (res->isError()) - notifyError(tr("Error while executing VACUUM on the database %1: %2").arg(db->getName(), res->getErrorText())); - else - notifyInfo(tr("VACUUM execution finished successfully.")); + EditorWindow* win = MAINWINDOW->openSqlEditor(db, "VACUUM;"); + if (!win) + return; + + win->getMdiWindow()->rename(tr("Vacuum (%1)").arg(db->getName())); + win->execute(); } void DbTree::integrityCheck() @@ -1347,16 +1449,11 @@ void DbTree::integrityCheck() if (!db || !db->isValid()) return; - EditorWindow* win = MAINWINDOW->openSqlEditor(); - if (!win->setCurrentDb(db)) - { - qCritical() << "Created EditorWindow had not got requested database:" << db->getName(); - win->close(); + EditorWindow* win = MAINWINDOW->openSqlEditor(db, "PRAGMA integrity_check;"); + if (!win) return; - } win->getMdiWindow()->rename(tr("Integrity check (%1)").arg(db->getName())); - win->setContents("PRAGMA integrity_check;"); win->execute(); } @@ -1493,12 +1590,19 @@ void DbTree::currentChanged(const QModelIndex ¤t, const QModelIndex &previ updateActionStates(treeModel->itemFromIndex(current)); } -void DbTree::deleteSelected() +void DbTree::deleteSelected(ItemFilterFunc filterFunc) { QModelIndexList idxList = ui->treeView->getSelectedIndexes(); QList items; - foreach (const QModelIndex& idx, idxList) - items << dynamic_cast(treeModel->itemFromIndex(idx)); + DbTreeItem* item; + for (const QModelIndex& idx : idxList) + { + item = dynamic_cast(treeModel->itemFromIndex(idx)); + if (filterFunc && !filterFunc(item)) + continue; + + items << item; + } deleteItems(items); } @@ -1615,6 +1719,36 @@ void DbTree::refreshFont() ui->treeView->doItemsLayout(); } +void DbTree::generateSelectForTable() +{ + Db* db = getSelectedDb(); + QString table = getSelectedTableName(); + + QueryGenerator generator; + QString sql = generator.generateSelectFromTable(db, table); + MAINWINDOW->openSqlEditor(db, sql); +} + +void DbTree::generateInsertForTable() +{ + Db* db = getSelectedDb(); + QString table = getSelectedTableName(); + + QueryGenerator generator; + QString sql = generator.generateInsertToTable(db, table); + MAINWINDOW->openSqlEditor(db, sql); +} + +void DbTree::generateUpdateForTable() +{ + +} + +void DbTree::generateDeleteForTable() +{ + +} + void DbTree::setupDefShortcuts() { setShortcutContext({ diff --git a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtree.h b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtree.h index 2f5583e..ea415a4 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtree.h +++ b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtree.h @@ -7,6 +7,7 @@ #include "dbtree/dbtreeitem.h" #include "guiSQLiteStudio_global.h" #include +#include class WidgetCover; class QAction; @@ -85,6 +86,10 @@ class GUI_API_EXPORT DbTree : public QDockWidget, public ExtActionContainer CREATE_SIMILAR_TABLE, RESET_AUTOINCREMENT, ERASE_TABLE_DATA, + GENERATE_SELECT, + GENERATE_UPDATE, + GENERATE_INSERT, + GENERATE_DELETE, _separator // Never use it directly, it's just for menu setup }; @@ -111,6 +116,7 @@ class GUI_API_EXPORT DbTree : public QDockWidget, public ExtActionContainer QToolBar* getToolBar(int toolbar) const; Db* getSelectedDb(); Db* getSelectedOpenDb(); + QSet getSelectedDatabases(); static bool isItemDraggable(const DbTreeItem* item); @@ -120,6 +126,8 @@ class GUI_API_EXPORT DbTree : public QDockWidget, public ExtActionContainer void closeEvent(QCloseEvent* e); private: + typedef std::function ItemFilterFunc; + void setActionEnabled(int action, bool enabled); TableWindow* openTable(DbTreeItem* item); TableWindow* openTable(Db* db, const QString& database, const QString& table); @@ -133,9 +141,16 @@ class GUI_API_EXPORT DbTree : public QDockWidget, public ExtActionContainer void filterUndeletableItems(QList& items); void filterItemsWithParentInList(QList& items); void deleteItem(DbTreeItem* item); + void deleteSelected(DbTreeItem::Type itemType); + QHash> groupByDb(const QList items); + QStringList itemsToNames(const QList& items); + QString getSelectedTableName() const; + QString getSelectedIndexName() const; + QString getSelectedTriggerName() const; + QString getSelectedViewName() const; + static bool areDbTreeItemsValidForItem(QList srcItems, const DbTreeItem* dstItem); static bool areUrlsValidForItem(const QList& srcUrls, const DbTreeItem* dstItem); - static void initDndTypes(); Ui::DbTree *ui = nullptr; @@ -194,13 +209,17 @@ class GUI_API_EXPORT DbTree : public QDockWidget, public ExtActionContainer void editColumn(DbTreeItem* item); void delColumn(DbTreeItem* item); void currentChanged(const QModelIndex & current, const QModelIndex & previous); - void deleteSelected(); + void deleteSelected(ItemFilterFunc filterFunc = nullptr); void deleteItems(const QList& itemsToDelete); void refreshSchema(); void dbConnected(Db* db); void dbDisconnected(Db* db); void updateDbIcon(Db* db); void refreshFont(); + void generateSelectForTable(); + void generateInsertForTable(); + void generateUpdateForTable(); + void generateDeleteForTable(); }; int qHash(DbTree::Action action); diff --git a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.cpp b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.cpp index c0f527f..c11221d 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.cpp @@ -13,6 +13,7 @@ #include "dialogs/errorsconfirmdialog.h" #include "dialogs/versionconvertsummarydialog.h" #include "db/invaliddb.h" +#include "services/notifymanager.h" #include #include #include @@ -1040,7 +1041,10 @@ bool DbTreeModel::dropDbTreeItem(const QList& srcItems, DbTreeItem* return false; if (srcItem->getDb() == dstItem->getDb()) + { + invokeStdDropAction = true; return true; + } return dropDbObjectItem(srcItems, dstItem, defaultAction); } @@ -1135,6 +1139,8 @@ QCheckBox* DbTreeModel::createCopyOrMoveMenuCheckBox(QMenu* menu, const QString& bool DbTreeModel::dropUrls(const QList& urls) { + QString filePath; + bool autoTest = false; for (const QUrl& url : urls) { if (!url.isLocalFile()) @@ -1143,13 +1149,41 @@ bool DbTreeModel::dropUrls(const QList& urls) continue; } + autoTest = false; + filePath = url.toLocalFile(); + if (CFG_UI.General.BypassDbDialogWhenDropped.get()) + { + if (quickAddDroppedDb(filePath)) + { + continue; + } + else + { + notifyWarn(tr("Could not add dropped database file '%1' automatically. Manual setup is necessary.").arg(filePath)); + autoTest = true; + } + } + DbDialog dialog(DbDialog::ADD, MAINWINDOW); - dialog.setPath(url.toLocalFile()); + dialog.setPath(filePath); + dialog.setDoAutoTest(autoTest); dialog.exec(); } return false; } +bool DbTreeModel::quickAddDroppedDb(const QString& filePath) +{ + DbPlugin* plugin = DBLIST->getPluginForDbFile(filePath); + if (!plugin) + return false; + + QString name = DBLIST->generateUniqueDbName(plugin, filePath); + QHash opts; + opts[DB_PLUGIN] = plugin->getName(); + return DBLIST->addDb(name, filePath, opts, !CFG_UI.General.NewDbNotPermanentByDefault.get()); +} + void DbTreeModel::moveOrCopyDbObjects(const QList& srcItems, DbTreeItem* dstItem, bool move, bool includeData, bool includeIndexes, bool includeTriggers) { if (srcItems.size() == 0) diff --git a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.h b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.h index ee97e87..122421a 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.h +++ b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.h @@ -85,6 +85,7 @@ class GUI_API_EXPORT DbTreeModel : public QStandardItemModel bool dropDbObjectItem(const QList& srcItems, DbTreeItem* dstItem, Qt::DropAction defaultAction); QCheckBox* createCopyOrMoveMenuCheckBox(QMenu* menu, const QString& label); bool dropUrls(const QList& urls); + bool quickAddDroppedDb(const QString& filePath); void moveOrCopyDbObjects(const QList& srcItems, DbTreeItem* dstItem, bool move, bool includeData, bool includeIndexes, bool includeTriggers); static bool confirmReferencedTables(const QStringList& tables); diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialog.cpp index f4e48fe..14cb06b 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialog.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialog.cpp @@ -33,8 +33,8 @@ void ColumnDialog::init() limitDialogWidth(this); setWindowIcon(ICONS.COLUMN); - ui->scale->setStrict(true); - ui->precision->setStrict(true); + ui->scale->setStrict(true, true); + ui->precision->setStrict(true, true); ui->typeCombo->addItem(""); foreach (DataType::Enum type, DataType::getAllTypes()) @@ -52,8 +52,11 @@ void ColumnDialog::init() connect(ui->constraintsView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(updateConstraintsToolbarState())); connect(ui->constraintsView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(editConstraint(QModelIndex))); - connect(constraintsModel, SIGNAL(constraintsChanged()), this, SLOT(updateConstraints())); + connect(constraintsModel, SIGNAL(constraintsChanged()), this, SLOT(updateValidations())); connect(constraintsModel, SIGNAL(constraintsChanged()), this, SLOT(updateState())); + connect(ui->typeCombo, SIGNAL(currentTextChanged(const QString&)), this, SLOT(updateValidations())); + connect(ui->scale, SIGNAL(modified()), this, SLOT(updateValidations())); + connect(ui->precision, SIGNAL(modified()), this, SLOT(updateValidations())); connect(ui->pkButton, SIGNAL(clicked()), this, SLOT(configurePk())); connect(ui->fkButton, SIGNAL(clicked()), this, SLOT(configureFk())); @@ -214,7 +217,7 @@ void ColumnDialog::editConstraint(SqliteCreateTable::Column::Constraint* constra ui->constraintsView->resizeColumnToContents(0); ui->constraintsView->resizeColumnToContents(1); - updateConstraints(); + updateValidations(); } void ColumnDialog::delConstraint(const QModelIndex& idx) @@ -377,6 +380,44 @@ bool ColumnDialog::isUnofficialSqlite2Constraint(SqliteCreateTable::Column::Cons return false; } +void ColumnDialog::updateTypeValidations() +{ + QString scaleErrorMsg = tr("Scale is not allowed for INTEGER PRIMARY KEY columns."); + QString precisionErrorMsg = tr("Precision cannot be defined without the scale."); + + QVariant scale = ui->scale->getValue(); + QVariant precision = ui->precision->getValue(); + + bool scaleDefined = !scale.toString().isEmpty(); + bool precisionDefined = !precision.toString().isEmpty(); + + bool precisionOk = !(precisionDefined && !scaleDefined); + bool scaleOk = true; + + bool hasPk = column->getConstraint(SqliteCreateTable::Column::Constraint::PRIMARY_KEY) != nullptr; + bool isInteger = ui->typeCombo->currentText().toUpper() == "INTEGER"; + if (hasPk && isInteger) + { + if (scaleDefined) + scaleOk = false; + + if (precisionDefined) + { + precisionOk = false; + precisionErrorMsg = tr("Precision is not allowed for INTEGER PRIMARY KEY columns."); + } + } + + setValidState(ui->scale, scaleOk, scaleErrorMsg); + setValidState(ui->precision, precisionOk, precisionErrorMsg); + + if (!scaleOk || !precisionOk) + { + QPushButton* btn = ui->buttonBox->button(QDialogButtonBox::Ok); + btn->setEnabled(false); + } +} + void ColumnDialog::moveConstraintUp() { QModelIndex idx = ui->constraintsView->currentIndex(); @@ -505,7 +546,7 @@ void ColumnDialog::switchMode(bool advanced) ui->constraintModesWidget->setCurrentWidget(advanced ? ui->advancedPage : ui->simplePage); } -void ColumnDialog::updateConstraints() +void ColumnDialog::updateValidations() { QPushButton* btn = ui->buttonBox->button(QDialogButtonBox::Ok); btn->setEnabled(true); @@ -536,8 +577,10 @@ void ColumnDialog::updateConstraints() setValidState(tb, true); } - foreach (SqliteCreateTable::Column::Constraint* constr, column->constraints) + for (SqliteCreateTable::Column::Constraint* constr : column->constraints) updateConstraint(constr); + + updateTypeValidations(); } void ColumnDialog::updateConstraint(SqliteCreateTable::Column::Constraint* constraint) @@ -564,7 +607,7 @@ void ColumnDialog::setColumn(SqliteCreateTable::Column* value) ui->precision->setValue(value->type->precision, false); } - updateConstraints(); + updateValidations(); } SqliteCreateTable::Column* ColumnDialog::getModifiedColumn() @@ -602,9 +645,13 @@ void ColumnDialog::updateDataType() if (!scaleTxt.isEmpty()) column->type->scale = ui->scale->getValue(); + else + column->type->scale = QVariant(); if (!precisionTxt.isEmpty()) column->type->precision = ui->precision->getValue(); + else + column->type->precision = QVariant(); column->type->rebuildTokens(); } diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialog.h b/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialog.h index c567e1a..596441c 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialog.h +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialog.h @@ -67,6 +67,7 @@ class GUI_API_EXPORT ColumnDialog : public QDialog, public ExtActionContainer QCheckBox* getCheckBoxForConstraint(SqliteCreateTable::Column::Constraint* constraint); QToolButton* getToolButtonForConstraint(SqliteCreateTable::Column::Constraint* constraint); bool isUnofficialSqlite2Constraint(SqliteCreateTable::Column::Constraint* constraint); + void updateTypeValidations(); Ui::ColumnDialog *ui = nullptr; SqliteCreateTable::ColumnPtr column; @@ -105,7 +106,7 @@ class GUI_API_EXPORT ColumnDialog : public QDialog, public ExtActionContainer void notNullToggled(bool enabled); void defaultToggled(bool enabled); void switchMode(bool advanced); - void updateConstraints(); + void updateValidations(); void updateConstraint(SqliteCreateTable::Column::Constraint* constraint); void updateDataType(); }; diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.cpp index 627e2c1..42c7099 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.cpp @@ -168,13 +168,7 @@ void ConfigDialog::init() ui->categoriesTree->setCurrentItem(ui->categoriesTree->topLevelItem(0)); configMapper = new ConfigMapper(CfgMain::getPersistableInstances()); - connect(configMapper, SIGNAL(modified()), this, SLOT(markModified())); - connect(configMapper, &ConfigMapper::notifyEnabledWidgetModified, [=](QWidget* widget, CfgEntry* key, const QVariant& value) - { - UNUSED(widget); - for (ConfigNotifiablePlugin* plugin : notifiablePlugins) - plugin->configModified(key, value); - }); + connectMapperSignals(configMapper); ui->categoriesFilter->setClearButtonEnabled(true); UserInputFilter* filter = new UserInputFilter(ui->categoriesFilter, this, SLOT(applyFilter(QString))); @@ -575,6 +569,12 @@ void ConfigDialog::commitPluginConfigs() } } +void ConfigDialog::connectMapperSignals(ConfigMapper* mapper) +{ + connect(mapper, SIGNAL(modified()), this, SLOT(markModified())); + connect(mapper, SIGNAL(notifyEnabledWidgetModified(QWidget*, CfgEntry*, const QVariant&)), this, SLOT(notifyPluginsAboutModification(QWidget*, CfgEntry*, const QVariant&))); +} + void ConfigDialog::updateDataTypeListState() { bool listEditingEnabled = ui->dataEditorsTypesList->selectedItems().size() > 0 && ui->dataEditorsTypesList->currentItem()->flags().testFlag(Qt::ItemIsEditable); @@ -952,6 +952,12 @@ void ConfigDialog::markRequiresSchemasRefresh() requiresSchemasRefresh = true; } +void ConfigDialog::notifyPluginsAboutModification(QWidget*, CfgEntry* key, const QVariant& value) +{ + for (ConfigNotifiablePlugin* plugin : notifiablePlugins) + plugin->configModified(key, value); +} + void ConfigDialog::updatePluginCategoriesVisibility(QTreeWidgetItem* categoryItem) { categoryItem->setHidden(categoryItem->childCount() == 0); @@ -1325,7 +1331,12 @@ bool ConfigDialog::initPluginPage(Plugin* plugin, bool skipConfigLoading) { pluginConfigMappers[cfgPlugin] = new ConfigMapper(mainConfig); pluginConfigMappers[cfgPlugin]->bindToConfig(widget); + connectMapperSignals(pluginConfigMappers[cfgPlugin]); mainConfig->begin(); + + // Remove this config from global mapper (if present there), so it's handled per plugin mapper + configMapper->removeMainCfgEntry(mainConfig); + configMapper->ignoreWidget(widget); } else if (!skipConfigLoading) { @@ -1342,7 +1353,7 @@ void ConfigDialog::deinitPluginPage(Plugin* plugin) if (!nameToPage.contains(pluginName)) return; - if (!dynamic_cast(plugin)) + if (dynamic_cast(plugin)) { UiConfiguredPlugin* cfgPlugin = dynamic_cast(plugin); CfgMain* mainCfg = cfgPlugin->getMainUiConfig(); @@ -1360,6 +1371,7 @@ void ConfigDialog::deinitPluginPage(Plugin* plugin) QWidget* widget = nameToPage[pluginName]; nameToPage.remove(pluginName); + configMapper->removeIgnoredWidget(widget); ui->stackedWidget->removeWidget(widget); delete widget; } diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.h b/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.h index ae2f3a7..f0ab1de 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.h +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.h @@ -84,6 +84,7 @@ class GUI_API_EXPORT ConfigDialog : public QDialog void addDataType(const QString& typeStr); void rollbackPluginConfigs(); void commitPluginConfigs(); + void connectMapperSignals(ConfigMapper* mapper); Ui::ConfigDialog *ui = nullptr; QStyle* previewStyle = nullptr; @@ -136,6 +137,7 @@ class GUI_API_EXPORT ConfigDialog : public QDialog void updateBuiltInPluginsVisibility(); void applyShortcutsFilter(const QString& filter); void markRequiresSchemasRefresh(); + void notifyPluginsAboutModification(QWidget*, CfgEntry* key, const QVariant& value); public slots: void accept(); diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.ui b/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.ui index 1c5515d..c69ad20 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.ui +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.ui @@ -14,16 +14,6 @@ Configuration - - - - Qt::Horizontal - - - QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - @@ -173,23 +163,15 @@ - Plugins + Database list - pluginsPage + databaseListPage - :/icons/img/plugin.png:/icons/img/plugin.png + :/icons/img/database_online.png:/icons/img/database_online.png - - - Code formatters - - - formatterPluginsPage - - @@ -215,6 +197,26 @@ + + + Plugins + + + pluginsPage + + + + :/icons/img/plugin.png:/icons/img/plugin.png + + + + Code formatters + + + formatterPluginsPage + + + @@ -227,68 +229,116 @@ - 0 + 5 - - + + - + - Data browsing and editing + Database list - - - + + + + + If switched off, then columns will be sorted in the order they are typed in CREATE TABLE statement. + - Number of data rows per page: + Sort table columns alphabetically + + + General.SortColumns - - - - - 150 - 16777215 - - - - 1 - - - 99999 + + + + Expand tables node when connected to a database - General.NumberOfRowsPerPage + General.ExpandTables - - + + - <p>When the data is read into grid view columns width is automatically adjusted. This value limits the initial width for the adjustment, but user can still resize the column manually over this limit.</p> + <p>Additional labels are those displayed next to the names on the databases list (they are blue, unless configured otherwise). Enabling this option will result in labels for databases, invalid databases and aggregated nodes (column group, index group, trigger group). For more labels see options below.<p> + + + Display additional labels on the list + + + true + + + false + + + General.ShowDbTreeLabels + + + + + For regular tables labels will show number of columns, indexes and triggers for each of tables. + + + Display labels for regular tables + + + General.ShowRegularTableLabels + + + + + + + Virtual tables will be marked with a 'virtual' label. + + + Display labels for virtual tables + + + General.ShowVirtualTableLabels + + + + + + + + - Limit initial data column width to (in pixels): + Expand views node when connected to a database + + + General.ExpandViews - - + + - <p>When the data is read into grid view columns width is automatically adjusted. This value limits the initial width for the adjustment, but user can still resize the column manually over this limit.</p> + If this option is switched off, then objects will be sorted in order they appear in sqlite_master table (which is in order they were created) - - 10 + + Sort objects (tables, indexes, triggers and views) alphabetically - - 99999 + + General.SortObjects - - 600 + + + + + + Display system tables and indexes on the list - General.MaxInitialColumnWith + General.ShowSystemObjects @@ -296,50 +346,34 @@ - + - Inserting new row in data grid + Database dialog window - + - - - Before currently selected row - - - true - - - 0 - - - General.InsertRowPlacement + + + <p>When adding new database it is marked to be "permanent" (stored in configuration) by default. Checking this option makes every new database to NOT be "permanent" by default.</p> - - - - - After currently selected row - - - 1 + Do not mark database to be "permanent" by default - General.InsertRowPlacement + General.NewDbNotPermanentByDefault - - - At the end of data view + + + <p>When this option is enabled, then files dropped from file manager onto database list will be automatically added to the list, bypassing standard database dialog. If for various reasons automatic process fails, then standard dialog will be presented to the user.</p> - - 2 + + Try to bypass dialog completly when dropping database file onto the list - General.InsertRowPlacement + General.BypassDbDialogWhenDropped @@ -347,7 +381,7 @@ - + Qt::Vertical @@ -361,6 +395,240 @@ + + + + + + true + + + + + 0 + 0 + 564 + 504 + + + + + + + Data browsing and editing + + + + + + Number of data rows per page: + + + + + + + + 150 + 16777215 + + + + 1 + + + 99999 + + + General.NumberOfRowsPerPage + + + + + + + <p>When the data is read into grid view columns width is automatically adjusted. This value limits the initial width for the adjustment, but user can still resize the column manually over this limit.</p> + + + Limit initial data column width to (in pixels): + + + + + + + <p>When the data is read into grid view columns width is automatically adjusted. This value limits the initial width for the adjustment, but user can still resize the column manually over this limit.</p> + + + 10 + + + 99999 + + + 600 + + + General.MaxInitialColumnWith + + + + + + + <p>When this is enabled and user holds mouse pointer over a cell in any data view (query results, a table data, a view data) a tooltip will appear with details about the cell - it includes details like column data type, constraints, ROWID and others.</p> + + + Show column and row details tooltip in data view + + + General.ShowDataViewTooltips + + + + + + + + + + Inserting new row in data grid + + + + + + Before currently selected row + + + true + + + 0 + + + General.InsertRowPlacement + + + + + + + After currently selected row + + + 1 + + + General.InsertRowPlacement + + + + + + + At the end of data view + + + 2 + + + General.InsertRowPlacement + + + + + + + + + + Table windows + + + + + + <p>When enabled, Table Windows will show up with the data tab, instead of the structure tab.</p> + + + Open Table Windows with the data tab for start + + + General.OpenTablesOnData + + + + + + + <p>When enabled the "Data" tab will be placed as first tab in every Table Window, instead of being at second place.</p> + + + Place data tab as first tab in a Table Window + + + General.DataTabAsFirstInTables + + + + + + + + + + View windows + + + + + + <p>When enabled, View Windows will show up with the data tab, instead of the structure tab.</p> + + + Open View Windows with the data tab for start + + + General.OpenViewsOnData + + + + + + + <p>When enabled the "Data" tab will be placed as first tab in every View Window, instead of being at second place.</p> + + + Place data tab as first tab in a View Window + + + General.DataTabAsFirstInViews + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + @@ -597,6 +865,28 @@ + + + + Status Field + + + + + + <p>When user manually closes the Status panel, this option makes sure that if any new message is printed in the Status panel it will be reopened. If it's disabled, then Status panel can only be open manually by the user from the "View" menu.</p> + + + Always open Status panel when new message is printed + + + General.AutoOpenStatusField + + + + + + @@ -711,8 +1001,8 @@ 0 0 - 456 - 608 + 596 + 487 @@ -757,163 +1047,7 @@ true - General.CompactLayout - - - - - - - - - - Database list - - - - - - If switched off, then columns will be sorted in the order they are typed in CREATE TABLE statement. - - - Sort table columns alphabetically - - - General.SortColumns - - - - - - - Expand tables node when connected to a database - - - General.ExpandTables - - - - - - - <p>Additional labels are those displayed next to the names on the databases list (they are blue, unless configured otherwise). Enabling this option will result in labels for databases, invalid databases and aggregated nodes (column group, index group, trigger group). For more labels see options below.<p> - - - Display additional labels on the list - - - true - - - false - - - General.ShowDbTreeLabels - - - - - - For regular tables labels will show number of columns, indexes and triggers for each of tables. - - - Display labels for regular tables - - - General.ShowRegularTableLabels - - - - - - - Virtual tables will be marked with a 'virtual' label. - - - Display labels for virtual tables - - - General.ShowVirtualTableLabels - - - - - - - - - - Expand views node when connected to a database - - - General.ExpandViews - - - - - - - If this option is switched off, then objects will be sorted in order they appear in sqlite_master table (which is in order they were created) - - - Sort objects (tables, indexes, triggers and views) alphabetically - - - General.SortObjects - - - - - - - Display system tables and indexes on the list - - - General.ShowSystemObjects - - - - - - - - - - Table windows - - - - - - When enabled, Table Windows will show up with the data tab, instead of the structure tab. - - - Open Table Windows with the data tab for start - - - General.OpenTablesOnData - - - - - - - - - - View windows - - - - - - When enabled, View Windows will show up with the data tab, instead of the structure tab. - - - Open View Windows with the data tab for start - - - General.OpenViewsOnData + General.CompactLayout @@ -966,6 +1100,19 @@ + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -1275,7 +1422,7 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'.Helvetica Neue DeskInterface'; font-size:13pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Sans Serif'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Abcdefgh</span></p></body></html> @@ -1366,8 +1513,8 @@ p, li { white-space: pre-wrap; } 0 0 - 249 - 322 + 290 + 323 @@ -1488,8 +1635,8 @@ p, li { white-space: pre-wrap; } 0 0 - 329 - 813 + 352 + 806 @@ -2012,6 +2159,16 @@ p, li { white-space: pre-wrap; } + + + + Qt::Horizontal + + + QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/dbdialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/dbdialog.cpp index a3d0e65..6bdf41f 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/dbdialog.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/dbdialog.cpp @@ -102,6 +102,9 @@ void DbDialog::showEvent(QShowEvent *e) updateOptions(); updateState(); + if (doAutoTest) + testConnectionClicked(); + QDialog::showEvent(e); } @@ -133,6 +136,9 @@ void DbDialog::init() generateNameSwitched(true); layout()->setSizeConstraint(QLayout::SetFixedSize); + + if (mode == Mode::ADD && CFG_UI.General.NewDbNotPermanentByDefault.get()) + ui->permamentCheckBox->setChecked(false); } void DbDialog::updateOptions() @@ -396,32 +402,11 @@ void DbDialog::updateType() if (disableTypeAutodetection) return; - QFileInfo file(ui->fileEdit->text()); - if (!file.exists() || file.isDir()) + DbPlugin* validPlugin = SQLITESTUDIO->getDbManager()->getPluginForDbFile(ui->fileEdit->text()); + if (!validPlugin || validPlugin->getLabel() == ui->typeCombo->currentText()) return; - QString currentPluginLabel = ui->typeCombo->currentText(); - QList validPlugins; - QHash options; - QString path = ui->fileEdit->text(); - Db* probeDb = nullptr; - for (DbPlugin* plugin : dbPlugins) - { - probeDb = plugin->getInstance("", path, options); - if (probeDb) - { - delete probeDb; - probeDb = nullptr; - - if (plugin->getLabel() == currentPluginLabel) - return; // current plugin is among valid plugins, no need to change anything - - validPlugins << plugin; - } - } - - if (validPlugins.size() > 0) - ui->typeCombo->setCurrentText(validPlugins.first()->getLabel()); + ui->typeCombo->setCurrentText(validPlugin->getLabel()); } QHash DbDialog::collectOptions() @@ -486,10 +471,9 @@ bool DbDialog::validate() } } - Db* registeredDb = DBLIST->getByName(ui->nameEdit->text()); + Db* registeredDb = DBLIST->getByName(ui->nameEdit->text(), Qt::CaseInsensitive); if (registeredDb && (mode == Mode::ADD || registeredDb != db)) { - qDebug() << ui->generateCheckBox->isChecked(); setValidState(ui->nameEdit, false, tr("This name is already in use. Please enter unique name.")); return false; } @@ -534,6 +518,11 @@ void DbDialog::updateState() ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(validate()); } +void DbDialog::setDoAutoTest(bool value) +{ + doAutoTest = value; +} + void DbDialog::propertyChanged() { ui->testConnIcon->setVisible(false); @@ -543,7 +532,7 @@ void DbDialog::typeChanged(int index) { UNUSED(index); updateOptions(); - updateState(); + valueForNameGenerationChanged(); } void DbDialog::valueForNameGenerationChanged() @@ -552,13 +541,16 @@ void DbDialog::valueForNameGenerationChanged() if (!ui->generateCheckBox->isChecked()) return; + QString generatedName; if (dbPlugins.count() > 0) { DbPlugin* plugin = dbPlugins[ui->typeCombo->currentText()]; - QString generatedName = plugin->generateDbName(ui->fileEdit->text()); - generatedName = generateUniqueName(generatedName, existingDatabaseNames); - ui->nameEdit->setText(generatedName); + generatedName = DBLIST->generateUniqueDbName(plugin, ui->fileEdit->text()); } + else + generatedName = DBLIST->generateUniqueDbName(ui->fileEdit->text()); + + ui->nameEdit->setText(generatedName); } void DbDialog::browseForFile() diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/dbdialog.h b/SQLiteStudio3/guiSQLiteStudio/dialogs/dbdialog.h index ce73b11..2beea3e 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/dbdialog.h +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/dbdialog.h @@ -39,6 +39,7 @@ class GUI_API_EXPORT DbDialog : public QDialog QString getName(); QHash collectOptions(); bool isPermanent(); + void setDoAutoTest(bool value); protected: void changeEvent(QEvent *e); @@ -68,6 +69,7 @@ class GUI_API_EXPORT DbDialog : public QDialog QWidget* lastWidgetInTabOrder = nullptr; DbPluginOption::CustomBrowseHandler customBrowseHandler = nullptr; bool disableTypeAutodetection = false; + bool doAutoTest = false; static const constexpr int ADDITIONAL_ROWS_BEGIN_INDEX = 1; diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/exportdialog.ui b/SQLiteStudio3/guiSQLiteStudio/dialogs/exportdialog.ui index 333d887..186114b 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/exportdialog.ui +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/exportdialog.ui @@ -6,8 +6,8 @@ 0 0 - 515 - 414 + 614 + 493 @@ -289,8 +289,8 @@ 0 0 - 483 - 318 + 308 + 267 diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/indexdialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/indexdialog.cpp index cdae91d..c5da317 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/indexdialog.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/indexdialog.cpp @@ -1,7 +1,6 @@ #include "indexdialog.h" #include "ui_indexdialog.h" #include "schemaresolver.h" -#include "parser/ast/sqliteindexedcolumn.h" #include "services/notifymanager.h" #include "common/utils_sql.h" #include "db/chainexecutor.h" @@ -11,6 +10,7 @@ #include "services/config.h" #include "uiutils.h" #include "sqlite3.h" +#include "indexexprcolumndialog.h" #include "windows/editorwindow.h" #include "services/codeformatter.h" #include @@ -40,6 +40,7 @@ IndexDialog::IndexDialog(Db* db, const QString& index, QWidget* parent) : IndexDialog::~IndexDialog() { + clearColumns(); delete ui; } @@ -67,20 +68,34 @@ void IndexDialog::init() return; } + ui->moveUpButton->setIcon(ICONS.MOVE_UP); + ui->moveDownButton->setIcon(ICONS.MOVE_DOWN); + ui->addExprColumnButton->setIcon(ICONS.INDEX_EXPR_ADD); + ui->editExprColumnButton->setIcon(ICONS.INDEX_EXPR_EDIT); + ui->delExprColumnButton->setIcon(ICONS.INDEX_EXPR_DEL); + connect(ui->moveUpButton, SIGNAL(clicked()), this, SLOT(moveColumnUp())); + connect(ui->moveDownButton, SIGNAL(clicked()), this, SLOT(moveColumnDown())); + connect(ui->addExprColumnButton, SIGNAL(clicked()), this, SLOT(addExprColumn())); + connect(ui->editExprColumnButton, SIGNAL(clicked()), this, SLOT(editExprColumn())); + connect(ui->delExprColumnButton, SIGNAL(clicked()), this, SLOT(delExprColumn())); + connect(ui->columnsTable, SIGNAL(cellDoubleClicked(int,int)), this, SLOT(editExprColumn(int))); + ui->columnsTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + connect(ui->columnsTable->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)), this, SLOT(updateToolBarButtons(QModelIndex))); ui->partialIndexEdit->setDb(db); connect(ui->tabWidget, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int))); columnStateSignalMapping = new QSignalMapper(this); - connect(columnStateSignalMapping, SIGNAL(mapped(int)), this, SLOT(updateColumnState(int))); + connect(columnStateSignalMapping, SIGNAL(mapped(QString)), this, SLOT(updateColumnState(QString))); SchemaResolver resolver(db); ui->tableCombo->addItem(QString::null); ui->tableCombo->addItems(resolver.getTables()); connect(ui->tableCombo, SIGNAL(currentTextChanged(QString)), this, SLOT(updateTable(QString))); connect(ui->tableCombo, SIGNAL(currentTextChanged(QString)), this, SLOT(updateValidation())); + connect(ui->uniqueCheck, SIGNAL(toggled(bool)), this, SLOT(updateValidation())); if (existingIndex) ui->tableCombo->setEnabled(false); @@ -98,6 +113,9 @@ void IndexDialog::init() ui->partialIndexCheck->setVisible(false); ui->partialIndexEdit->setVisible(false); ui->columnsTable->setColumnHidden(1, true); + ui->addExprColumnButton->setVisible(false); + ui->editExprColumnButton->setVisible(false); + ui->delExprColumnButton->setVisible(false); } readCollations(); @@ -139,17 +157,17 @@ void IndexDialog::readIndex() void IndexDialog::buildColumns() { // Clean up + clearColumns(); ui->columnsTable->setRowCount(0); - columnCheckBoxes.clear(); - sortComboBoxes.clear(); - collateComboBoxes.clear(); totalColumns = tableColumns.size(); ui->columnsTable->setRowCount(totalColumns); int row = 0; - foreach (const QString& column, tableColumns) + for (const QString& column : tableColumns) buildColumn(column, row++); + + updateToolBarButtons(); } void IndexDialog::updateTable(const QString& value) @@ -166,15 +184,16 @@ void IndexDialog::updateValidation() { bool tableOk = ui->tableCombo->currentIndex() > 0; bool colSelected = false; + bool hasExprColumn = false; if (tableOk) { - foreach (QCheckBox* cb, columnCheckBoxes) + for (Column* col : columns.values()) { - if (cb->isChecked()) + if (col->getCheck()->isChecked()) { colSelected = true; - break; + hasExprColumn |= col->isExpr(); } } } @@ -182,11 +201,14 @@ void IndexDialog::updateValidation() bool partialConditionOk = (!ui->partialIndexCheck->isChecked() || (ui->partialIndexEdit->isSyntaxChecked() && !ui->partialIndexEdit->haveErrors())); + bool uniqueAndExprOk = !(ui->uniqueCheck->isChecked() && hasExprColumn); + + setValidState(ui->uniqueCheck, uniqueAndExprOk, tr("Unique index cannot have indexed expressions. Either remove expressions from list below, or uncheck this option.")); setValidState(ui->tableCombo, tableOk, tr("Pick the table for the index.")); setValidState(ui->columnsTable, colSelected, tr("Select at least one column.")); setValidState(ui->partialIndexCheck, partialConditionOk, tr("Enter a valid condition.")); - ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(colSelected && partialConditionOk); + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(colSelected && partialConditionOk && uniqueAndExprOk); } void IndexDialog::setTable(const QString& value) @@ -207,9 +229,30 @@ void IndexDialog::readCollations() void IndexDialog::buildColumn(const QString& name, int row) { - int col = 0; + Column* column = new Column(name, ui->columnsTable); + buildColumn(column, row); +} + +IndexDialog::Column* IndexDialog::buildColumn(SqliteOrderBy* orderBy, int row) +{ + SqliteExpr* expr = dynamic_cast(orderBy->expr->clone()); + return buildColumn(expr, row); +} + +IndexDialog::Column* IndexDialog::buildColumn(SqliteExpr* expr, int row) +{ + Column* column = new Column(expr, ui->columnsTable); + buildColumn(column, row); + return column; +} - QWidget* checkParent = new QWidget(); +void IndexDialog::buildColumn(Column* column, int row) +{ + QString key = column->getKey(); + columns[key] = column; + columnsByRow << column; + + column->setCheckParent(new QWidget()); QHBoxLayout* layout = new QHBoxLayout(); QMargins margins = layout->contentsMargins(); margins.setTop(0); @@ -217,51 +260,45 @@ void IndexDialog::buildColumn(const QString& name, int row) margins.setLeft(4); margins.setRight(4); layout->setContentsMargins(margins); - checkParent->setLayout(layout); + column->getCheckParent()->setLayout(layout); - QCheckBox* check = new QCheckBox(name); - checkParent->layout()->addWidget(check); + column->setCheck(new QCheckBox(key)); + column->getCheckParent()->layout()->addWidget(column->getCheck()); - ui->columnsTable->setCellWidget(row, col++, checkParent); - columnStateSignalMapping->setMapping(check, row); - connect(check, SIGNAL(toggled(bool)), columnStateSignalMapping, SLOT(map())); - connect(check, SIGNAL(toggled(bool)), this, SLOT(updateValidation())); - columnCheckBoxes << check; + columnStateSignalMapping->setMapping(column->getCheck(), key); + connect(column->getCheck(), SIGNAL(toggled(bool)), columnStateSignalMapping, SLOT(map())); + connect(column->getCheck(), SIGNAL(toggled(bool)), this, SLOT(updateValidation())); - QComboBox* collation = nullptr; if (db->getDialect() == Dialect::Sqlite3) { - collation = new QComboBox(); - collation->setEditable(true); - collation->lineEdit()->setPlaceholderText(tr("default", "index dialog")); - collation->setModel(&collations); - ui->columnsTable->setCellWidget(row, col++, collation); - collateComboBoxes << collation; - } - else - { - col++; + column->setCollation(new QComboBox()); + column->getCollation()->setEditable(true); + column->getCollation()->lineEdit()->setPlaceholderText(tr("default", "index dialog")); + column->getCollation()->setModel(&collations); } - QComboBox* sortOrder = new QComboBox(); - sortOrder->setToolTip(tr("Sort order", "table constraints")); - ui->columnsTable->setCellWidget(row, col++, sortOrder); - sortComboBoxes << sortOrder; + column->setSort(new QComboBox()); + column->getSort()->setToolTip(tr("Sort order", "table constraints")); QStringList sortList = {"", sqliteSortOrder(SqliteSortOrder::ASC), sqliteSortOrder(SqliteSortOrder::DESC)}; - sortOrder->addItems(sortList); + column->getSort()->addItems(sortList); + + column->prepareForNewRow(); + column->assignToNewRow(row); totalColumns++; - updateColumnState(row); + updateColumnState(key); } -void IndexDialog::updateColumnState(int row) +void IndexDialog::updateColumnState(const QString& columnKey) { - bool enabled = columnCheckBoxes[row]->isChecked(); - sortComboBoxes[row]->setEnabled(enabled); - if (db->getDialect() == Dialect::Sqlite3) - collateComboBoxes[row]->setEnabled(enabled); + Column* col = columns[columnKey]; + + bool enabled = col->getCheck()->isChecked(); + col->getSort()->setEnabled(enabled); + if (col->hasCollation()) + col->getCollation()->setEnabled(enabled); } void IndexDialog::updatePartialConditionState() @@ -283,26 +320,204 @@ void IndexDialog::tabChanged(int tab) updateDdl(); } +void IndexDialog::moveColumnUp() +{ + QModelIndex idx = ui->columnsTable->selectionModel()->currentIndex(); + if (!idx.isValid()) + return; + + int row = idx.row(); + if (row <= 0) + return; + + columnsByRow.move(row, row - 1); + rebuildColumnsByNewOrder(); + + idx = ui->columnsTable->model()->index(row - 1, 0); + ui->columnsTable->selectionModel()->setCurrentIndex(idx, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); +} + +void IndexDialog::moveColumnDown() +{ + QModelIndex idx = ui->columnsTable->selectionModel()->currentIndex(); + if (!idx.isValid()) + return; + + int row = idx.row(); + int cols = tableColumns.size(); + + if ((row + 1) >= cols) + return; + + columnsByRow.move(row, row + 1); + rebuildColumnsByNewOrder(); + + idx = ui->columnsTable->model()->index(row + 1, 0); + ui->columnsTable->selectionModel()->setCurrentIndex(idx, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); +} + +void IndexDialog::updateToolBarButtons(const QModelIndex& idx) +{ + if (!idx.isValid()) + { + ui->editExprColumnButton->setEnabled(false); + ui->delExprColumnButton->setEnabled(false); + ui->moveUpButton->setEnabled(false); + ui->moveDownButton->setEnabled(false); + return; + } + + int row = idx.row(); + int cols = tableColumns.size(); + ui->moveUpButton->setEnabled(row > 0); + ui->moveDownButton->setEnabled((row + 1) < cols); + + bool isExpr = columnsByRow[row]->isExpr(); + ui->editExprColumnButton->setEnabled(isExpr); + ui->delExprColumnButton->setEnabled(isExpr); +} + +void IndexDialog::addExprColumn() +{ + IndexExprColumnDialog dialog(db, this); + dialog.setExistingExprColumnKeys(getExistingColumnExprs()); + dialog.setTableColumns(getTableColumns()); + if (!dialog.exec()) + return; + + SqliteExpr* expr = dialog.getColumn(); + if (!expr) + { + qCritical() << "Null expr in IndexDialog::addExprColumn(). Aborting."; + return; + } + + int row = columnsByRow.size(); + ui->columnsTable->insertRow(row); + + Column* col = buildColumn(expr, row); + col->getCheck()->setChecked(true); + rebuildColumnsByNewOrder(); + + ui->columnsTable->scrollToBottom(); + updateValidation(); +} + +void IndexDialog::editExprColumn(int row) +{ + if (row < 0) + row = ui->columnsTable->currentRow(); + + if (row < 0 || row >= columnsByRow.size()) + { + qWarning() << "IndexDialog::editExprColumn() called for row out of bounds:" << row << "while there are" << columnsByRow.size() << "rows."; + return; + } + + Column* col = columnsByRow[row]; + if (!col->isExpr()) + { + qWarning() << "IndexDialog::editExprColumn() called for non-expr index column."; + return; + } + + IndexExprColumnDialog dialog(db, col->getExpr(), this); + dialog.setExistingExprColumnKeys(getExistingColumnExprs(col->getKey())); + dialog.setTableColumns(getTableColumns()); + if (!dialog.exec()) + return; + + SqliteExpr* expr = dialog.getColumn(); + if (!expr) + { + qCritical() << "Null expr in IndexDialog::editExprColumn(). Aborting."; + return; + } + + QString oldKey = col->getKey(); + col->setExpr(expr); + QString newKey = col->getKey(); + + columns.remove(oldKey); + columns[newKey] = col; + + col->getCheck()->setText(newKey); + col->getCheck()->setChecked(true); + rebuildColumnsByNewOrder(); + updateValidation(); +} + +void IndexDialog::delExprColumn() +{ + int row = ui->columnsTable->currentRow(); + + if (row < 0 || row >= columnsByRow.size()) + { + qWarning() << "IndexDialog::delExprColumn() called for row out of bounds:" << row << "while there are" << columnsByRow.size() << "rows."; + return; + } + + Column* col = columnsByRow[row]; + if (!col->isExpr()) + { + qWarning() << "IndexDialog::delExprColumn() called for non-expr index column."; + return; + } + + // Removes all widgets in the row + ui->columnsTable->removeRow(row); + + columnsByRow.removeOne(col); + columns.remove(col->getKey()); + delete col; + + rebuildColumnsByNewOrder(); + updateValidation(); +} + void IndexDialog::applyColumnValues() { - Dialect dialect = db->getDialect(); - int row; - foreach (SqliteIndexedColumn* idxCol, createIndex->indexedColumns) + Column* column = nullptr; + QString key; + int row = 0; + int totalRows = tableColumns.size(); + bool orderChanged = false; + for (SqliteOrderBy* idxCol : createIndex->indexedColumns) { - row = indexOf(tableColumns, idxCol->name, Qt::CaseInsensitive); - if (row == -1) + key = getKey(idxCol); + + if (idxCol->isSimpleColumn()) { - qCritical() << "Cannot find column from index in the table columns! Indexed column:" << idxCol->name - << ", table columns:" << tableColumns << ", index name:" << index << ", table name:" << table; - continue; + column = columns[key]; + if (!column) + { + qCritical() << "Cannot find column by name or expression! Column name/expression:" << key + << ", available columns:" << columns.keys() << ", index name:" << index; + continue; + } + } + else + column = buildColumn(idxCol, totalRows++); + + column->getCheck()->setChecked(true); + updateColumnState(key); + column->getSort()->setCurrentText(sqliteSortOrder(idxCol->order)); + if (column->hasCollation()) + column->getCollation()->setCurrentText(idxCol->getCollation()); + + // Setting proper order + int currentRow = columnsByRow.indexOf(column); + if (currentRow != row) + { + columnsByRow.move(currentRow, row); + orderChanged = true; } - columnCheckBoxes[row]->setChecked(true); - updateColumnState(row); - sortComboBoxes[row]->setCurrentText(sqliteSortOrder(idxCol->sortOrder)); - if (dialect == Dialect::Sqlite3) - collateComboBoxes[row]->setCurrentText(idxCol->collate); + row++; } + + if (orderChanged) + rebuildColumnsByNewOrder(); } void IndexDialog::applyIndex() @@ -315,15 +530,43 @@ void IndexDialog::applyIndex() ui->partialIndexEdit->setPlainText(createIndex->where->detokenize()); } -SqliteIndexedColumn* IndexDialog::addIndexedColumn(const QString& name) +SqliteOrderBy* IndexDialog::addIndexedColumn(const QString& name) +{ + SqliteOrderBy* idxCol = new SqliteOrderBy(); + idxCol->setParent(createIndex.data()); + + SqliteExpr* expr = new SqliteExpr(); + expr->initId(name); + idxCol->expr = expr; + expr->setParent(idxCol); + + createIndex->indexedColumns << idxCol; + return idxCol; +} + +SqliteOrderBy* IndexDialog::addIndexedColumn(SqliteExpr* expr) { - SqliteIndexedColumn* idxCol = new SqliteIndexedColumn(); - idxCol->name = name; + SqliteOrderBy* idxCol = new SqliteOrderBy(); idxCol->setParent(createIndex.data()); + + SqliteExpr* clonedExpr = dynamic_cast(expr->clone()); + idxCol->expr = clonedExpr; + clonedExpr->setParent(idxCol); + createIndex->indexedColumns << idxCol; return idxCol; } +void IndexDialog::addCollation(SqliteOrderBy* col, const QString& name) +{ + SqliteExpr* expr = new SqliteExpr(); + col->expr->setParent(expr); + expr->initCollate(col->expr, name); + expr->setParent(col); + + col->expr = expr; +} + void IndexDialog::rebuildCreateIndex() { createIndex = SqliteCreateIndexPtr::create(); @@ -333,22 +576,22 @@ void IndexDialog::rebuildCreateIndex() createIndex->uniqueKw = ui->uniqueCheck->isChecked(); - Dialect dialect = db->getDialect(); - SqliteIndexedColumn* idxCol = nullptr; - int i = -1; - for (const QString& column : tableColumns) + SqliteOrderBy* idxCol = nullptr; + for (Column* column : columnsByRow) { - i++; - - if (!columnCheckBoxes[i]->isChecked()) + if (!column->getCheck()->isChecked()) continue; - idxCol = addIndexedColumn(column); - if (dialect == Dialect::Sqlite3 && !collateComboBoxes[i]->currentText().isEmpty()) - idxCol->collate = collateComboBoxes[i]->currentText(); + if (column->isExpr()) + idxCol = addIndexedColumn(column->getExpr()); + else + idxCol = addIndexedColumn(column->getName()); + + if (column->hasCollation() && !column->getCollation()->currentText().isEmpty()) + addCollation(idxCol, column->getCollation()->currentText()); - if (sortComboBoxes[i]->currentIndex() > 0) - idxCol->sortOrder = sqliteSortOrder(sortComboBoxes[i]->currentText()); + if (column->getSort()->currentIndex() > 0) + idxCol->order = sqliteSortOrder(column->getSort()->currentText()); } if (ui->partialIndexCheck->isChecked()) @@ -388,10 +631,9 @@ void IndexDialog::queryDuplicates() QStringList countCols; QString wrappedCol; QString countColName; - int i = 0; for (const QString& column : tableColumns) { - if (!columnCheckBoxes[i++]->isChecked()) + if (!columns[column]->getCheck()->isChecked()) continue; wrappedCol = wrapObjIfNeeded(column, dialect); @@ -413,6 +655,62 @@ void IndexDialog::queryDuplicates() editor->execute(); } +void IndexDialog::clearColumns() +{ + for (Column* c : columns.values()) + delete c; + + columns.clear(); + columnsByRow.clear(); +} + +void IndexDialog::rebuildColumnsByNewOrder() +{ + int row = 0; + for (Column* column : columnsByRow) + { + column->prepareForNewRow(); + column->assignToNewRow(row++); + } +} + +QString IndexDialog::getKey(SqliteOrderBy* col) const +{ + if (col->isSimpleColumn()) + return col->getColumnName(); + + return col->expr->tokens.filterWhiteSpaces(false).detokenize(); +} + +QStringList IndexDialog::getExistingColumnExprs(const QString& exceptThis) const +{ + QString key; + QStringList exprs; + for (Column* col : columnsByRow) + { + if (col->isExpr()) + { + key = col->getKey(); + if (!exceptThis.isNull() && key == exceptThis) + continue; + + exprs << key; + } + } + return exprs; +} + +QStringList IndexDialog::getTableColumns() const +{ + QStringList cols; + for (Column* col : columnsByRow) + { + if (!col->isExpr()) + cols << col->getKey(); + } + return cols; +} + void IndexDialog::accept() { rebuildCreateIndex(); @@ -468,3 +766,125 @@ void IndexDialog::accept() .arg(executor.getErrorsMessages().join(",\n")), QMessageBox::Ok); } } + +IndexDialog::Column::Column(const QString& name, QTableWidget* table) +{ + this->name = name; + this->table = table; +} + +IndexDialog::Column::Column(SqliteExpr* expr, QTableWidget* table) +{ + this->expr = expr; + this->table = table; +} + +IndexDialog::Column::~Column() +{ + safe_delete(expr); +} + +void IndexDialog::Column::assignToNewRow(int row) +{ + table->setCellWidget(row, 0, column1Contrainer); + table->setCellWidget(row, 1, column2Contrainer); + table->setCellWidget(row, 2, column3Contrainer); +} + +void IndexDialog::Column::prepareForNewRow() +{ + column1Contrainer = defineContainer(checkParent); + column2Contrainer = defineContainer(sort); + if (collation) + column3Contrainer = defineContainer(collation); +} + +QCheckBox* IndexDialog::Column::getCheck() const +{ + return check; +} + +void IndexDialog::Column::setCheck(QCheckBox* cb) +{ + check = cb; +} + +QWidget* IndexDialog::Column::getCheckParent() const +{ + return checkParent; +} + +void IndexDialog::Column::setCheckParent(QWidget* w) +{ + checkParent = w; +} + +QComboBox* IndexDialog::Column::getSort() const +{ + return sort; +} + +void IndexDialog::Column::setSort(QComboBox* cb) +{ + sort = cb; +} + +QComboBox* IndexDialog::Column::getCollation() const +{ + return collation; +} + +void IndexDialog::Column::setCollation(QComboBox* cb) +{ + collation = cb; +} + +bool IndexDialog::Column::hasCollation() const +{ + return collation != nullptr; +} + +QString IndexDialog::Column::getName() const +{ + return name; +} + +SqliteExpr* IndexDialog::Column::getExpr() const +{ + return expr; +} + +void IndexDialog::Column::setExpr(SqliteExpr* expr) +{ + safe_delete(this->expr); + this->expr = expr; +} + +bool IndexDialog::Column::isExpr() const +{ + return expr != nullptr; +} + +QString IndexDialog::Column::getKey() const +{ + if (expr) + return expr->tokens.filterWhiteSpaces(false).detokenize(); + else + return name; +} + +QWidget* IndexDialog::Column::defineContainer(QWidget* w) +{ + QHBoxLayout* layout = new QHBoxLayout(); + QMargins margins = layout->contentsMargins(); + margins.setTop(0); + margins.setBottom(0); + margins.setLeft(0); + margins.setRight(0); + layout->setContentsMargins(margins); + + QWidget* container = new QWidget(); + container->setLayout(layout); + container->layout()->addWidget(w); + return container; +} diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/indexdialog.h b/SQLiteStudio3/guiSQLiteStudio/dialogs/indexdialog.h index 1f9d1f8..f29b651 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/indexdialog.h +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/indexdialog.h @@ -4,6 +4,7 @@ #include "db/db.h" #include "guiSQLiteStudio_global.h" #include "parser/ast/sqlitecreateindex.h" +#include "common/strhash.h" #include #include @@ -15,6 +16,7 @@ class QGridLayout; class QSignalMapper; class QCheckBox; class QComboBox; +class QTableWidget; class GUI_API_EXPORT IndexDialog : public QDialog { @@ -31,15 +33,65 @@ class GUI_API_EXPORT IndexDialog : public QDialog void changeEvent(QEvent *e); private: + class Column + { + public: + Column(const QString& name, QTableWidget* table); + Column(SqliteExpr* expr, QTableWidget* table); + ~Column(); + + void assignToNewRow(int row); + void prepareForNewRow(); + QCheckBox* getCheck() const; + void setCheck(QCheckBox* cb); + QWidget* getCheckParent() const; + void setCheckParent(QWidget* w); + QComboBox* getSort() const; + void setSort(QComboBox* cb); + QComboBox* getCollation() const; + void setCollation(QComboBox* cb); + bool hasCollation() const; + + QString getName() const; + SqliteExpr* getExpr() const; + void setExpr(SqliteExpr* expr); + bool isExpr() const; + QString getKey() const; + + private: + QWidget* defineContainer(QWidget* w); + + QWidget* column1Contrainer = nullptr; + QWidget* column2Contrainer = nullptr; + QWidget* column3Contrainer = nullptr; + QWidget* checkParent = nullptr; + QCheckBox* check = nullptr; + QComboBox* sort = nullptr; + QComboBox* collation = nullptr; + QTableWidget* table = nullptr; + QString name; + SqliteExpr* expr = nullptr; + }; + void init(); void readIndex(); void readCollations(); void buildColumn(const QString& name, int row); + Column* buildColumn(SqliteOrderBy* orderBy, int row); + Column* buildColumn(SqliteExpr* expr, int row); + void buildColumn(Column* column, int row); void applyColumnValues(); void applyIndex(); - SqliteIndexedColumn* addIndexedColumn(const QString& name); + SqliteOrderBy* addIndexedColumn(const QString& name); + SqliteOrderBy* addIndexedColumn(SqliteExpr* expr); + void addCollation(SqliteOrderBy* col, const QString& name); void rebuildCreateIndex(); void queryDuplicates(); + void clearColumns(); + void rebuildColumnsByNewOrder(); + QString getKey(SqliteOrderBy* col) const; + QStringList getExistingColumnExprs(const QString& exceptThis = QString()) const; + QStringList getTableColumns() const; bool existingIndex = false; Db* db = nullptr; @@ -50,9 +102,8 @@ class GUI_API_EXPORT IndexDialog : public QDialog QStringList tableColumns; QSignalMapper* columnStateSignalMapping = nullptr; QStringListModel collations; - QList columnCheckBoxes; - QList sortComboBoxes; - QList collateComboBoxes; + StrHash columns; + QList columnsByRow; int totalColumns = 0; Ui::IndexDialog *ui = nullptr; @@ -60,10 +111,16 @@ class GUI_API_EXPORT IndexDialog : public QDialog void updateValidation(); void buildColumns(); void updateTable(const QString& value); - void updateColumnState(int row); + void updateColumnState(const QString& columnKey); void updatePartialConditionState(); void updateDdl(); void tabChanged(int tab); + void moveColumnUp(); + void moveColumnDown(); + void updateToolBarButtons(const QModelIndex& idx = QModelIndex()); + void addExprColumn(); + void editExprColumn(int row = -1); + void delExprColumn(); public slots: void accept(); diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/indexdialog.ui b/SQLiteStudio3/guiSQLiteStudio/dialogs/indexdialog.ui index 4e2cbac..36066c5 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/indexdialog.ui +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/indexdialog.ui @@ -30,45 +30,10 @@ Index - - - - On table: - - - - - - - Index name: - - - - - - - Partial index condition - - - - - - - - 0 - 1 - - - - - - - - Unique index - - + + - + @@ -76,8 +41,23 @@ 2 + + false + + + true + + + QAbstractItemView::NoDragDrop + + + Qt::IgnoreAction + - QAbstractItemView::NoSelection + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows QAbstractItemView::ScrollPerPixel @@ -102,12 +82,97 @@ - - + + + + On table: + + - + + + + + Delete selected indexed expression + + + + + + + + + + Moves selected index column up in the order, making it more significant in the index. + + + + + + + + + + Moves selected index column down in the order, making it less significant in the index. + + + + + + + + + + Partial index condition + + + + + + + Unique index + + + + + + + Index name: + + + + + + + Edit selected indexed expression + + + + + + + + + + + 0 + 1 + + + + + + + + Add indexed expression + + + + + + diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/indexexprcolumndialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/indexexprcolumndialog.cpp new file mode 100644 index 0000000..f041294 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/indexexprcolumndialog.cpp @@ -0,0 +1,151 @@ +#include "indexexprcolumndialog.h" +#include "ui_indexexprcolumndialog.h" +#include "parser/ast/sqliteexpr.h" +#include "db/db.h" +#include "uiutils.h" +#include "parser/parser.h" +#include "parser/ast/sqliteselect.h" +#include + +IndexExprColumnDialog::IndexExprColumnDialog(Db* db, QWidget* parent) : + QDialog(parent), + ui(new Ui::IndexExprColumnDialog) +{ + ui->setupUi(this); + + this->db = db; + ui->sqlEditor->setDb(db); + ui->sqlEditor->setVirtualSqlExpression("CREATE INDEX idx ON tab (%1 COLLATE NOCASE ASC)"); + + connect(ui->sqlEditor, SIGNAL(textChanged()), this, SLOT(validate())); + connect(ui->sqlEditor, SIGNAL(errorsChecked(bool)), this, SLOT(validate())); +} + +IndexExprColumnDialog::IndexExprColumnDialog(Db* db, SqliteExpr* col, QWidget *parent) : + IndexExprColumnDialog(db, parent) +{ + readColumn(col); +} + +IndexExprColumnDialog::~IndexExprColumnDialog() +{ + delete ui; +} + +void IndexExprColumnDialog::readColumn(SqliteExpr* col) +{ + ui->sqlEditor->setPlainText(col->tokens.detokenize()); +} + +void IndexExprColumnDialog::setOkEnabled(bool enabled) +{ + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(enabled); +} + +SqliteExpr* IndexExprColumnDialog::parseExpr() +{ + Parser parser(db->getDialect()); + return parser.parseExpr(ui->sqlEditor->toPlainText()); +} + +bool IndexExprColumnDialog::checkRestrictions(QString& errorMsg) +{ + SqliteExprPtr expr = SqliteExprPtr(parseExpr()); + if (!expr) + return false; + + QString key = expr->tokens.filterWhiteSpaces(false).detokenize(); + if (existingExprColumnKeys.contains(key)) + { + errorMsg = tr("This expression is already indexed by the index."); + return false; + } + + if (tableColumns.contains(key)) + { + errorMsg = tr("Column should be indexed directly, not by expression. Either extend this expression to contain something more " + "than just column name, or abort and select this column in index dialog directly."); + return false; + } + + QStringList usedColumns = expr->getContextColumns(false, true); + for (const QString& col : usedColumns) + { + if (!tableColumns.contains(col)) + { + errorMsg = tr("Column '%1' does not belong to the table covered by this index. Indexed expressions can refer only to columns from the indexed table.").arg(col); + return false; + } + } + + QList selects = expr->getAllTypedStatements(); + if (!selects.isEmpty()) + { + errorMsg = tr("It's forbidden to use 'SELECT' statements in indexed expressions."); + return false; + } + + return true; +} + +void IndexExprColumnDialog::setExistingExprColumnKeys(const QStringList& value) +{ + existingExprColumnKeys = value; +} + +void IndexExprColumnDialog::setTableColumns(const QStringList& value) +{ + tableColumns = value; +} + +void IndexExprColumnDialog::validate() +{ + if (!ui->sqlEditor->isSyntaxChecked()) + { + setValidState(ui->sqlEditor, false, tr("Enter an indexed expression.")); + setOkEnabled(false); + return; + } + + // First check if we already validated this text. + // This method is called twice, by both errorsChecked() and textChanged(). + QString text = ui->sqlEditor->toPlainText(); + if (!lastValidatedText.isNull() && lastValidatedText == text) + return; + + lastValidatedText = text; + + bool exprOk = !ui->sqlEditor->toPlainText().trimmed().isEmpty() && !ui->sqlEditor->haveErrors(); + QString errorMsg = tr("Invalid expression."); + if (exprOk) + exprOk = checkRestrictions(errorMsg); + + setValidState(ui->sqlEditor, exprOk, errorMsg); + setOkEnabled(exprOk); +} + +SqliteExpr* IndexExprColumnDialog::getColumn() const +{ + return theColumn; +} + +void IndexExprColumnDialog::accept() +{ + SqliteExpr* expr = parseExpr(); + if (expr) + { + expr->rebuildTokens(); + theColumn = expr; + } + else + qCritical() << "Accepted IndexExprColumnDialog with unparsable expr! This should not happen. IndexDialog will get null expr."; + + QDialog::accept(); +} + + +int IndexExprColumnDialog::exec() +{ + ui->sqlEditor->checkSyntaxNow(); + return QDialog::exec(); +} diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/indexexprcolumndialog.h b/SQLiteStudio3/guiSQLiteStudio/dialogs/indexexprcolumndialog.h new file mode 100644 index 0000000..5e4fde5 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/indexexprcolumndialog.h @@ -0,0 +1,47 @@ +#ifndef INDEXEXPRCOLUMNDIALOG_H +#define INDEXEXPRCOLUMNDIALOG_H + +#include + +class SqliteExpr; +class Db; + +namespace Ui { + class IndexExprColumnDialog; +} + +class IndexExprColumnDialog : public QDialog +{ + Q_OBJECT + + public: + explicit IndexExprColumnDialog(Db* db, QWidget *parent = 0); + IndexExprColumnDialog(Db* db, SqliteExpr* col, QWidget *parent = 0); + ~IndexExprColumnDialog(); + + SqliteExpr* getColumn() const; + void setTableColumns(const QStringList& value); + void setExistingExprColumnKeys(const QStringList& value); + + private: + void readColumn(SqliteExpr* col); + void setOkEnabled(bool enabled); + SqliteExpr* parseExpr(); + bool checkRestrictions(QString& errorMsg); + + Ui::IndexExprColumnDialog *ui; + SqliteExpr* theColumn = nullptr; + QString lastValidatedText; + Db* db = nullptr; + QStringList tableColumns; + QStringList existingExprColumnKeys; + + public slots: + void accept(); + int exec(); + + private slots: + void validate(); +}; + +#endif // INDEXEXPRCOLUMNDIALOG_H diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/indexexprcolumndialog.ui b/SQLiteStudio3/guiSQLiteStudio/dialogs/indexexprcolumndialog.ui new file mode 100644 index 0000000..4df8486 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/indexexprcolumndialog.ui @@ -0,0 +1,83 @@ + + + IndexExprColumnDialog + + + + 0 + 0 + 400 + 300 + + + + Indexed expression + + + + + + Expression to index + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + SqlEditor + QPlainTextEdit +
sqleditor.h
+
+
+ + + + buttonBox + accepted() + IndexExprColumnDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + IndexExprColumnDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +
diff --git a/SQLiteStudio3/guiSQLiteStudio/guiSQLiteStudio.pro b/SQLiteStudio3/guiSQLiteStudio/guiSQLiteStudio.pro index ff07990..be3e876 100644 --- a/SQLiteStudio3/guiSQLiteStudio/guiSQLiteStudio.pro +++ b/SQLiteStudio3/guiSQLiteStudio/guiSQLiteStudio.pro @@ -182,7 +182,12 @@ SOURCES +=\ dialogs/languagedialog.cpp \ common/ipvalidator.cpp \ dialogs/cssdebugdialog.cpp \ - themetuner.cpp + themetuner.cpp \ + dialogs/indexexprcolumndialog.cpp \ + common/centerediconitemdelegate.cpp \ + datagrid/sqlviewmodel.cpp \ + common/exttableview.cpp \ + common/exttablewidget.cpp HEADERS += mainwindow.h \ iconmanager.h \ @@ -329,7 +334,12 @@ HEADERS += mainwindow.h \ dialogs/languagedialog.h \ common/ipvalidator.h \ dialogs/cssdebugdialog.h \ - themetuner.h + themetuner.h \ + dialogs/indexexprcolumndialog.h \ + common/centerediconitemdelegate.h \ + datagrid/sqlviewmodel.h \ + common/exttableview.h \ + common/exttablewidget.h FORMS += mainwindow.ui \ dbtree/dbtree.ui \ @@ -378,7 +388,8 @@ FORMS += mainwindow.ui \ dialogs/newversiondialog.ui \ dialogs/quitconfirmdialog.ui \ dialogs/languagedialog.ui \ - dialogs/cssdebugdialog.ui + dialogs/cssdebugdialog.ui \ + dialogs/indexexprcolumndialog.ui RESOURCES += \ icons.qrc \ diff --git a/SQLiteStudio3/guiSQLiteStudio/iconmanager.cpp b/SQLiteStudio3/guiSQLiteStudio/iconmanager.cpp index 63dde26..3d6c5f2 100644 --- a/SQLiteStudio3/guiSQLiteStudio/iconmanager.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/iconmanager.cpp @@ -87,6 +87,7 @@ void IconManager::rescanResources(const QString& pluginName) loadRecurently(":/icons", "", false); Icon::reloadAll(); + emit rescannedFor(pluginName); } void IconManager::rescanResources(Plugin* plugin, PluginType* pluginType) diff --git a/SQLiteStudio3/guiSQLiteStudio/iconmanager.h b/SQLiteStudio3/guiSQLiteStudio/iconmanager.h index 648e173..7547712 100644 --- a/SQLiteStudio3/guiSQLiteStudio/iconmanager.h +++ b/SQLiteStudio3/guiSQLiteStudio/iconmanager.h @@ -118,6 +118,8 @@ class GUI_API_EXPORT IconManager : public QObject DEF_ICON(FUNCTION, "function") DEF_ICON(GET_UPDATE, "get_update") DEF_ICON(GO_BACK, "go_back") + DEF_ICON(GENERATE_COLUMNS, "wand") + DEF_ICO3(GENERATE_QUERY, GENERATE_COLUMNS) DEF_ICON(HELP, "help") DEF_ICON(HOMEPAGE, "homepage") DEF_ICON(IMPORT, "import") @@ -131,6 +133,9 @@ class GUI_API_EXPORT IconManager : public QObject DEF_ICON(INDICATOR_INFO, "indicator_info") DEF_ICON(INDICATOR_WARN, "indicator_warn") DEF_ICON(INFO_BALLOON, "info_balloon") + DEF_ICON(INDEX_EXPR_ADD, "tag_hash_add") + DEF_ICON(INDEX_EXPR_EDIT, "tag_hash_edit") + DEF_ICON(INDEX_EXPR_DEL, "tag_hash_del") DEF_ICON(INSERT_ROW, "insert_row") DEF_ICON(INSERT_ROWS, "insert_rows") DEF_ICO3(INSERT_FN_ARG, INSERT_ROW) @@ -274,6 +279,9 @@ class GUI_API_EXPORT IconManager : public QObject public slots: void rescanResources(const QString& pluginName = QString()); + + signals: + void rescannedFor(const QString& pluginName); }; #define ICONMANAGER IconManager::getInstance() diff --git a/SQLiteStudio3/guiSQLiteStudio/icons.qrc b/SQLiteStudio3/guiSQLiteStudio/icons.qrc index 015e68a..6c08cc6 100644 --- a/SQLiteStudio3/guiSQLiteStudio/icons.qrc +++ b/SQLiteStudio3/guiSQLiteStudio/icons.qrc @@ -195,5 +195,9 @@ img/delete.png img/dock_layout_horizontal.png img/dock_layout_vertical.png + img/tag_hash_add.png + img/tag_hash_del.png + img/tag_hash_edit.png + img/wand.png diff --git a/SQLiteStudio3/guiSQLiteStudio/img/tag_hash_add.png b/SQLiteStudio3/guiSQLiteStudio/img/tag_hash_add.png new file mode 100644 index 0000000..032c353 Binary files /dev/null and b/SQLiteStudio3/guiSQLiteStudio/img/tag_hash_add.png differ diff --git a/SQLiteStudio3/guiSQLiteStudio/img/tag_hash_del.png b/SQLiteStudio3/guiSQLiteStudio/img/tag_hash_del.png new file mode 100644 index 0000000..5f43fcc Binary files /dev/null and b/SQLiteStudio3/guiSQLiteStudio/img/tag_hash_del.png differ diff --git a/SQLiteStudio3/guiSQLiteStudio/img/tag_hash_edit.png b/SQLiteStudio3/guiSQLiteStudio/img/tag_hash_edit.png new file mode 100644 index 0000000..31916c8 Binary files /dev/null and b/SQLiteStudio3/guiSQLiteStudio/img/tag_hash_edit.png differ diff --git a/SQLiteStudio3/guiSQLiteStudio/img/wand.png b/SQLiteStudio3/guiSQLiteStudio/img/wand.png new file mode 100644 index 0000000..1e2724e Binary files /dev/null and b/SQLiteStudio3/guiSQLiteStudio/img/wand.png differ diff --git a/SQLiteStudio3/guiSQLiteStudio/mainwindow.cpp b/SQLiteStudio3/guiSQLiteStudio/mainwindow.cpp index fb5c7b5..8d80277 100644 --- a/SQLiteStudio3/guiSQLiteStudio/mainwindow.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/mainwindow.cpp @@ -39,6 +39,7 @@ #include "common/widgetcover.h" #include "dialogs/cssdebugdialog.h" #include "themetuner.h" +#include "services/codeformatter.h" #include #include #include @@ -580,6 +581,20 @@ QString MainWindow::currentStyle() const return QApplication::style()->objectName(); } +EditorWindow* MainWindow::openSqlEditor(Db* dbToSet, const QString& sql) +{ + EditorWindow* win = openSqlEditor(); + if (!win->setCurrentDb(dbToSet)) + { + qCritical() << "Created EditorWindow had not got requested database:" << dbToSet->getName(); + win->close(); + return nullptr; + } + + win->setContents(FORMATTER->format("sql", sql, dbToSet)); + return win; +} + void MainWindow::closeNonSessionWindows() { foreach (MdiWindow* window, ui->mdiArea->getWindows()) @@ -605,8 +620,18 @@ void MainWindow::refreshMdiWindows() { mdiMenu->clear(); - foreach (QAction* action, getMdiArea()->getTaskBar()->getTasks()) - mdiMenu->addAction(action); + QStringList actionNames; + QHash nameToAction; + for (QAction* action : getMdiArea()->getTaskBar()->getTasks()) + { + actionNames << action->text(); + nameToAction[action->text()] = action; + } + + qSort(actionNames); + + for (const QString& name : actionNames) + mdiMenu->addAction(nameToAction[name]); updateWindowActions(); } diff --git a/SQLiteStudio3/guiSQLiteStudio/mainwindow.h b/SQLiteStudio3/guiSQLiteStudio/mainwindow.h index 10d7a9d..be96af1 100644 --- a/SQLiteStudio3/guiSQLiteStudio/mainwindow.h +++ b/SQLiteStudio3/guiSQLiteStudio/mainwindow.h @@ -120,6 +120,7 @@ class GUI_API_EXPORT MainWindow : public QMainWindow, public ExtActionContainer QMenu* getSQLiteStudioMenu() const; QString currentStyle() const; ThemeTuner* getThemeTuner() const; + EditorWindow* openSqlEditor(Db* dbToSet, const QString& sql); protected: void closeEvent(QCloseEvent *event); diff --git a/SQLiteStudio3/guiSQLiteStudio/sqleditor.cpp b/SQLiteStudio3/guiSQLiteStudio/sqleditor.cpp index 4b0628b..9dc85f7 100644 --- a/SQLiteStudio3/guiSQLiteStudio/sqleditor.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/sqleditor.cpp @@ -139,6 +139,7 @@ void SqlEditor::createActions() createAction(FIND_NEXT, tr("Find next", "sql editor"), this, SLOT(findNext()), this); createAction(FIND_PREV, tr("Find previous", "sql editor"), this, SLOT(findPrevious()), this); createAction(REPLACE, tr("Replace", "sql editor"), this, SLOT(replace()), this); + createAction(TOGGLE_COMMENT, tr("Toggle comment", "sql editor"), this, SLOT(toggleComment()), this); actionMap[CUT]->setEnabled(false); actionMap[COPY]->setEnabled(false); @@ -255,6 +256,21 @@ void SqlEditor::saveToFile(const QString &fileName) notifyInfo(tr("Saved SQL contents to file: %1").arg(fileName)); } +void SqlEditor::toggleLineCommentForLine(const QTextBlock& block) +{ + QTextCursor cur = textCursor(); + QString line = block.text(); + cur.setPosition(block.position()); + if (line.startsWith("--")) + { + cur.deleteChar(); + cur.deleteChar(); + } + else + cur.insertText("--"); + +} + void SqlEditor::updateUndoAction(bool enabled) { actionMap[UNDO]->setEnabled(enabled); @@ -1298,6 +1314,91 @@ void SqlEditor::configModified() highlighter->rehighlight(); } +void SqlEditor::toggleComment() +{ + // Handle no selection - toggle single line + QTextCursor cur = textCursor(); + int start = cur.selectionStart(); + int end = cur.selectionEnd(); + + if (start == end) + { + toggleLineCommentForLine(cur.block()); + return; + } + + // Handle multiline selection - from begin of the line to begin of the line + QTextDocument* doc = document(); + + QTextBlock startBlock = doc->findBlock(start); + bool startAtLineBegining = startBlock.position() == start; + + QTextBlock endBlock = doc->findBlock(end); + bool endAtLineBegining = endBlock.position() == end; + + if (startAtLineBegining && endAtLineBegining) + { + // Check if all lines where commented previously + bool allCommented = true; + for (QTextBlock theBlock = startBlock; theBlock != endBlock; theBlock = theBlock.next()) + { + if (!theBlock.text().startsWith("--")) + { + allCommented = false; + break; + } + } + + // Apply comment toggle + cur.beginEditBlock(); + for (QTextBlock theBlock = startBlock; theBlock != endBlock; theBlock = theBlock.next()) + { + cur.setPosition(theBlock.position()); + if (allCommented) + { + cur.deleteChar(); + cur.deleteChar(); + } + else + cur.insertText("--"); + } + + cur.setPosition(start); + cur.setPosition(endBlock.position(), QTextCursor::KeepAnchor); + cur.endEditBlock(); + setTextCursor(cur); + return; + } + + // Handle custom selection + QString txt = cur.selectedText().trimmed(); + cur.beginEditBlock(); + if (txt.startsWith("/*") && txt.endsWith("*/")) + { + cur.setPosition(end); + cur.deletePreviousChar(); + cur.deletePreviousChar(); + cur.setPosition(start); + cur.deleteChar(); + cur.deleteChar(); + + cur.setPosition(start); + cur.setPosition(end - 4, QTextCursor::KeepAnchor); + } + else + { + cur.setPosition(end); + cur.insertText("*/"); + cur.setPosition(start); + cur.insertText("/*"); + + cur.setPosition(start); + cur.setPosition(end + 4, QTextCursor::KeepAnchor); + } + cur.endEditBlock(); + setTextCursor(cur); +} + void SqlEditor::keyPressEvent(QKeyEvent* e) { switch (e->key()) diff --git a/SQLiteStudio3/guiSQLiteStudio/sqleditor.h b/SQLiteStudio3/guiSQLiteStudio/sqleditor.h index 28fbb39..1c98682 100644 --- a/SQLiteStudio3/guiSQLiteStudio/sqleditor.h +++ b/SQLiteStudio3/guiSQLiteStudio/sqleditor.h @@ -40,6 +40,7 @@ CFG_KEY_LIST(SqlEditor, QObject::tr("SQL editor input field"), CFG_KEY_ENTRY(MOVE_BLOCK_UP, Qt::ALT + Qt::Key_Up, QObject::tr("Move selected block of text one line up")) CFG_KEY_ENTRY(COPY_BLOCK_DOWN, Qt::ALT + Qt::CTRL + Qt::Key_Down, QObject::tr("Copy selected block of text and paste it a line below")) CFG_KEY_ENTRY(COPY_BLOCK_UP, Qt::ALT + Qt::CTRL + Qt::Key_Up, QObject::tr("Copy selected block of text and paste it a line above")) + CFG_KEY_ENTRY(TOGGLE_COMMENT, Qt::CTRL + Qt::Key_Slash, QObject::tr("Toggle comment")) ) class GUI_API_EXPORT SqlEditor : public QPlainTextEdit, public ExtActionContainer @@ -70,7 +71,8 @@ class GUI_API_EXPORT SqlEditor : public QPlainTextEdit, public ExtActionContaine FIND, FIND_NEXT, FIND_PREV, - REPLACE + REPLACE, + TOGGLE_COMMENT }; enum ToolBar @@ -190,6 +192,7 @@ class GUI_API_EXPORT SqlEditor : public QPlainTextEdit, public ExtActionContaine void handleValidObjectCursor(const QPoint& point); bool handleValidObjectContextMenu(const QPoint& pos); void saveToFile(const QString& fileName); + void toggleLineCommentForLine(const QTextBlock& block); SqliteSyntaxHighlighter* highlighter = nullptr; QMenu* contextMenu = nullptr; @@ -280,6 +283,7 @@ class GUI_API_EXPORT SqlEditor : public QPlainTextEdit, public ExtActionContaine void reachedEnd(); void changeFont(const QVariant& font); void configModified(); + void toggleComment(); signals: void errorsChecked(bool haveErrors); diff --git a/SQLiteStudio3/guiSQLiteStudio/statusfield.cpp b/SQLiteStudio3/guiSQLiteStudio/statusfield.cpp index 7fb746c..4acd1a6 100644 --- a/SQLiteStudio3/guiSQLiteStudio/statusfield.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/statusfield.cpp @@ -123,11 +123,11 @@ void StatusField::addEntry(const QIcon &icon, const QString &text, const QColor& item->setText(text); } - setVisible(true); + if (CFG_UI.General.AutoOpenStatusField.get()) + setVisible(true); ui->tableWidget->scrollToBottom(); - - if (!noFlashing) + if (isVisible() && !noFlashing) flashItems(itemsCreated, color); } diff --git a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_de.qm b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_de.qm index 9dad8df..597e95f 100644 Binary files a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_de.qm and b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_de.qm differ diff --git a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_de.ts b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_de.ts index f3822d6..ba0392e 100644 --- a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_de.ts +++ b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_de.ts @@ -67,13 +67,13 @@ Portable distribution. Sollte hier vermutlich "Portable Version" heißen? - Portable Version + Portable Version. MacOS X application boundle distribution. Das müsste mal genauer übersetzt werden. - MacOS X Programmbundle-Version + MacOS X Programmbundle-Version. @@ -215,12 +215,12 @@ Reporting as an unregistered user, using e-mail address. - Versenden als nicht registrierter Benutzer mittels E-mail Adresse + Versenden als nicht registrierter Benutzer mittels E-mail Adresse. Reporting as a registered user. - Versenden als registrierter Benutzer + Versenden als registrierter Benutzer. @@ -286,7 +286,7 @@ Invalid response from server. - Ungültige Antwort vom Server + Ungültige Antwort vom Server. @@ -335,12 +335,12 @@ A login must be at least 2 characters long. - Ein Login Kürzel muss mindestens 2 Zeichen lang sein + Ein Login Kürzel muss mindestens 2 Zeichen lang sein. A password must be at least 5 characters long. - Ein Passwort muss mindestens 5 Zeichen lang sein + Ein Passwort muss mindestens 5 Zeichen lang sein. @@ -363,7 +363,7 @@ Implementation language: - Sprache + Sprache: @@ -378,12 +378,12 @@ Register in following databases: - In den folgenden Datenbanken registrieren + In den folgenden Datenbanken registrieren: Implementation code: - Anweisungen + Anweisungen: @@ -441,7 +441,7 @@ Pick a color - Wählen Sie eine Farbe aus. + Wählen Sie eine Farbe aus @@ -482,12 +482,12 @@ Enter a default value expression. - Geben Sie einen Standardwert für den Ausdruck an + Geben Sie einen Standardwert an. Invalid default value expression: %1 - Ungültiger Standardwert für Ausdruck: %1 + Ungültiger Standardwert für Ausdruck: %1 @@ -589,95 +589,110 @@ Erweiterter Modus - + Add constraint column dialog Bedingung hinzufügen - + Edit constraint column dialog Bedingung editieren - - + + Delete constraint column dialog Bedingung löschen - + Move constraint up column dialog Bedingung nach oben verschieben - + Move constraint down column dialog Bedingung nach unten verschieben - + Add a primary key column dialog Primärschlüssel zufügen - + Add a foreign key column dialog Fremdschlüssel zufügen - + Add an unique constraint column dialog Eindeutige Bedingung hinzufügen - + Add a check constraint column dialog Prüfungsbedingung hinzufügen - + Add a not null constraint column dialog Nicht-NULL Bedingung hinzufügen - + Add a collate constraint column dialog Kollationsbedingung hinzufügen - + Add a default constraint column dialog Standardbedingung hinzufügen - + Are you sure you want to delete constraint '%1'? column dialog Sind Sie sicher, dass Sie die folgende Bedingung löschen wollen: '%1'? - + Correct the constraint's configuration. Korrigiert die Konfiguration der Bedingung. - + This constraint is not officially supported by SQLite 2, but it's okay to use it. Diese Bedingung wird von SQLite 2 offiziell nicht unterstützt, aber sie kann dennoch benutzt werden. + + + Scale is not allowed for INTEGER PRIMARY KEY columns. + Für INTEGER PRIMARY KEY ist eine Skalierung nicht erlaubt. + + + + Precision cannot be defined without the scale. + Die Präzision kann ohne Skalierung nicht definiert werden. + + + + Precision is not allowed for INTEGER PRIMARY KEY columns. + Für INTEGER PRIMARY KEY ist eine Präzision nicht erlaubt. + ColumnDialogConstraintsModel @@ -891,530 +906,629 @@ but it's okay to use it. ConfigDialog - + Configuration Konfiguration - + Search Suchen - + General Allgemein - + Keyboard shortcuts Tastaturkürzel - + Look & feel - Aussehen + Kurz und knackig + Layout - + Style Stil - + Fonts Schriftarten - + Colors Farben - + Plugins Plugins - + Code formatters Codeformatierer - + Data browsing Datenbearbeitung - + Data editors Dateneditoren - + + Database dialog window + Dialogfenster der Datenbank + + + + <p>When adding new database it is marked to be "permanent" (stored in configuration) by default. Checking this option makes every new database to NOT be "permanent" by default.</p> + + + + + Do not mark database to be "permanent" by default + + + + + <p>When this option is enabled, then files dropped from file manager onto database list will be automatically added to the list, bypassing standard database dialog. If for various reasons automatic process fails, then standard dialog will be presented to the user.</p> + + + + + Try to bypass dialog completly when dropping database file onto the list + + + + Data browsing and editing Datenbearbeitung - + Number of data rows per page: Anzahl an Datenzeilen pro Seite: - - + + <p>When the data is read into grid view columns width is automatically adjusted. This value limits the initial width for the adjustment, but user can still resize the column manually over this limit.</p> <p>Wenn Daten in das Ergebnisfenster eingelesen werden, dann wird die Breite der Spalten dabei automatisch angepasst. Dieser Wert begrenzt maximale Breite für die automatische Breitenanpassung. Der Anwender kann die Spaltenbreite jedoch manuell über dieses Limit verbreitern.</p> - + Limit initial data column width to (in pixels): Begrenze die initiale Spaltenbreite im Ergebnisfenster auf (Pixel): - + + <p>When this is enabled and user holds mouse pointer over a cell in any data view (query results, a table data, a view data) a tooltip will appear with details about the cell - it includes details like column data type, constraints, ROWID and others.</p> + + + + + Show column and row details tooltip in data view + + + + + Inserting new row in data grid + Neue Zeile im Gitternetz des Datenfensters hinzufügen + + + + Before currently selected row + Vor der derzeitig ausgewählten Zeile + + + + After currently selected row + Nach der derzeitig ausgewählten Zeile + + + + At the end of data view + Am Ende der Datenfensters + + + + <p>When enabled, Table Windows will show up with the data tab, instead of the structure tab.</p> + <p>Wenn aktiviert, wird der Reiter "Daten" anstelle des Reiters "Struktur" angezeigt beim öffnen eines Tabellenfensters angezeigt.</p> + + + + <p>When enabled the "Data" tab will be placed as first tab in every Table Window, instead of being at second place.</p> + <p>Wenn aktiviert, wird der Reiter "Daten" als erster Reiter angezeigt für jedes Tabellenfenster, anstelle an zweiter Stelle.</p> + + + + Place data tab as first tab in a Table Window + Den Reiter Daten als ersten Reiter im Tabellenfenster anzeigen + + + + <p>When enabled, View Windows will show up with the data tab, instead of the structure tab.</p> + + + + + <p>When enabled the "Data" tab will be placed as first tab in every View Window, instead of being at second place.</p> + + + + + Place data tab as first tab in a View Window + Den Reiter Daten als ersten Reiter im View-Fenster anzeigen + + + Data types Datentypen - + Available editors: Verfügbare Editoren: - + Editors selected for this data type: Für diesen Datentyp ausgewählte Editoren: - + Schema editing Schema - + Number of DDL changes kept in history. Maximale Anzahl an DDL Änderungen im Verlauf. - + DDL history size: - DDL Verlaufsgröße + DDL Verlaufsgröße: - + Don't show DDL preview dialog when commiting schema changes - Zeige keine DDL Vorschau, wenn Schemaänderungen committed werden. + Zeige keine DDL Vorschau, wenn Schemaänderungen committed werden - + SQL queries SQL Abfragen - - + + Number of queries kept in the history. Maximale Anzahl an SQL Abfragen im Verlauf. - + History size: - Verlaufsgröße + Verlaufsgröße: - + <p>If there is more than one query in the SQL editor window, then (if this option is enabled) only a single query will be executed - the one under the keyboard insertion cursor. Otherwise all queries will be executed. You can always limit queries to be executed by selecting those queries before calling to execute.</p> <p>Wenn diese Option aktiviert ist und sich mehrere SQL Abfragen im Editorfenster befinden, dann wird nur die SQL Abfrage ausgeführt, in der sich der Cursor befindet. Ist diese Option nicht gesetzt, dann werden alle SQL Abfragen ausgeführt. Sie können die auszuführenden SQL Abfragen selbst bestimmen, indem Sie diese vor der Ausführung mit der Maus oder Tastatur markieren.</p> - + Execute only the query under the cursor - Führt nur die Abfrage unter dem Cursor aus. + Führt nur die Abfrage unter dem Cursor aus - + Updates Updates - + Automatically check for updates at startup Prüfe vor dem Start automatisch auf Updates - + Session Sitzung - + Restore last session (active MDI windows) after startup Stelle letzte Sitzung nach dem Start wieder her (aktive MDI Fenster) - + + Status Field + Statusfeld + + + + <p>When user manually closes the Status panel, this option makes sure that if any new message is printed in the Status panel it will be reopened. If it's disabled, then Status panel can only be open manually by the user from the "View" menu.</p> + + + + + Always open Status panel when new message is printed + Den Panel Status immer öffnen, wenn eine neue Meldung ausgegeben wird + + + Filter shortcuts by name or key combination Filtere Tastaturkürzel nach Name oder Tastenkombination - + Action Aktion - + Key combination Tastenkombination - - + + Language Sprache - + Changing language requires application restart to take effect. Die Änderung der Sprache erfordert einen Neustart des Programms. - + Compact layout Kompaktes Layout - + <p>Compact layout reduces all margins and spacing on the UI to minimum, making space for displaying more data. It makes the interface a little bit less aesthetic, but allows to display more data at once.</p> <p>Das kompakte Layout reduziert alle Lücken und Abstände der Oberfläche auf ein Minimum, um mehr Platz für die Darstellung der Daten zu schaffen. Die Oberfläche sieht dann zwar nicht mehr sehr ästhetisch aus, aber man hat mehr Daten im Überblick.</p> - + Use compact layout Benutze kompaktes Layout - General.CompactLayout - Standard.KompaktesLayout + Standard.KompaktesLayout - + + Database list Liste der Datenbanken - + If switched off, then columns will be sorted in the order they are typed in CREATE TABLE statement. Wenn die Option deaktiviert ist, werden die Spalten in der Reihenfolge sortiert in der sie im CREATE TABLE Statement angegeben wurden. - + Sort table columns alphabetically Tabellenspalten alphabetisch sortieren - + Expand tables node when connected to a database Tabellenknoten aufklappen, wenn eine Datenbank verbunden ist - + <p>Additional labels are those displayed next to the names on the databases list (they are blue, unless configured otherwise). Enabling this option will result in labels for databases, invalid databases and aggregated nodes (column group, index group, trigger group). For more labels see options below.<p> <p>Zusätzliche Bezeichnungen sind jene, die neben den Namen der Datenbankliste angezeigt werden (sie sind normalerweise blau gefärbt, es sei denn dies wurde umkonfiguriert). Ist diese Option aktiviert, dann werden diese Bezeichnungen angezeigt für Datenbanken, ungültige Datenbanken und zusammengefasste Knoten (Spalten-, Index- und Triggergruppen). Für mehr Details siehe die folgenden optionen.<p> - + Display additional labels on the list Zeige zusätzliche Bezeichnungen in der Liste an - + For regular tables labels will show number of columns, indexes and triggers for each of tables. Für normale Tabellen enthält die Bezeichnung die Anzahl der Spalten, Indizes und Trigger einer jeden Tabelle. - + Display labels for regular tables Zeigt Bezeichnungen für normale Tabellen an - + Virtual tables will be marked with a 'virtual' label. Virtuelle Tabellen werden mit einem 'virtuell' Kürzel versehen. - + Display labels for virtual tables Zeige Bezeichnungen für virtuelle Tabellen - + Expand views node when connected to a database Knoten aufklappen, wenn eine Datenbank verbunden ist - + If this option is switched off, then objects will be sorted in order they appear in sqlite_master table (which is in order they were created) Wenn die Option deaktiviert ist, werden die Objekte in der Reihenfolge sortiert in der sie in der sqlite_master Tabelle angezeigt werden (entspricht der Reihenfolge in der sie angelegt worden sind) - + Sort objects (tables, indexes, triggers and views) alphabetically Objekte alphabetisch sortieren - + Display system tables and indexes on the list Zeige Systemtabellen und Indizes in der Liste an - + Table windows Tabellenfenster - When enabled, Table Windows will show up with the data tab, instead of the structure tab. - Wenn die Option aktiviert ist, dann wird im Tabellenfenster der Reiter "Daten" angezeigt statt "Strukturen". + Wenn die Option aktiviert ist, dann wird im Tabellenfenster der Reiter "Daten" angezeigt statt "Strukturen". - + Open Table Windows with the data tab for start Öffnet das Tabellenfenster mit dem Reiter "Daten" im Vordergrund - + View windows Viewfenster - When enabled, View Windows will show up with the data tab, instead of the structure tab. - Wenn die Option aktiviert ist, dann wird im Viewfenster der Reiter "Daten" angezeigt statt "Strukturen". + Wenn die Option aktiviert ist, dann wird im Viewfenster der Reiter "Daten" angezeigt statt "Strukturen". - + Open View Windows with the data tab for start Öffnet das Viewfenster mit dem Reiter "Daten" im Vordergrund - + Main window dock areas Dockingbereiche des Hauptfensters - + Left and right areas occupy corners Linke und rechte Bereiche belegen die Ecken - + Top and bottom areas occupy corners Obere und untere Bereiche belegen die Ecken - + Hide built-in plugins Verberge eingebaute Plugins - + Current style: Aktueller Stil: - + Preview Vorschau - + Enabled Aktiviert - + Disabled Deaktiviert - + Active formatter plugin Aktives Formatierungsplugin - + SQL editor font Schriftart des SQL Editors - + Database list font Schriftart der Datenbankliste - + Database list additional label font Zusätzliche Bezeichnungen in der Datenbankliste - + Data view font Schriftart der Ergebnisansicht - + Status field font Schriftart des Statusfelds - + SQL editor colors Farben des SQL Editors - + Current line background Hintergrundfarbe der aktuellen Zeile - + <p>SQL strings are enclosed with single quote characters.</p> <p>SQL Zeichenketten sind mit einfachen Anführungszeichen umschlossen.</p> - + String foreground Vordergrundfarbe von Zeichenketten - + <p>Bind parameters are placeholders for values yet to be provided by the user. They have one of the forms:</p><ul><li>:param_name</li><li>$param_name</li><li>@param_name</li><li>?</li></ul> <p>Bind Parameter sind Platzhalter für Werte, die der Anwender eingibt. Sie haben dabei eine der folgenden Formen:</p><ul><li>:param_name</li><li>$param_name</li><li>@param_name</li><li>?</li></ul> - + Bind parameter foreground Vordergrundfarbe von Bind Parametern - + Highlighted parenthesis background Hintergrundfarbe von hervorgehobener Klammern - + <p>BLOB values are binary values represented as hexadecimal numbers, like:</p><ul><li>X'12B4'</li><li>x'46A2F4'</li></ul> <p>BLOB Werte sind hexadezimale Werte wie z.B.:</p><ul><li>X'12B4'</li><li>x'46A2F4'</li></ul> - + BLOB value foreground Vordergrundfarbe von BLOB Werten - + Regular foreground Reguläre Vordergrundfarbe - + Line numbers area background Hintergrundfarbe der Zeilennummernleiste - + Keyword foreground Vordergrundfarbe von Schlüsselwörtern - + Number foreground Vordergrundfarbe von Ziffern - + Comment foreground Vordergrundfarbe von Kommentaren - + <p>Valid objects are name of tables, indexes, triggers, or views that exist in the SQLite database.</p> <p>Gültige Objekte sind Namen von Tabellen, Indizes, Triggern oder Views die in der SQLite Datenbank existieren.</p> - + Valid objects foreground Vordergrundfarbe von gültigen Objekten - + Data view colors Farben der Ergebnisansicht - + <p>Any data changes will be outlined with this color, until they're commited to the database.</p> <p>Jede Datenänderung wird mit dieser Farbe kenntlich gemacht, bis die geänderten Daten in die Datenbank zurückgeschrieben worden sind.</p> - + Uncommited data outline color Rahmenfarbe von nicht gespeicherten Daten - + <p>In case of error while commiting data changes, the problematic cell will be outlined with this color.</p> <p>Tritt beim Speichern einer Änderung ein Problem auf, dann wird die problematische Zelle mit dieser Farbe markiert.</p> - + Commit error outline color Rahmenfarbe für fehlerhafte Daten - + NULL value foreground Vordergrundfarbe für NULL Werte - + Deleted row background Hintergrundfarbe von gelöschten Zeilen - + Database list colors Farben der Datenbankliste - + <p>Additional labels are those which tell you SQLite version, number of objects deeper in the tree, etc.</p> <p>Zusätzliche Bezeichnungen sind solche, die z.B. die SQLite Version oder die Anzahl an Einträgen in einer Baumliste usw. anzeigen.</p> - + Additional labels foreground Vordergrundfarbe für zusätzliche Bezeichnungen - + Status field colors Farben des Statusfelds - + Information message foreground Vordergrundfarbe für Infomeldungen - + Warning message foreground Vordergrundfarbe für Warnmeldungen - + Error message foreground Vordergrundfarbe für Fehlermeldungen @@ -1466,43 +1580,43 @@ but it's okay to use it. Plugin Details - + Plugins are loaded/unloaded immediately when checked/unchecked, but modified list of plugins to load at startup is not saved until you commit the whole configuration dialog. Plugins werden direkt beim Aktivieren/Deaktivieren geladen bzw. entfernt, die modifizierte Pluginliste wird jedoch erst beim Bestätigen und Schließen des Konfigurationsfensters gespeichert. - + %1 (built-in) plugins manager in configuration dialog %1 (eingebaut) - + Details Details - + No plugins in this category. Keine Plugins in dieser Kategorie. - + Add new data type Neuen Datentypen zufügen - + Rename selected data type Markierten Datentypen umbenennen - + Delete selected data type Markierten Datentypen löschen - + Help for configuring data type editors Hilfe zur Konfiguration des Datentypen Editors @@ -1654,120 +1768,138 @@ but it's okay to use it. DataView - + Filter data data view Daten filtern - + Grid view Gitteransicht - + Form view Formularansicht - + Refresh table data data view Aktualisiere Tabellendaten - + First page data view Erste Seite - + Previous page data view Vorherige Seite - + Next page data view Nächste Seite - + Last page data view Letzte Seite - + Apply filter data view Filter anwenden - + Commit changes for selected cells data view Änderungen für die selektierten Zellen speichern - + Rollback changes for selected cells data view Änderungen für die selektierten Zellen zurücknehmen - + Show grid view of results sql editor Zeige Ergebnismenge in der Gitteransicht - + Show form view of results sql editor Zeige Ergebnismenge in der Formularansicht - + Filter by text data view Nach Text filtern - + Filter by the Regular Expression data view Nach regulärem Ausdruck filtern - + Filter by SQL expression data view Nach einem SQL Ausdruck filtern - + Tabs on top data view Reiterleiste oben - + Tabs at bottom data view Reiterleiste unten - + + Place new rows above selected row + data view + Neue Zeilen über der ausgewählten Zeile einfügen + + + + Place new rows below selected row + data view + Neue Zeilen nach der ausgewählten Zeile einfügen + + + + Place new rows at the end of the data view + data view + Neue Zeilen am Ende des Datenfensters einfügen + + + Total number of rows is being counted. Browsing other pages will be possible after the row counting is done. Gesamtanzahl der Zeilen wird ermittelt. Das Aufrufen anderer Seiten ist erst nach Abschluss der Zählung möglich. - + Row: %1 Zeile: %1 @@ -1837,7 +1969,7 @@ Das Aufrufen anderer Seiten ist erst nach Abschluss der Zählung möglich. Enter a not empty, unique name (as in the list of databases on the left). - Geben Sie einen eindeutigen Namen an (so wie links in der Datenbankliste) + Geben Sie einen eindeutigen Namen an (so wie links in der Datenbankliste). @@ -1914,7 +2046,7 @@ Das Aufrufen anderer Seiten ist erst nach Abschluss der Zählung möglich. - + File Datei @@ -1935,47 +2067,47 @@ Das Aufrufen anderer Seiten ist erst nach Abschluss der Zählung möglich.<p>Wenn diese Option aktiviert ist, wird die Datenbank in der Konfiguration gespeichert und bei jedem Start von SQLiteStudio wieder hergestellt.</p> - + Browse for existing database file on local computer Lokalen Computer nach Datenbankdateien durchsuchen - + Browse Durchsuchen - + Enter an unique database name. Geben Sie einen eindeutigen Datenbanknamen ein. - + This name is already in use. Please enter unique name. Der Name wird bereits benutzt, bitte geben Sie einen freien, eindeutigen Namen ein. - + Enter a database file path. Geben Sie einen Dateipfad für die Datenbank ein. - + This database is already on the list under name: %1 Die Datenbank ist bereits unter folgendem Namen in der Liste enthalten: %1 - + Select a database type. Wählen Sie einen Datebanktypen aus. - + Auto-generated Automatisch generiert - + Type the name Geben Sie den Namen ein @@ -2024,9 +2156,32 @@ Das Aufrufen anderer Seiten ist erst nach Abschluss der Zählung möglich. + Error while dropping %1: %2 Fehler beim Löschen: %1 %2 + + + Delete objects + Objekte löschen + + + + Are you sure you want to delete following objects: +%1 + Sind Sie sicher, dass Sie die folgenden Objekte löschen möchten: +%1 + + + + Cannot start transaction. Details: %1 + Kann Transaktion nicht starten. Details: %1 + + + + Cannot commit transaction. Details: %1 + Kann Transaktion nicht ausführen. Details: %1 + DbTree @@ -2041,345 +2196,369 @@ Das Aufrufen anderer Seiten ist erst nach Abschluss der Zählung möglich.Nach Name filtern - + Copy Kopieren - + Paste Einfügen - + Select all Alles auswählen - + Create a group Gruppe erstellen - + Delete the group Diese Gruppe löschen - + Rename the group Gruppe umbenennen - + Add a database Datenbank hinzufügen - + Edit the database Datenbank editieren - + Remove the database Datenbank entfernen - + Connect to the database Mit der Datenbank verbinden - + Disconnect from the database Verbindung zur Datenbank trennen - + Import Import - + Export the database Datenbank exportieren - + Convert database type Datenbanktyp konvertieren - + Vacuum ??? Vakuum - + Integrity check Integritätsprüfung - + Create a table Tabelle erstellen - + Edit the table - Datenbank editieren + Tabelle editieren - + Delete the table Tabelle löschen - + Export the table Tabelle exportieren - + Import into the table In die Tabelle importieren - + Populate table Tabelle füllen - + Create similar table Erzeuge identische Tabelle - + Reset autoincrement sequence Automatischen Zähler zurücksetzen - + Create an index Index erstellen - + Edit the index Index editieren - + Delete the index Index löschen - + Create a trigger Trigger erstellen - + Edit the trigger Trigger editieren - + Delete the trigger Trigger löschen - + Create a view View erstellen - + Edit the view View editieren - + Delete the view View löschen - + Add a column Spalte zufügen - + Edit the column Spalte editieren - + Delete the column Spalte löschen - + Delete selected items Gewählte Einträge löschen - + Clear filter Filter zurücksetzen - + Refresh all database schemas Alle Datenbankschemen aktualisieren - + Refresh selected database schema Alle markierten Datenbankschemen aktualisieren - - + + Erase table data Tabellendaten löschen - - + + Database Datenbank - + Grouping Gruppieren - - + + Generate query for table + Abfrage für Tabelle generieren + + + + Create group Gruppe erstellen - + Group name Gruppenname - + Entry with name %1 already exists in group %2. - Der Eintrag mit Namen %1 existiert bereits in der Gruppe %2 + Der Eintrag mit Namen %1 existiert bereits in der Gruppe %2. - + Delete group Gruppe löschen - + Are you sure you want to delete group %1? All objects from this group will be moved to parent group. Sind Sie sicher, dass Sie die Gruppe %1 löschen möchten? Alle Objekte in dieser Gruppe werden in die übergeordnete Gruppe verschoben. - + + Are you sure you want to remove database '%1' from the list? + Sind Sie sicher, dass Sie die Datenbank '%1' aus der Liste entfernen möchten? + + + + Are you sure you want to remove following databases from the list: +%1 + Sind Sie sicher, dass Sie folgende Datenbanken aus der Liste entfernen möchten: +%1 + + + + Remove database + Datenbank entfernen + + + + Vacuum (%1) + Vacuum (%1) + + Delete database - Datenbank löschen + Datenbank löschen - Are you sure you want to delete database '%1'? - Sind Sie sicher, dass Sie die Datenbank '%1' löschen möchten? + http://bugs.sqlitestudio.pl/?id=3066 changed according to this + Sind Sie sicher, dass Sie die Datenbank '%1' entfernen möchten? - - + + Cannot import, because no import plugin is loaded. Der Import kann nicht durchgeführt werden, da kein Import Plugin geladen ist. - - + + Cannot export, because no export plugin is loaded. Export fehlgeschlagen, da kein Export Plugins geladen sind. - Error while executing VACUUM on the database %1: %2 - Fehler beim Ausführen des VACUUM-Befehls auf die Datenbank %1: %2 + Fehler beim Ausführen des VACUUM-Befehls auf die Datenbank %1: %2 - VACUUM execution finished successfully. - VACUUM erfolgreich abgeschlossen. + VACUUM erfolgreich abgeschlossen. - + Integrity check (%1) Integritätsprüfung (%1) - + Reset autoincrement Autoincrement zurücksetzen - + Are you sure you want to reset autoincrement value for table '%1'? Sind Sie sicher, dass Sie den Autoincrement Wert für die Tabelle '%1' zurücksetzen möchten? - + An error occurred while trying to reset autoincrement value for table '%1': %2 Ein Fehler ist aufgetreten beim Zurücksetzen des Autoincrementwertes für die Tabelle '%1': %2 - + Autoincrement value for table '%1' has been reset successfly. Autoincrementwert für die Tabelle '%1' wurde erfolgreich zurückgesetzt. - + Are you sure you want to delete all data from table '%1'? - Sind Sie sicher, dass Sie alle Daten aus Tabelle '%1' löschen möchten? + Sind Sie sicher, dass Sie alle Daten der Tabelle '%1' löschen möchten? - + An error occurred while trying to delete data from table '%1': %2 - Beim Löschen von Daten aus Tabelle '%1' ist folgender Fehelr aufgetreten: %2 + Beim Löschen der Daten aus Tabelle '%1' ist folgender Fehler aufgetreten: %2 - + All data has been deleted for table '%1'. Es wurden alle Daten aus Tabelle '%1' gelöscht. - + Following objects will be deleted: %1. Folgende Objekte werden gelöscht: %1. - + Following databases will be removed from list: %1. Folgende Datenbanken werden aus der Liste entfernt: %1. - + Remainig objects from deleted group will be moved in place where the group used to be. Die aus der gelöschten Gruppe verbleibenden Objekte werden an die Position der gelöschten Gruppe verschoben. - + %1<br><br>Are you sure you want to continue? %1<br><br>Sind Sie sicher, dass Sie fortfahren möchten? - + Delete objects Objekte löschen @@ -2414,124 +2593,129 @@ Alle Objekte in dieser Gruppe werden in die übergeordnete Gruppe verschoben.
DbTreeModel - + Database: %1 dbtree tooltip Datenbank: %1 - + Version: dbtree tooltip Version: - + File size: dbtree tooltip Dateigröße: - + Encoding: dbtree tooltip Kodierung: - + Error: dbtree tooltip Fehlerbeschreibung: - + Table : %1 dbtree tooltip Tabelle: %1 - + Columns (%1): dbtree tooltip - Spalten (%1) + Spalten (%1): - + Indexes (%1): dbtree tooltip - Indizes (%1) + Indizes (%1): - + Triggers (%1): dbtree tooltip - Trigger (%1) + Trigger (%1): - + Copy Kopieren - + Move Verschieben - + Include data Inklusive Daten - + Include indexes Inklusive Indizes - + Include triggers Inklusive Trigger - + Abort Abbrechen - + + Could not add dropped database file '%1' automatically. Manual setup is necessary. + + + + Referenced tables Referenzierte Tabellen - + Do you want to include following referenced tables as well: %1 Möchten Sie die folgenden referenzierten Tabellen mit einbeziehen? %1 - + Name conflict Namenskonflikt - + Following object already exists in the target database. Please enter new, unique name, or press '%1' to abort the operation: Folgende Objekte existieren bereits in der Datenbank. Bitte geben Sie einen neuen, eindeutigen Namen an oder drücken Sie %1, um den Vorgang abzubrechen: - + SQL statements conversion SQL Statement Konvertierung - + Following error occurred while converting SQL statements to the target SQLite version: Folgender Fehler trat auf bei der Konvertierung von SQL Statements in die SQLite Zielversion: - + Would you like to ignore those errors and proceed? Möchten Sie diese Fehler ignorieren und fortfahren? @@ -2541,7 +2725,7 @@ Bitte geben Sie einen neuen, eindeutigen Namen an oder drücken Sie %1, um den V Filter by database: - Nach Datenbank filtern + Nach Datenbank filtern: @@ -2808,7 +2992,7 @@ Bitte geben Sie einen neuen, eindeutigen Namen an oder drücken Sie %1, um den V Select database objects to export - Wählen Sie die zu exportierenden Datebankobjekte aus. + Wählen Sie die zu exportierenden Datebankobjekte aus @@ -2876,7 +3060,7 @@ Bitte geben Sie einen neuen, eindeutigen Namen an oder drücken Sie %1, um den V Exported text encoding: - Exportierte Textkodierung + Exportierte Textkodierung: @@ -2939,7 +3123,7 @@ Bitte geben Sie einen neuen, eindeutigen Namen an oder drücken Sie %1, um den V Pick file to export to - Wählen Sie eine Datei aus in die exportiert werden soll. + Wählen Sie eine Datei aus in die exportiert werden soll @@ -3076,7 +3260,7 @@ Bitte geben Sie einen neuen, eindeutigen Namen an oder drücken Sie %1, um den V Final step implementation code: - Abschlussanweisungen + Abschlussanweisungen: @@ -3156,8 +3340,8 @@ Bitte geben Sie einen neuen, eindeutigen Namen an oder drücken Sie %1, um den V Per step code: - evtl. Einzelschrittanweisung??? - Pro Schritt Anweisung + evtl. Einzelschrittanweisung??? (Artur: hört sich gut an) + Einzelschrittanweisung: @@ -3239,42 +3423,42 @@ Bitte geben Sie einen neuen, eindeutigen Namen an oder drücken Sie %1, um den V Datenquellenoptionen - + Cancel Abbrechen - + If you type table name that doesn't exist, it will be created. Wenn Sie einen Tabellenname eingeben, der noch nicht existiert, dann wird diese neue Tabelle erzeugt werden. - + Enter the table name Datenbankname eingeben - + Select import plugin. Importplugin auswählen - + You must provide a file to import from. Sie müssen den Namen der Importdatei angeben. - + The file '%1' does not exist. Die Datei '%1' existiert nicht. - + Path you provided is a directory. A regular file is required. Der von Ihnen angegebene Pfad ist ein Verzeichnis. Es wird jedoch eine Datei benötigt. - + Pick file to import from Wählen Sie eine Datei aus von der importiert werden soll. @@ -3288,96 +3472,126 @@ Bitte geben Sie einen neuen, eindeutigen Namen an oder drücken Sie %1, um den V Index - + On table: Auf Tabelle: - + Index name: Indexname: - + Partial index condition Partieller Indexzustand - + Unique index Einzigartiger Index - + Column Spalte - + Collation Kollation - + Sort Sortierung - + + Delete selected indexed expression + + + + + Moves selected index column up in the order, making it more significant in the index. + + + + + Moves selected index column down in the order, making it less significant in the index. + + + + + Edit selected indexed expression + + + + + Add indexed expression + + + + DDL DDL - + Tried to open index dialog for closed or inexisting database. Es wurde versucht den Index-Dialog für eine geschlossene oder nicht existente Datenbank zu öffnen. - + Could not process index %1 correctly. Unable to open an index dialog. Der Index %1 kann nicht vollständig bearbeitet werden, da der Index-Dialog nicht geöffnet werden kann. - + + Unique index cannot have indexed expressions. Either remove expressions from list below, or uncheck this option. + + + + Pick the table for the index. Tabelle für den Index auswählen. - + Select at least one column. Mindestens eine Spalte auswählen. - + Enter a valid condition. Geben Sie einen gültigen Zustand ein. - + default index dialog Standard - + Sort order table constraints Sortierung - - + + Error index dialog Fehler - + Cannot create unique index, because values in selected columns are not unique. Would you like to execute SELECT query to see problematic values? Der eindeutige Index kann nicht erzeigt werden, da Werte in den selektierten Spalten nicht eundeutig sind. Möchten Sie die zugehörige SELECT Abfrage ausführen, um die uneindeutigen Werte zu sehen? - + An error occurred while executing SQL statements: %1 Fehler beim Ausführen des folgenden SQL Statments: @@ -3385,22 +3599,65 @@ Bitte geben Sie einen neuen, eindeutigen Namen an oder drücken Sie %1, um den V - LanguageDialog + IndexExprColumnDialog - - Language - Sprache + + Indexed expression + - - Please choose language: - Bitte Sprache auswählen: + + Expression to index + - - - MainWindow - + + This expression is already indexed by the index. + + + + + Column should be indexed directly, not by expression. Either extend this expression to contain something more than just column name, or abort and select this column in index dialog directly. + + + + + Column '%1' does not belong to the table covered by this index. Indexed expressions can refer only to columns from the indexed table. + + + + + It's forbidden to use 'SELECT' statements in indexed expressions. + + + + + Enter an indexed expression. + + + + + Invalid expression. + + + + + LanguageDialog + + + Language + Sprache + + + + Please choose language: + Bitte Sprache auswählen: + + + + MainWindow + + Database toolbar Datenbankleiste @@ -3425,273 +3682,273 @@ Bitte geben Sie einen neuen, eindeutigen Namen an oder drücken Sie %1, um den V Ansichtenleiste - + Configuration widgets Konfigurationshelfer - + Syntax highlighting engines Syntaxhervorhebungen - + Data editors Dateneditoren - + Running in debug mode. Press %1 or use 'Help / Open debug console' menu entry to open the debug console. Ablauf im Debugmodus. Zum Öffnen der Debugkonsole drücken Sie %1 oder wählen Menü 'Hilfe' den Eintrag 'Debugkonsole öffnen' aus. - + Running in debug mode. Debug messages are printed to the standard output. Ablauf im Debugmodus. Debugmeldungen werden in der Standardausgabe angezeigt.. - + You need to restart application to make the language change take effect. Das Programm muss neu gestartet werden, damit die Änderung der Sprache wirksam wird. - + Open SQL editor SQL Editor öffnen - + Open DDL history DDL Verlauf öffnen - + Open SQL functions editor - + Open collations editor Editor für Kollationen öffnen - + Import Importieren - + Export Exportieren - + Open configuration dialog Einstellungen - + Tile windows Alle Fenster aufteilen - + Tile windows horizontally Alle Fenster horizontal aufteilen - + Tile windows vertically Alle Fenster vertikal aufteilen - + Cascade windows Alle Fenster kaskadiert aufteilen - + Next window Nächstes Fenster - + Previous window Vorheriges Fenster - + Hide status field Statusfeld verbergen - + Close selected window Ausgewähltes Fenster schließen - + Close all windows but selected Alle anderen Fenster schließen - + Close all windows Alle Fenster schließen - + Restore recently closed window Zuletzt geöffnetes Fenster wiederherstellen - + Rename selected window Ausgewähltes Fenster umbenennen - + Open Debug Console Debug Konsole öffnen - + Open CSS Console CSS Konsole öffnen - + Report a bug Fehler melden - + Propose a new feature Eine neue Programmfunktion vorschlagen - + About Über SQLiteStudio - + Licenses Lizenzen - + Open home page Homepage aufrufen - + Open forum page Forum aufrufen - + User Manual Bedienungsanleitung - + SQLite documentation SQLite Dokumentation - + Report history Verlauf gemeldeter Fehler - + Check for updates Auf Updates prüfen - + Database menubar Datenbank - + Structure menubar Struktur - + View menubar Ansicht - + Window list menubar view menu Fensterliste - + Tools menubar Werkzeuge - + Help Hilfe - + Could not set style: %1 main window Der folgende Stil kann nicht gesetzt werden: %1 - + Cannot export, because no export plugin is loaded. Es kann nicht exportiert werden, da kein Export Plugin geladen ist. - + Cannot import, because no import plugin is loaded. Es kann nicht importiert werden, da kein Import Plugin geladen ist. - + Rename window Fenster umbenennen - + Enter new name for the window: - Geben Sie einen neuen Namen für das Fenster ein. + Neuen Namen für das Fenster eingeben: - + New updates are available. <a href="%1">Click here for details</a>. Neues Update verfügbar. <a href="%1">Weitere Details</a>. - + You're running the most recent version. No updates are available. Sie haben bereits die aktuellste Version. Keine Update verfügbar. - + Database passed in command line parameters (%1) was already on the list under name: %2 Die Datenbank, die mittels Programmparameter übergeben wurde (%1), war bereits in der Liste unter dem Namen %2 vorhanden. - + Database passed in command line parameters (%1) has been temporarily added to the list under name: %2 Die Datenbank, die mittels Programmparameter übergeben wurde (%1), wurde in der Liste termporär unter dem Namen %2 zugefügt. - + Could not add database %1 to list. Die Datenbank %1 konnte nicht hinzugefügt werden. @@ -4009,12 +4266,12 @@ Bitte geben Sie einen neuen, eindeutigen Namen an oder drücken Sie %1, um den V Select database with table to populate - Wählen Sie die Datebank und Tabelle zum Auffüllen aus. + Wählen Sie die Datebank und Tabelle zum Auffüllen aus Select table to populate - Wählen Sie die Tabelle zum Auffüllen aus. + Wählen Sie die Tabelle zum Auffüllen aus @@ -4092,129 +4349,129 @@ Bitte geben Sie einen neuen, eindeutigen Namen an oder drücken Sie %1, um den V Name der Kollation: %1 - + Data grid view Ergebnisansicht - + Copy cell(s) contents to clipboard Kopiert Zelleninhalt(e) in die Zwischenablage - + Paste cell(s) contents from clipboard Fügt Zelleninhalt(e) von der Zwischenablage ein - + Set empty value to selected cell(s) Fügt einen leeren Wert in die selektierte(n) Zelle(n) ein - + Set NULL value to selected cell(s) Fügt den NULL Wert in die selektierte(n) Zelle(n) ein - + Commit changes to cell(s) contents Änderungen der Zellenninhalte speichern - + Rollback changes to cell(s) contents Änderungen der Zelleninhalte zurücknehmen - + Delete selected data row Markierte Datenzeile löschen - + Insert new data row Neue Datenzeile einfügen - + Open contents of selected cell in a separate editor Inhalt der markierten Zelle im separaten Editor öffnen - + Total pages available: %1 Verfügbare Gesamtseiten: %1 - + Total rows loaded: %1 Insgesamt geladene Zeilen: %1 - + Data view (both grid and form) Ergebnisansicht (tabellarisch und Formular) - + Refresh data Daten aktualisieren - + Switch to grid view of the data Zur tabellarischen Ergebnisansicht wechseln - + Switch to form view of the data Zur Formularansicht wechseln - + Database list Liste der Datenbanken - + Delete selected item Gewählten Eintrag löschen - + Clear filter contents Filter zurücksetzen - + Refresh schema Schema aktualisieren - + Refresh all schemas Alle Schemas aktualisieren - + Add database Datenbank hinzufügen - + Select all items Alles auswählen - + Copy selected item(s) Gewählte Einträge kopieren - + - + Paste from clipboard Von der Zwischenablage einfügen @@ -4335,109 +4592,114 @@ Bitte geben Sie einen neuen, eindeutigen Namen an oder drücken Sie %1, um den V - + Cut selected text Gewählten Text ausschneiden - + Copy selected text Gewählten Text kopieren - + Delete selected text Gewählten Text löschen - + Undo Rückgängig - + Redo Wiederholen - + SQL editor input field SQL Editor Eingabefeld - + Select whole editor contents Gesamten Editorinhalt auswählen - + Save contents into a file Inhalte in eine Datei speichern - + Load contents from a file Inhalte aus einer Datei laden - + Find in text Suche im Text - + Find next Nächster Fund - + Find previous Vorheriger Fund - + Replace in text Ersetze im Text - + Delete current line Aktuelle Zeile löschen - + Request code assistant Code-Assistenten anfordern - + Format contents Format-Inhalte - + Move selected block of text one line down Selektierten Textblock eine Zeile nach unten verschieben - + Move selected block of text one line up Selektierten Textblock eine Zeile nach oben verschieben - + Copy selected block of text and paste it a line below Selektierten Textblock kopieren und unterhalb einfügen - + Copy selected block of text and paste it a line above Selektierten Textblock kopieren und oberhalb einfügen + + + Toggle comment + Kommentar umschalten + All SQLite databases @@ -4511,106 +4773,106 @@ Bitte geben Sie einen neuen, eindeutigen Namen an oder drücken Sie %1, um den V Tastatureingabe-Fokus in das obere SQL Editorfenster setzen - + Table window Tabellenfenster - + Refresh table structure Aktualisiere Tabellenstruktur - + Add new column Neue Spalte zufügen - + Edit selected column Gewählte Spalte bearbeiten - + Delete selected column Gewählte Spalte löschen - + Export table data Tabellendaten exportieren - + Import data to the table Daten in die Tabelle importieren - + Add new table constraint Neue Tabellenbedingung zufügen - + Edit selected table constraint Markierte Tabellenbedingung bearbeiten - + Delete selected table constraint Markierte Tabellenbedingung löschen - + Refresh table index list Aktualisiere Tabellenindexliste - + Add new index Neuen Index zufügen - + Edit selected index Gewählten Index bearbeiten - + Delete selected index Gewählten Index löschen - + Refresh table trigger list Aktualisiere Tabellentriggerliste - + Add new trigger Neuen Trigger zufügen - + Edit selected trigger Gewählten Trigger bearbeiten - + Delete selected trigger Gewählten Trigger löschen - + Go to next tab Springe zum nächsten Reiter - + Go to previous tab Springe zum vorherigen Reiter @@ -4732,174 +4994,180 @@ find next SqlEditor - + Cut sql editor Ausschneiden - + Copy sql editor Kopieren - + Paste sql editor Einfügen - + Delete sql editor Löschen - + Select all sql editor Alles auswählen - + Undo sql editor Rückgängig - + Redo sql editor Wiederholen - + Complete sql editor Komplett - + Format SQL sql editor SQL formatieren - + Save SQL to file sql editor SQL in Datei speichern - + Select file to save SQL sql editor SQL aus Datei laden - + Load SQL from file sql editor Zeile löschen - + Delete line sql editor Zeile löschen - + Move block down sql editor Block nach unten verschieben - + Move block up sql editor Block nach oben verschieben - + Copy block down sql editor Block nach unten kopieren - + Copy up down sql editor "up down" ??? Muss geklärt werden! Kopiere auf ab - + Find sql editor Finden - + Find next sql editor Nächster Fund - + Find previous sql editor Vorheriger Fund - + Replace sql editor Ersetzen - + + Toggle comment + sql editor + Kommentar umschalten + + + Saved SQL contents to file: %1 SQL Inhalte in Datei speichern: %1 - + Syntax completion can be used only when a valid database is set for the SQL editor. Die Funktion Autovervollständigung kann nur genutzt werden, wenn eine gültige Datenbank für den SQL Editor gewählt wurde. - + Contents of the SQL editor are huge, so errors detecting and existing objects highlighting are temporarily disabled. Der Text im SQL Editor ist sehr groß, daher wurde die Syntaxkontrolle und die farbliche Hervorhebung von Objekten vorübergehend deaktiviert. - + Save to file In Datei speichern - + Could not open file '%1' for writing: %2 Die Datei '%1' kann nicht für Schreibzugriffe geöffnet werden: %2 - + SQL scripts (*.sql);;All files (*) SQL Skripte (*.sql);;Alle Dateien (*) - + Open file Datei öffnen - + Could not open file '%1' for reading: %2 Die Datei '%1' kann nicht für Lesezugriffe geöffnet werden: %2 - + Reached the end of document. Hit the find again to restart the search. Das Dokumentenende wurde erreicht. Drücken Sie 'Nächster Fund', um die Suche am Dokumentenanfang fortzusetzen. @@ -4907,36 +5175,36 @@ find next SqlQueryItem - + Column: data view tooltip Spalte: - + Data type: data view Datentyp: - + Table: data view tooltip Tabelle: - + Constraints: data view tooltip Bedingungen: - + This cell is not editable, because: %1 Diese Zelle kann nicht editiert werden, weil: %1 - + Cannot load the data for a cell that refers to the already closed database. Es können keine Daten für eine Zelle dargestellt werden, die eine bereits geschlossene Datenbank referenziert. @@ -4944,83 +5212,88 @@ find next SqlQueryItemDelegate - - + + Cannot edit this cell. Details: %2 Die Zelle kann nicht editiert. Details: %2 - + The row is marked for deletion. Diese Zeile ist zum Löschen markiert. + + + Foreign key for column %2 has more than %1 possible values. It's too much to display in drop down list. You need to edit value manually. + + SqlQueryModel - - + + Only one query can be executed simultaneously. Es kann nur eine Abfrage gleichzeitig ausgeführt werden. - + Uncommited data Nicht gespeicherte Daten - + There are uncommited data changes. Do you want to proceed anyway? All uncommited changes will be lost. Es gibt ungespeicherte Änderungen. Möchten Sie wirklich fortfahren? Alle Änderungen werden dann verloren gehen. - + Cannot commit the data for a cell that refers to the already closed database. Es können keine Daten für eine Zelle gespeichert werden, die eine bereits geschlossene Datenbank referenziert. - + Could not begin transaction on the database. Details: %1 Es kann keine Transaktion auf der Datenbank gestartet werden. Details: %1 - + An error occurred while commiting the transaction: %1 Fehler beim Committen der Transaktion: %1 - + An error occurred while rolling back the transaction: %1 Fehler beim Rollback der Transaktion: %1 - + Tried to commit a cell which is not editable (yet modified and waiting for commit)! This is a bug. Please report it. Es wurde versucht eine nicht editierbare Zelle zu committen (derzeit modifiziert und auf das Commit wartend)! Dies ist ein Fehler den Sie melden sollten. - + An error occurred while commiting the data: %1 Fehler beim Committen der Daten: %1 - - + + Error while executing SQL query on database '%1': %2 Fehler beim Ausführen der SQL-Abfrage auf der Datenbank '%1': %2 - + Error while loading query results: %1 Fehler beim Laden der Abfrageergebnisse: %1 - + Insert multiple rows Mehrere Zeilen einfügen - + Number of rows to insert: Anzahl an Zeilen zum Einfügen: @@ -5028,92 +5301,117 @@ find next SqlQueryView - + + Go to referenced row in... + + + + Copy Kopieren - + Copy as... Kopieren als... - + Paste Einfügen - + Paste as... Einfügen als... - + Set NULL values NULL Wert setzen - + Erase values Werte löschen - + Edit value in editor Wert im Editor bearbeiten - + Commit Commit - + Rollback Rollback - + Commit selected cells Gewählte Zellen speichern - + Rollback selected cells Gewählte Zellen wiederherstellen - + Define columns to sort by Sortierspalten definieren - + Remove custom sorting Benutzerdefinierte Sortierung entfernen - + Insert row Zeile einfügen - + Insert multiple rows Mehrere Zeilen einfügen - + Delete selected row Gewählte Zeile löschen - + + Generate query for selected cells + + + + No items selected to paste clipboard contents to. Es sind keine Elemente selektiert in die der Inhalt der Zwischenablage eingefügt werden könnte. - + + Go to referenced row in table '%1' + + + + + table '%1' + + + + + Referenced row (%1) + + + + Edit value Werte editieren @@ -5121,12 +5419,12 @@ find next SqlTableModel - + Error while commiting new row: %1 Fehler beim Committen der neuen Zeile: %1 - + Error while deleting row from table %1: %2 Fehler beim Löschen der Zeile aus Tabelle %1: %2 @@ -5155,19 +5453,19 @@ find next Type table constraints - + Typ Details table constraints - + Details Name table constraints - + Name @@ -5175,7 +5473,7 @@ find next Foreign table: - + Fremde Tabelle: @@ -5186,7 +5484,7 @@ but it's okay to use them anyway. Columns - + Spalten @@ -5201,32 +5499,32 @@ but it's okay to use them anyway. Reactions - + Reaktionen Deferred foreign key - + Verzögerter Fremdschlüssel Named constraint - + Benannte Bedingung Constraint name - + Name der Bedingung Pick the foreign column. - + Wählen Sie die Fremdspalte aus. Pick the foreign table. - + Wählen Sie die Fremdtabelle aus. @@ -5236,7 +5534,7 @@ but it's okay to use them anyway. Enter a name of the constraint. - + Geben Sie einen Namen für die Bedingung ein. @@ -5250,22 +5548,22 @@ but it's okay to use them anyway. Columns - + Spalten Column - + Spalte Collation - + Kollation Sort - + Sortierung @@ -5275,22 +5573,22 @@ but it's okay to use them anyway. Autoincrement - + Automatisch hochzählend Named constraint - + Benannte Bedingung Constraint name - + Name der Bedingung On conflict - + Bei Konflikt @@ -5302,35 +5600,74 @@ but it's okay to use them anyway. Sort order table constraints - + Sortierung Select at least one column. - + Mindestens eine Spalte auswählen. Enter a name of the constraint. - + Geben Sie einen Namen für die Bedingung ein. TableStructureModel - + Name table structure columns Name - + Data type table structure columns Datentyp + + + Primary +Key + table structure columns + + + + + Foreign +Key + table structure columns + + + + + Unique + table structure columns + + + + + Check + table structure columns + Prüfung + + + + Not +NULL + table structure columns + + + Collate + table structure columns + + + + Default value table structure columns Standardwert @@ -5341,7 +5678,7 @@ but it's okay to use them anyway. Structure - + Struktur @@ -5350,420 +5687,431 @@ but it's okay to use them anyway. + Data Constraints - + Bedingungen Indexes - + Indizes Triggers - + Trigger DDL - + DDL - + Export table table window - + Import data to table table window - + Populate table table window - + Tabelle füllen - + Refresh structure table window - + Commit structure changes table window - + Rollback structure changes table window - + Add column table window - + Edit column table window - - + + Delete column table window - + Move column up table window - + Spalte nach oben verschieben - + Move column down table window - + Spalte nach unten verschieben - + Create similar table table window - + Erzeuge identische Tabelle - + Reset autoincrement value table window - + Add table constraint table window - + Edit table constraint table window - + Delete table constraint table window - + Move table constraint up table window - + Move table constraint down table window - + Add table primary key table window - + Add table foreign key table window - + Add table unique constraint table window - + Add table check constraint table window - + Refresh index list table window - + Create index table window - + Edit index table window - + Delete index table window - + Index löschen - + Refresh trigger list table window - + Trigger Liste aktualisieren - + Create trigger table window - + Edit trigger table window - + Delete trigger table window - + Trigger löschen - + Are you sure you want to delete column '%1'? table window - + Following problems will take place while modifying the table. Would you like to proceed? table window - + Table modification table window - + Could not load data for table %1. Error details: %2 - + Could not process the %1 table correctly. Unable to open a table window. - + Could not restore window %1, because no database or table was stored in session for this window. - + Could not restore window '%1', because no database or table was stored in session for this window. - + Could not restore window '%1', because database %2 could not be resolved. - + Could not restore window '%1'', because the table %2 doesn't exist in the database %3. - - + + New table %1 - + + Commited changes for table '%1' successfly. + + + + + Commited changes for table '%1' (named before '%2') successfly. + + + + Could not commit table structure. Error message: %1 table window - + Reset autoincrement - + Autoincrement zurücksetzen - + Are you sure you want to reset autoincrement value for table '%1'? - + Sind Sie sicher, dass Sie den Autoincrement Wert für die Tabelle '%1' zurücksetzen möchten? - + An error occurred while trying to reset autoincrement value for table '%1': %2 - + Ein Fehler ist aufgetreten beim Zurücksetzen des Autoincrementwertes für die Tabelle '%1': %2 - + Autoincrement value for table '%1' has been reset successfly. - + Autoincrementwert für die Tabelle '%1' wurde erfolgreich zurückgesetzt. - + Empty name - + A blank name for the table is allowed in SQLite, but it is not recommended. Are you sure you want to create a table with blank name? - + Cannot create a table without at least one column. - + Cannot create table %1, if it has no primary key defined. Either uncheck the %2, or define a primary key. - + Cannot use autoincrement for primary key when %1 clause is used. Either uncheck the %2, or the autoincrement in a primary key. - + Are you sure you want to delete table constraint '%1'? table window - + Delete constraint table window - + Bedingung löschen - + Cannot export, because no export plugin is loaded. - + Cannot import, because no import plugin is loaded. - + Uncommited changes - + Nicht gespeicherte Änderungen - + There are uncommited structure modifications. You cannot browse or edit data until you have table structure settled. Do you want to commit the structure, or do you want to go back to the structure tab? - + Go back to structure tab - + Commit modifications and browse data. - + Name table window indexes - + Name - + Unique table window indexes - + Columns table window indexes - + Spalten - + Partial index condition table window indexes - + Partieller Indexzustand - + Name table window triggers - + Name - + Event table window triggers - + Condition table window triggers - + Details table window triggers - + Details - + Table window "%1" has uncommited structure modifications and data. - + Table window "%1" has uncommited data. - + Table window "%1" has uncommited structure modifications. @@ -5792,7 +6140,7 @@ Do you want to commit the structure, or do you want to go back to the structure On table: - + Auf Tabelle: @@ -5848,7 +6196,7 @@ Do you want to commit the structure, or do you want to go back to the structure DDL - + DDL @@ -5863,7 +6211,7 @@ Do you want to commit the structure, or do you want to go back to the structure Enter a valid condition. - + Geben Sie einen gültigen Zustand ein. @@ -5874,13 +6222,14 @@ Do you want to commit the structure, or do you want to go back to the structure Error trigger dialog - + Fehler An error occurred while executing SQL statements: %1 - + Fehler beim Ausführen des folgenden SQL Statments: +%1 @@ -5911,7 +6260,7 @@ Do you want to commit the structure, or do you want to go back to the structure Query - + Abfrage @@ -5919,201 +6268,272 @@ Do you want to commit the structure, or do you want to go back to the structure - + + Output column names + + + + + Data - + Triggers - + Trigger - + DDL - + DDL - - + + Could not restore window '%1', because no database or view was stored in session for this window. - + Could not restore window '%1', because database %2 could not be resolved. - + Could not restore window '%1', because database %2 could not be open. - + Could not restore window '%1', because the view %2 doesn't exist in the database %3. - - + + New view %1 - + Refresh the view view window - + Commit the view changes view window - + Rollback the view changes view window - - Refresh trigger list + + Explicit column names + + + + + Generate output column names automatically basing on result columns of the view. + + + + + Add column view window - - Create new trigger + + Edit column view window - - Edit selected trigger + + Delete column view window - + + Move column up + view window + Spalte nach oben verschieben + + + + Move column down + view window + Spalte nach unten verschieben + + + + Refresh trigger list + view window + Trigger Liste aktualisieren + + + + Create new trigger + view window + Trigger erstellen + + + + Edit selected trigger + view window + Trigger editieren + + + Delete selected trigger view window - + Trigger löschen - + View window "%1" has uncommited structure modifications and data. - + View window "%1" has uncommited data. - + View window "%1" has uncommited structure modifications. - + Could not load data for view %1. Error details: %2 - + Uncommited changes - + Nicht gespeicherte Änderungen - + There are uncommited structure modifications. You cannot browse or edit data until you have the view structure settled. Do you want to commit the structure, or do you want to go back to the structure tab? - + Go back to structure tab - + Commit modifications and browse data. - + + Commited changes for view '%1' successfly. + + + + + Commited changes for view '%1' (named before '%2') successfly. + + + + Could not commit view changes. Error message: %1 view window - + + Override columns + + + + + Currently defined columns will be overriden. Do you want to continue? + + + + + Could not determinate columns returned from the view. The query is problably incomplete or contains errors. + + + + Name view window triggers - + Name - + Instead of view window triggers - + Condition view window triggers - + Details table window triggers - + Details - + Could not process the %1 view correctly. Unable to open a view window. - + Empty name - + A blank name for the view is allowed in SQLite, but it is not recommended. Are you sure you want to create a view with blank name? - + The SELECT statement could not be parsed. Please correct the query and retry. Details: %1 - + The view could not be modified due to internal SQLiteStudio error. Please report this! - + The view code could not be parsed properly for execution. This is a SQLiteStudio's bug. Please report it. - + Following problems will take place while modifying the view. Would you like to proceed? view window - + View modification view window diff --git a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_es.ts b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_es.ts index 78940e4..715333f 100644 --- a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_es.ts +++ b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_es.ts @@ -1,6 +1,6 @@ - + AboutDialog @@ -586,95 +586,110 @@ - + Add constraint column dialog - + Edit constraint column dialog - - + + Delete constraint column dialog - + Move constraint up column dialog - + Move constraint down column dialog - + Add a primary key column dialog - + Add a foreign key column dialog - + Add an unique constraint column dialog - + Add a check constraint column dialog - + Add a not null constraint column dialog - + Add a collate constraint column dialog - + Add a default constraint column dialog - + Are you sure you want to delete constraint '%1'? column dialog - + Correct the constraint's configuration. - + This constraint is not officially supported by SQLite 2, but it's okay to use it. + + + Scale is not allowed for INTEGER PRIMARY KEY columns. + + + + + Precision cannot be defined without the scale. + + + + + Precision is not allowed for INTEGER PRIMARY KEY columns. + + ColumnDialogConstraintsModel @@ -888,557 +903,616 @@ but it's okay to use it. ConfigDialog - + Configuration - + Search - + General - + Keyboard shortcuts - + Look & feel - + Style - + Fonts - + Colors - + Plugins - + Code formatters - + Data browsing - + Data editors - + + Database dialog window + + + + + <p>When adding new database it is marked to be "permanent" (stored in configuration) by default. Checking this option makes every new database to NOT be "permanent" by default.</p> + + + + + Do not mark database to be "permanent" by default + + + + + <p>When this option is enabled, then files dropped from file manager onto database list will be automatically added to the list, bypassing standard database dialog. If for various reasons automatic process fails, then standard dialog will be presented to the user.</p> + + + + + Try to bypass dialog completly when dropping database file onto the list + + + + Data browsing and editing - + Number of data rows per page: - - + + <p>When the data is read into grid view columns width is automatically adjusted. This value limits the initial width for the adjustment, but user can still resize the column manually over this limit.</p> - + Limit initial data column width to (in pixels): - - Inserting new row in data grid + + <p>When this is enabled and user holds mouse pointer over a cell in any data view (query results, a table data, a view data) a tooltip will appear with details about the cell - it includes details like column data type, constraints, ROWID and others.</p> - - Before currently selected row + + Show column and row details tooltip in data view + + + + + Inserting new row in data grid - - - - General.InsertRowPlacement + + Before currently selected row - + After currently selected row - + At the end of data view - + + <p>When enabled, Table Windows will show up with the data tab, instead of the structure tab.</p> + + + + + <p>When enabled the "Data" tab will be placed as first tab in every Table Window, instead of being at second place.</p> + + + + + Place data tab as first tab in a Table Window + + + + + <p>When enabled, View Windows will show up with the data tab, instead of the structure tab.</p> + + + + + <p>When enabled the "Data" tab will be placed as first tab in every View Window, instead of being at second place.</p> + + + + + Place data tab as first tab in a View Window + + + + Data types - + Available editors: - + Editors selected for this data type: - + Schema editing - + Number of DDL changes kept in history. - + DDL history size: - + Don't show DDL preview dialog when commiting schema changes - + SQL queries - - + + Number of queries kept in the history. - + History size: - + <p>If there is more than one query in the SQL editor window, then (if this option is enabled) only a single query will be executed - the one under the keyboard insertion cursor. Otherwise all queries will be executed. You can always limit queries to be executed by selecting those queries before calling to execute.</p> - + Execute only the query under the cursor - + Updates - + Automatically check for updates at startup - + Session - + Restore last session (active MDI windows) after startup - + + Status Field + + + + + <p>When user manually closes the Status panel, this option makes sure that if any new message is printed in the Status panel it will be reopened. If it's disabled, then Status panel can only be open manually by the user from the "View" menu.</p> + + + + + Always open Status panel when new message is printed + + + + Filter shortcuts by name or key combination - + Action - + Key combination - - + + Language - + Changing language requires application restart to take effect. - + Compact layout - + <p>Compact layout reduces all margins and spacing on the UI to minimum, making space for displaying more data. It makes the interface a little bit less aesthetic, but allows to display more data at once.</p> - + Use compact layout - - General.CompactLayout - - - - + + Database list - + If switched off, then columns will be sorted in the order they are typed in CREATE TABLE statement. - + Sort table columns alphabetically - + Expand tables node when connected to a database - + <p>Additional labels are those displayed next to the names on the databases list (they are blue, unless configured otherwise). Enabling this option will result in labels for databases, invalid databases and aggregated nodes (column group, index group, trigger group). For more labels see options below.<p> - + Display additional labels on the list - + For regular tables labels will show number of columns, indexes and triggers for each of tables. - + Display labels for regular tables - + Virtual tables will be marked with a 'virtual' label. - + Display labels for virtual tables - + Expand views node when connected to a database - + If this option is switched off, then objects will be sorted in order they appear in sqlite_master table (which is in order they were created) - + Sort objects (tables, indexes, triggers and views) alphabetically - + Display system tables and indexes on the list - + Table windows - - When enabled, Table Windows will show up with the data tab, instead of the structure tab. - - - - + Open Table Windows with the data tab for start - + View windows - - When enabled, View Windows will show up with the data tab, instead of the structure tab. - - - - + Open View Windows with the data tab for start - + Main window dock areas - + Left and right areas occupy corners - + Top and bottom areas occupy corners - + Hide built-in plugins - + Current style: - + Preview - + Enabled - + Disabled - + Active formatter plugin - + SQL editor font - + Database list font - + Database list additional label font - + Data view font - + Status field font - + SQL editor colors - + Current line background - + <p>SQL strings are enclosed with single quote characters.</p> - + String foreground - + <p>Bind parameters are placeholders for values yet to be provided by the user. They have one of the forms:</p><ul><li>:param_name</li><li>$param_name</li><li>@param_name</li><li>?</li></ul> - + Bind parameter foreground - + Highlighted parenthesis background - + <p>BLOB values are binary values represented as hexadecimal numbers, like:</p><ul><li>X'12B4'</li><li>x'46A2F4'</li></ul> - + BLOB value foreground - + Regular foreground - + Line numbers area background - + Keyword foreground - + Number foreground - + Comment foreground - + <p>Valid objects are name of tables, indexes, triggers, or views that exist in the SQLite database.</p> - + Valid objects foreground - + Data view colors - + <p>Any data changes will be outlined with this color, until they're commited to the database.</p> - + Uncommited data outline color - + <p>In case of error while commiting data changes, the problematic cell will be outlined with this color.</p> - + Commit error outline color - + NULL value foreground - + Deleted row background - + Database list colors - + <p>Additional labels are those which tell you SQLite version, number of objects deeper in the tree, etc.</p> - + Additional labels foreground - + Status field colors - + Information message foreground - + Warning message foreground - + Error message foreground @@ -1490,43 +1564,43 @@ but it's okay to use it. - + Plugins are loaded/unloaded immediately when checked/unchecked, but modified list of plugins to load at startup is not saved until you commit the whole configuration dialog. - + %1 (built-in) plugins manager in configuration dialog - + Details - + No plugins in this category. - + Add new data type - + Rename selected data type - + Delete selected data type - + Help for configuring data type editors @@ -1678,137 +1752,137 @@ but it's okay to use it. DataView - + Filter data data view - + Grid view - + Form view - + Refresh table data data view - + First page data view - + Previous page data view - + Next page data view - + Last page data view - + Apply filter data view - + Commit changes for selected cells data view - + Rollback changes for selected cells data view - + Show grid view of results sql editor - + Show form view of results sql editor - + Filter by text data view - + Filter by the Regular Expression data view - + Filter by SQL expression data view - + Tabs on top data view - + Tabs at bottom data view - + Place new rows above selected row data view - + Place new rows below selected row data view - + Place new rows at the end of the data view data view - + Total number of rows is being counted. Browsing other pages will be possible after the row counting is done. - + Row: %1 @@ -1955,7 +2029,7 @@ Browsing other pages will be possible after the row counting is done. - + File @@ -1976,47 +2050,47 @@ Browsing other pages will be possible after the row counting is done. - + Browse for existing database file on local computer - + Browse - + Enter an unique database name. - + This name is already in use. Please enter unique name. - + Enter a database file path. - + This database is already on the list under name: %1 - + Select a database type. - + Auto-generated - + Type the name @@ -2065,9 +2139,31 @@ Browsing other pages will be possible after the row counting is done. + Error while dropping %1: %2 + + + Delete objects + + + + + Are you sure you want to delete following objects: +%1 + + + + + Cannot start transaction. Details: %1 + + + + + Cannot commit transaction. Details: %1 + + DbTree @@ -2082,343 +2178,349 @@ Browsing other pages will be possible after the row counting is done. - + Copy - + Paste - + Select all - + Create a group - + Delete the group - + Rename the group - + Add a database - + Edit the database - + Remove the database - + Connect to the database - + Disconnect from the database - + Import - + Export the database - + Convert database type - + Vacuum - + Integrity check - + Create a table - + Edit the table - + Delete the table - + Export the table - + Import into the table - + Populate table - + Create similar table - + Reset autoincrement sequence - + Create an index - + Edit the index - + Delete the index - + Create a trigger - + Edit the trigger - + Delete the trigger - + Create a view - + Edit the view - + Delete the view - + Add a column - + Edit the column - + Delete the column - + Delete selected items - + Clear filter - + Refresh all database schemas - + Refresh selected database schema - - + + Erase table data - - + + Database - + Grouping - - + + Generate query for table + + + + + Create group - + Group name - + Entry with name %1 already exists in group %2. - + Delete group - + Are you sure you want to delete group %1? All objects from this group will be moved to parent group. - - Delete database + + Are you sure you want to remove database '%1' from the list? - - Are you sure you want to delete database '%1'? + + Are you sure you want to remove following databases from the list: +%1 - - - Cannot import, because no import plugin is loaded. + + Remove database - - - Cannot export, because no export plugin is loaded. + + Vacuum (%1) - - Error while executing VACUUM on the database %1: %2 + + + Cannot import, because no import plugin is loaded. + - VACUUM execution finished successfully. + Cannot export, because no export plugin is loaded. - + Integrity check (%1) - + Reset autoincrement - + Are you sure you want to reset autoincrement value for table '%1'? - + An error occurred while trying to reset autoincrement value for table '%1': %2 - + Autoincrement value for table '%1' has been reset successfly. - + Are you sure you want to delete all data from table '%1'? - + An error occurred while trying to delete data from table '%1': %2 - + All data has been deleted for table '%1'. - + Following objects will be deleted: %1. - + Following databases will be removed from list: %1. - + Remainig objects from deleted group will be moved in place where the group used to be. - + %1<br><br>Are you sure you want to continue? - + Delete objects @@ -2453,123 +2555,128 @@ All objects from this group will be moved to parent group. DbTreeModel - + Database: %1 dbtree tooltip - + Version: dbtree tooltip - + File size: dbtree tooltip - + Encoding: dbtree tooltip - + Error: dbtree tooltip - + Table : %1 dbtree tooltip - + Columns (%1): dbtree tooltip - + Indexes (%1): dbtree tooltip - + Triggers (%1): dbtree tooltip - + Copy - + Move - + Include data - + Include indexes - + Include triggers - + Abort - + + Could not add dropped database file '%1' automatically. Manual setup is necessary. + + + + Referenced tables - + Do you want to include following referenced tables as well: %1 - + Name conflict - + Following object already exists in the target database. Please enter new, unique name, or press '%1' to abort the operation: - + SQL statements conversion - + Following error occurred while converting SQL statements to the target SQLite version: - + Would you like to ignore those errors and proceed? @@ -3320,124 +3427,197 @@ Please enter new, unique name, or press '%1' to abort the operation: - + On table: - + Index name: - + Partial index condition - + Unique index - + Column - + Collation - + Sort - + + Delete selected indexed expression + + + + + Moves selected index column up in the order, making it more significant in the index. + + + + + Moves selected index column down in the order, making it less significant in the index. + + + + + Edit selected indexed expression + + + + + Add indexed expression + + + + DDL - + Tried to open index dialog for closed or inexisting database. - + Could not process index %1 correctly. Unable to open an index dialog. - + + Unique index cannot have indexed expressions. Either remove expressions from list below, or uncheck this option. + + + + Pick the table for the index. - + Select at least one column. - + Enter a valid condition. - + default index dialog - + Sort order table constraints - - + + Error index dialog - + Cannot create unique index, because values in selected columns are not unique. Would you like to execute SELECT query to see problematic values? - + An error occurred while executing SQL statements: %1 - LanguageDialog + IndexExprColumnDialog - - Language + + Indexed expression - - Please choose language: + + Expression to index - - - MainWindow - - Database toolbar + + This expression is already indexed by the index. - - Structure toolbar + + Column should be indexed directly, not by expression. Either extend this expression to contain something more than just column name, or abort and select this column in index dialog directly. + + + + + Column '%1' does not belong to the table covered by this index. Indexed expressions can refer only to columns from the indexed table. + + + + + It's forbidden to use 'SELECT' statements in indexed expressions. + + + + + Enter an indexed expression. + + + + + Invalid expression. + + + + + LanguageDialog + + + Language + + + + + Please choose language: + + + + + MainWindow + + + Database toolbar + + + + + Structure toolbar @@ -3456,273 +3636,273 @@ Please enter new, unique name, or press '%1' to abort the operation: - + Configuration widgets - + Syntax highlighting engines - + Data editors - + Running in debug mode. Press %1 or use 'Help / Open debug console' menu entry to open the debug console. - + Running in debug mode. Debug messages are printed to the standard output. - + You need to restart application to make the language change take effect. - + Open SQL editor - + Open DDL history - + Open SQL functions editor - + Open collations editor - + Import - + Export - + Open configuration dialog - + Tile windows - + Tile windows horizontally - + Tile windows vertically - + Cascade windows - + Next window - + Previous window - + Hide status field - + Close selected window - + Close all windows but selected - + Close all windows - + Restore recently closed window - + Rename selected window - + Open Debug Console - + Open CSS Console - + Report a bug - + Propose a new feature - + About - + Licenses - + Open home page - + Open forum page - + User Manual - + SQLite documentation - + Report history - + Check for updates - + Database menubar - + Structure menubar - + View menubar - + Window list menubar view menu - + Tools menubar - + Help - + Could not set style: %1 main window - + Cannot export, because no export plugin is loaded. - + Cannot import, because no import plugin is loaded. - + Rename window - + Enter new name for the window: - + New updates are available. <a href="%1">Click here for details</a>. - + You're running the most recent version. No updates are available. - + Database passed in command line parameters (%1) was already on the list under name: %2 - + Database passed in command line parameters (%1) has been temporarily added to the list under name: %2 - + Could not add database %1 to list. @@ -4122,127 +4302,127 @@ Please enter new, unique name, or press '%1' to abort the operation: - + Data grid view - + Copy cell(s) contents to clipboard - + Paste cell(s) contents from clipboard - + Set empty value to selected cell(s) - + Set NULL value to selected cell(s) - + Commit changes to cell(s) contents - + Rollback changes to cell(s) contents - + Delete selected data row - + Insert new data row - + Open contents of selected cell in a separate editor - + Total pages available: %1 - + Total rows loaded: %1 - + Data view (both grid and form) - + Refresh data - + Switch to grid view of the data - + Switch to form view of the data - + Database list - + Delete selected item - + Clear filter contents - + Refresh schema - + Refresh all schemas - + Add database - + Select all items - + Copy selected item(s) - + Paste from clipboard @@ -4468,6 +4648,11 @@ Please enter new, unique name, or press '%1' to abort the operation:Copy selected block of text and paste it a line above + + + Toggle comment + + All SQLite databases @@ -4540,106 +4725,106 @@ Please enter new, unique name, or press '%1' to abort the operation: - + Table window - + Refresh table structure - + Add new column - + Edit selected column - + Delete selected column - + Export table data - + Import data to the table - + Add new table constraint - + Edit selected table constraint - + Delete selected table constraint - + Refresh table index list - + Add new index - + Edit selected index - + Delete selected index - + Refresh table trigger list - + Add new trigger - + Edit selected trigger - + Delete selected trigger - + Go to next tab - + Go to previous tab @@ -4883,47 +5068,53 @@ find next - + + Toggle comment + sql editor + + + + Saved SQL contents to file: %1 - + Syntax completion can be used only when a valid database is set for the SQL editor. - + Contents of the SQL editor are huge, so errors detecting and existing objects highlighting are temporarily disabled. - + Save to file - + Could not open file '%1' for writing: %2 - + SQL scripts (*.sql);;All files (*) - + Open file - + Could not open file '%1' for reading: %2 - + Reached the end of document. Hit the find again to restart the search. @@ -4931,36 +5122,36 @@ find next SqlQueryItem - + Column: data view tooltip - + Data type: data view - + Table: data view tooltip - + Constraints: data view tooltip - + This cell is not editable, because: %1 - + Cannot load the data for a cell that refers to the already closed database. @@ -4968,83 +5159,88 @@ find next SqlQueryItemDelegate - - + + Cannot edit this cell. Details: %2 - + The row is marked for deletion. + + + Foreign key for column %2 has more than %1 possible values. It's too much to display in drop down list. You need to edit value manually. + + SqlQueryModel - - + + Only one query can be executed simultaneously. - + Uncommited data - + There are uncommited data changes. Do you want to proceed anyway? All uncommited changes will be lost. - + Cannot commit the data for a cell that refers to the already closed database. - + Could not begin transaction on the database. Details: %1 - + An error occurred while commiting the transaction: %1 - + An error occurred while rolling back the transaction: %1 - + Tried to commit a cell which is not editable (yet modified and waiting for commit)! This is a bug. Please report it. - + An error occurred while commiting the data: %1 - - + + Error while executing SQL query on database '%1': %2 - + Error while loading query results: %1 - + Insert multiple rows - + Number of rows to insert: @@ -5052,92 +5248,117 @@ find next SqlQueryView - + + Go to referenced row in... + + + + Copy - + Copy as... - + Paste - + Paste as... - + Set NULL values - + Erase values - + Edit value in editor - + Commit - + Rollback - + Commit selected cells - + Rollback selected cells - + Define columns to sort by - + Remove custom sorting - + Insert row - + Insert multiple rows - + Delete selected row - + + Generate query for selected cells + + + + No items selected to paste clipboard contents to. - + + Go to referenced row in table '%1' + + + + + table '%1' + + + + + Referenced row (%1) + + + + Edit value @@ -5145,12 +5366,12 @@ find next SqlTableModel - + Error while commiting new row: %1 - + Error while deleting row from table %1: %2 @@ -5342,19 +5563,58 @@ but it's okay to use them anyway. TableStructureModel - + Name table structure columns - + Data type table structure columns + + + Primary +Key + table structure columns + + + + + Foreign +Key + table structure columns + + + + + Unique + table structure columns + + + + + Check + table structure columns + + + + + Not +NULL + table structure columns + + + Collate + table structure columns + + + + Default value table structure columns @@ -5374,6 +5634,7 @@ but it's okay to use them anyway. + Data @@ -5398,396 +5659,406 @@ but it's okay to use them anyway. - + Export table table window - + Import data to table table window - + Populate table table window - + Refresh structure table window - + Commit structure changes table window - + Rollback structure changes table window - + Add column table window - + Edit column table window - - + + Delete column table window - + Move column up table window - + Move column down table window - + Create similar table table window - + Reset autoincrement value table window - + Add table constraint table window - + Edit table constraint table window - + Delete table constraint table window - + Move table constraint up table window - + Move table constraint down table window - + Add table primary key table window - + Add table foreign key table window - + Add table unique constraint table window - + Add table check constraint table window - + Refresh index list table window - + Create index table window - + Edit index table window - + Delete index table window - + Refresh trigger list table window - + Create trigger table window - + Edit trigger table window - + Delete trigger table window - + Are you sure you want to delete column '%1'? table window - + Following problems will take place while modifying the table. Would you like to proceed? table window - + Table modification table window - + Could not load data for table %1. Error details: %2 - + Could not process the %1 table correctly. Unable to open a table window. - + Could not restore window %1, because no database or table was stored in session for this window. - + Could not restore window '%1', because no database or table was stored in session for this window. - + Could not restore window '%1', because database %2 could not be resolved. - + Could not restore window '%1'', because the table %2 doesn't exist in the database %3. - - + + New table %1 - + + Commited changes for table '%1' successfly. + + + + + Commited changes for table '%1' (named before '%2') successfly. + + + + Could not commit table structure. Error message: %1 table window - + Reset autoincrement - + Are you sure you want to reset autoincrement value for table '%1'? - + An error occurred while trying to reset autoincrement value for table '%1': %2 - + Autoincrement value for table '%1' has been reset successfly. - + Empty name - + A blank name for the table is allowed in SQLite, but it is not recommended. Are you sure you want to create a table with blank name? - + Cannot create a table without at least one column. - + Cannot create table %1, if it has no primary key defined. Either uncheck the %2, or define a primary key. - + Cannot use autoincrement for primary key when %1 clause is used. Either uncheck the %2, or the autoincrement in a primary key. - + Are you sure you want to delete table constraint '%1'? table window - + Delete constraint table window - + Cannot export, because no export plugin is loaded. - + Cannot import, because no import plugin is loaded. - + Uncommited changes - + There are uncommited structure modifications. You cannot browse or edit data until you have table structure settled. Do you want to commit the structure, or do you want to go back to the structure tab? - + Go back to structure tab - + Commit modifications and browse data. - + Name table window indexes - + Unique table window indexes - + Columns table window indexes - + Partial index condition table window indexes - + Name table window triggers - + Event table window triggers - + Condition table window triggers - + Details table window triggers - + Table window "%1" has uncommited structure modifications and data. - + Table window "%1" has uncommited data. - + Table window "%1" has uncommited structure modifications. @@ -5943,201 +6214,272 @@ Do you want to commit the structure, or do you want to go back to the structure - + + Output column names + + + + + Data - + Triggers - + DDL - - + + Could not restore window '%1', because no database or view was stored in session for this window. - + Could not restore window '%1', because database %2 could not be resolved. - + Could not restore window '%1', because database %2 could not be open. - + Could not restore window '%1', because the view %2 doesn't exist in the database %3. - - + + New view %1 - + Refresh the view view window - + Commit the view changes view window - + Rollback the view changes view window - + + Explicit column names + + + + + Generate output column names automatically basing on result columns of the view. + + + + + Add column + view window + + + + + Edit column + view window + + + + + Delete column + view window + + + + + Move column up + view window + + + + + Move column down + view window + + + + Refresh trigger list view window - + Create new trigger view window - + Edit selected trigger view window - + Delete selected trigger view window - + View window "%1" has uncommited structure modifications and data. - + View window "%1" has uncommited data. - + View window "%1" has uncommited structure modifications. - + Could not load data for view %1. Error details: %2 - + Uncommited changes - + There are uncommited structure modifications. You cannot browse or edit data until you have the view structure settled. Do you want to commit the structure, or do you want to go back to the structure tab? - + Go back to structure tab - + Commit modifications and browse data. - + + Commited changes for view '%1' successfly. + + + + + Commited changes for view '%1' (named before '%2') successfly. + + + + Could not commit view changes. Error message: %1 view window - + + Override columns + + + + + Currently defined columns will be overriden. Do you want to continue? + + + + + Could not determinate columns returned from the view. The query is problably incomplete or contains errors. + + + + Name view window triggers - + Instead of view window triggers - + Condition view window triggers - + Details table window triggers - + Could not process the %1 view correctly. Unable to open a view window. - + Empty name - + A blank name for the view is allowed in SQLite, but it is not recommended. Are you sure you want to create a view with blank name? - + The SELECT statement could not be parsed. Please correct the query and retry. Details: %1 - + The view could not be modified due to internal SQLiteStudio error. Please report this! - + The view code could not be parsed properly for execution. This is a SQLiteStudio's bug. Please report it. - + Following problems will take place while modifying the view. Would you like to proceed? view window - + View modification view window diff --git a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_fr.ts b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_fr.ts index 6ecc9aa..015a070 100644 --- a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_fr.ts +++ b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_fr.ts @@ -6,17 +6,17 @@ About SQLiteStudio and licenses - Apropos de SQLiteStudio et licences + À propos de SQLiteStudio et ses licences About - Apropos + À propos de… <html><head/><body><p align="center"><span style=" font-size:11pt; font-weight:600;">SQLiteStudio v%1</span></p><p align="center">Free, open-source, cross-platform SQLite database manager.<br/><a href="http://sqlitestudio.pl"><span style=" text-decoration: underline; color:#0000ff;">http://sqlitestudio.pl</span></a><br/></p><p align="center">%2<br/></p><p align="center">Author and active maintainer:<br/>SalSoft (<a href="http://salsoft.com.pl"><span style=" text-decoration: underline; color:#0000ff;">http://salsoft.com.pl</span></a>)<br/></p></body></html> - <html><head/><body><p align="center"><span style=" font-size:11pt; font-weight:600;">SQLiteStudio v%1</span></p><p align="center">Libre, open-source, cross-platform SQLite database manager.<br/><a href="http://sqlitestudio.pl"><span style=" text-decoration: underline; color:#0000ff;">http://sqlitestudio.pl</span></a><br/></p><p align="center">%2<br/></p><p align="center">Auteur et maintenance:<br/>SalSoft (<a href="http://salsoft.com.pl"><span style=" text-decoration: underline; color:#0000ff;">http://salsoft.com.pl</span></a>)<br/></p></body></html> + <html><head/><body><p align="center"><span style=" font-size:11pt; font-weight:600;">SQLiteStudio v%1</span></p><p align="center">Libre, open-source, cross-platform SQLite database manager.<br/><a href="http://sqlitestudio.pl"><span style=" text-decoration: underline; color:#0000ff;">http://sqlitestudio.pl</span></a><br/></p><p align="center">%2<br/></p><p align="center">Auteur et maintenance:<br/>SalSoft (<a href="http://salsoft.com.pl"><span style=" text-decoration: underline; color:#0000ff;">http://salsoft.com.pl</span></a>)<br/></p></body></html> @@ -31,7 +31,7 @@ Icon directories - Répertoires d'images + Répertoires d’images @@ -46,7 +46,7 @@ Application directory - Répertoire de l'application + Répertoire de l’application @@ -110,7 +110,7 @@ Log in - S'identifier + S’identifier @@ -135,7 +135,7 @@ Operating system - Système d'exploitation + Système d’exploitation @@ -150,7 +150,7 @@ You can see all your reported bugs and ideas by selecting menu '%1' and then '%2'. - Vous pouvez voir tous bugs et idées que vous avez rapportées en sélectionnant le menu '%1' puis '%2'. + Vous pouvez voir tous bugs et idées que vous avez rapportées en sélectionnant le menu « %1 » puis « %2 ». @@ -161,7 +161,7 @@ An error occurred while sending a bug report: %1 %2 - Une erreur est survenue lors de l'envoi du rapport de bug: %1 + Une erreur est survenue lors de l’envoi du rapport de bug: %1 %2 @@ -173,13 +173,13 @@ An idea proposal sent successfully. - L'idée proposée à été envoyée avec succès. + L’idée proposée à été envoyée avec succès. An error occurred while sending an idea proposal: %1 %2 - Une erreeur est survenu lors de l'envoi de l'idée proposée: %1 %2 + Une erreeur est survenu lors de l’envoi de l’idée proposée: %1 %2 @@ -229,7 +229,7 @@ Providing true email address will make it possible to contact you regarding your report. To learn more, press 'help' button on the right side. - En fournissant un mail existant il sera possible de vous contacterau sujet du rapport. Pour en savoir plus, clic sur le bouton 'help'sur le coté droit. + En fournissant un mail existant il sera possible de vous contacterau sujet du rapport. Pour en savoir plus, clic sur le bouton « help » sur le coté droit. @@ -275,12 +275,12 @@ Clear reports history - Vider l'historique de rapports + Vider l’historique de rapports Delete selected entry - Supprimer l'entrée sélectionnée + Supprimer l’entrée sélectionnée @@ -361,7 +361,7 @@ Implementation language: - Language d'implémentation: + Language d’implémentation: @@ -381,7 +381,7 @@ Implementation code: - Code d'inplémentation: + Code d’inplémentation: @@ -421,17 +421,17 @@ Pick the implementation language. - Prendre le language d'inplémentation. + Prendre le language d’inplémentation. Enter a non-empty implementation code. - Saississez un nom, non vide, de language d'implémentation. + Saississez un nom, non vide, de language d’implémentation. Collations editor window has uncommited modifications. - L'éditeur de regroupement n'as pas enregistré les modifications. + L’éditeur de regroupement n’as pas enregistré les modifications. @@ -480,12 +480,12 @@ Enter a default value expression. - Saississez l'expression d'une valeur par défaut. + Saississez l’expression d’une valeur par défaut. Invalid default value expression: %1 - Invalide expression d'une valeur par défaut: %1 + Invalide expression d’une valeur par défaut: %1 @@ -663,7 +663,7 @@ Are you sure you want to delete constraint '%1'? column dialog - Etes-vous sûr de vouloir supprimer la contrainte '%1'? + Etes-vous sûr de vouloir supprimer la contrainte « %1 » ? @@ -674,8 +674,8 @@ This constraint is not officially supported by SQLite 2, but it's okay to use it. - Cette contrainte n'est pas supportée officiellement par SQLite 2, -mais c'est OK pour l'utiliser. + Cette contrainte n’est pas supportée officiellement par SQLite 2, +mais c’est OK pour l’utiliser. @@ -772,7 +772,7 @@ mais c'est OK pour l'utiliser. Enter a name of the constraint. - Saississez le nom d'une contrainte. + Saississez le nom d’une contrainte. @@ -963,7 +963,7 @@ mais c'est OK pour l'utiliser. <p>When the data is read into grid view columns width is automatically adjusted. This value limits the initial width for the adjustment, but user can still resize the column manually over this limit.</p> - <p>Lorsque les données sont lues dans le tableau la largeur est automatiquement ajustée. Cette valeur limite la largeur initialepour l'ajustement, mais l'utilisateur peut recadrer les colonnes manuellement audessus de cette limite.</p> + <p>Lorsque les données sont lues dans le tableau la largeur est automatiquement ajustée. Cette valeur limite la largeur initialepour l’ajustement, mais l’utilisateur peut recadrer les colonnes manuellement audessus de cette limite.</p> @@ -1020,17 +1020,17 @@ mais c'est OK pour l'utiliser. Number of DDL changes kept in history. - Nombre de DDL modifiés gardés dans l'historique. + Nombre de DDL modifiés gardés dans l’historique. DDL history size: - Dimension de l'historique DDL: + Dimension de l’historique DDL: Don't show DDL preview dialog when commiting schema changes - Ne pas montrer la présualisation DDL pendant l'enregistrement de schéma modifié + Ne pas montrer la présualisation DDL pendant l’enregistrement de schéma modifié @@ -1041,17 +1041,17 @@ mais c'est OK pour l'utiliser. Number of queries kept in the history. - Nombre de requêtes gardées dans l'historique. + Nombre de requêtes gardées dans l’historique. History size: - Dimension de l'historique: + Dimension de l’historique: <p>If there is more than one query in the SQL editor window, then (if this option is enabled) only a single query will be executed - the one under the keyboard insertion cursor. Otherwise all queries will be executed. You can always limit queries to be executed by selecting those queries before calling to execute.</p> - <p>S'il y a plus d'une requête dans l'éditeur d'SQL, alors (si cette option est permise) seulement une seule requête sera exécutée -cellesous le curseur d'insertion. Autrement toutes les requêtes seront exécutées. Vous pouvez limiter le nombre de requêtes devant être exécutées en sélectionnant ces requêtes avant leur exécution.</p> + <p>S’il y a plus d’une requête dans l’éditeur d’SQL, alors (si cette option est permise) seulement une seule requête sera exécutée -cellesous le curseur d’insertion. Autrement toutes les requêtes seront exécutées. Vous pouvez limiter le nombre de requêtes devant être exécutées en sélectionnant ces requêtes avant leur exécution.</p> @@ -1102,7 +1102,7 @@ mais c'est OK pour l'utiliser. Changing language requires application restart to take effect. - Le changement de langage requiére le redemarrage de l'application pour prendre effet. + Le changement de langage requiére le redemarrage de l’application pour prendre effet. @@ -1132,7 +1132,7 @@ mais c'est OK pour l'utiliser. If switched off, then columns will be sorted in the order they are typed in CREATE TABLE statement. - Sur off, les colonnes seront triées dans l'ordre de saisie de l'instruction CREATE TABLE. + Sur off, les colonnes seront triées dans l’ordre de saisie de l’instruction CREATE TABLE. @@ -1167,7 +1167,7 @@ mais c'est OK pour l'utiliser. Virtual tables will be marked with a 'virtual' label. - Les tables vituelles seront marquées avec un label virtuel. + Les tables vituelles seront marquées avec un label « virtuel ». @@ -1182,12 +1182,12 @@ mais c'est OK pour l'utiliser. If this option is switched off, then objects will be sorted in order they appear in sqlite_master table (which is in order they were created) - Si cette option est déactivée, les objets seront triés pour qu' ils apparaissent dans la table sqlite_master (dans l'ordre de création) + Si cette option est déactivée, les objets seront triés pour qu’ ils apparaissent dans la table sqlite_master (dans l’ordre de création) Sort objects (tables, indexes, triggers and views) alphabetically - Tri d'objets (tables, index, déclancheurs et vues) en alpha + Tri d’objets (tables, index, déclancheurs et vues) en alpha @@ -1202,12 +1202,12 @@ mais c'est OK pour l'utiliser. When enabled, Table Windows will show up with the data tab, instead of the structure tab. - Lorsque c'est permis, la fenêtre des tables sera affichée avec l'onglet des données, à la place de l'onglet structure. + Lorsque c’est permis, la fenêtre des tables sera affichée avec l’onglet des données, à la place de l’onglet structure. Open Table Windows with the data tab for start - Ourerture la fenêtre de table avec l'onglet des données au départ + Ourerture la fenêtre de table avec l’onglet des données au départ @@ -1217,12 +1217,12 @@ mais c'est OK pour l'utiliser. When enabled, View Windows will show up with the data tab, instead of the structure tab. - Lorsque c'est permis, la fenêtre des vues sera affichée avec l'onglet des données, à la place de l'onglet structure. + Lorsque c’est permis, la fenêtre des vues sera affichée avec l’onglet des données, à la place de l’onglet structure. Open View Windows with the data tab for start - Ourerture la fenêtre de vue avec l'onglet des données au départ + Ourerture la fenêtre de vue avec l’onglet des données au départ @@ -1272,7 +1272,7 @@ mais c'est OK pour l'utiliser. SQL editor font - Police de l'éditeur SQL + Police de l’éditeur SQL @@ -1297,7 +1297,7 @@ mais c'est OK pour l'utiliser. SQL editor colors - Couleurs de l'éditeur SQL + Couleurs de l’éditeur SQL @@ -1317,7 +1317,7 @@ mais c'est OK pour l'utiliser. <p>Bind parameters are placeholders for values yet to be provided by the user. They have one of the forms:</p><ul><li>:param_name</li><li>$param_name</li><li>@param_name</li><li>?</li></ul> - <p>Les paramètres fournis par l'utilisateur sont passés par valeur. Ils ont l'une de ces formes:</p><ul><li>:param_name</li><li>$param_name</li><li>@param_name</li><li>?</li></ul> + <p>Les paramètres fournis par l’utilisateur sont passés par valeur. Ils ont l’une de ces formes:</p><ul><li>:param_name</li><li>$param_name</li><li>@param_name</li><li>?</li></ul> @@ -1382,7 +1382,7 @@ mais c'est OK pour l'utiliser. <p>Any data changes will be outlined with this color, until they're commited to the database.</p> - <p>Touts les modifications de données seront écrits avec cette couleur,à l'enregistrement de la base de données.</p> + <p>Touts les modifications de données seront écrits avec cette couleur,à l’enregistrement de la base de données.</p> @@ -1392,12 +1392,12 @@ mais c'est OK pour l'utiliser. <p>In case of error while commiting data changes, the problematic cell will be outlined with this color.</p> - <p>En cas de l'erreur à l'enregistrement des modifications de données, la cellule problématique sera indiquée avec cette couleur.</p> + <p>En cas de l’erreur à l’enregistrement des modifications de données, la cellule problématique sera indiquée avec cette couleur.</p> Commit error outline color - Erreur d'enregistrement du surlignage + Erreur d’enregistrement du surlignage @@ -1417,7 +1417,7 @@ mais c'est OK pour l'utiliser. <p>Additional labels are those which tell you SQLite version, number of objects deeper in the tree, etc.</p> - <p>Des labels supplémentaires indique la version SQLITE, le nombre d'objets au nieau inférieur, etc.</p> + <p>Des labels supplémentaires indique la version SQLITE, le nombre d’objets au nieau inférieur, etc.</p> @@ -1432,7 +1432,7 @@ mais c'est OK pour l'utiliser. Information message foreground - Message d'information devant + Message d’information devant @@ -1442,7 +1442,7 @@ mais c'est OK pour l'utiliser. Error message foreground - Message d'erreur devant + Message d’erreur devant @@ -1494,7 +1494,7 @@ mais c'est OK pour l'utiliser. Plugins are loaded/unloaded immediately when checked/unchecked, but modified list of plugins to load at startup is not saved until you commit the whole configuration dialog. - Les plugins sont chargés/déchargés immédiatement avec vérifié/non vérifié, mais les modifications de la liste de plugins à charger au lancement ne sont pas enregistrées avant l'enregistrement de la configuration entière. + Les plugins sont chargés/déchargés immédiatement avec vérifié/non vérifié, mais les modifications de la liste de plugins à charger au lancement ne sont pas enregistrées avant l’enregistrement de la configuration entière. @@ -1807,7 +1807,7 @@ mais c'est OK pour l'utiliser. Total number of rows is being counted. Browsing other pages will be possible after the row counting is done. - Le total des lignes en cours de comptage. La navigation d'autres pages à la fin du comptage. + Le total des lignes en cours de comptage. La navigation d’autres pages à la fin du comptage. @@ -1870,12 +1870,12 @@ Browsing other pages will be possible after the row counting is done. Enter valid and writable file path. - Saississez le chemin d'un fichier valide et en écriture. + Saississez le chemin d’un fichier valide et en écriture. Entered file exists and will be overwritten. - Le fichier remplacera l'existant. + Le fichier remplacera l’existant. @@ -1905,7 +1905,7 @@ Browsing other pages will be possible after the row counting is done. Following error occurred while converting SQL statements to the target SQLite version: - L'erreur suivante est survenue lors de la conversion des déclarations SQL dans cible version SQLite: + L’erreur suivante est survenue lors de la conversion des déclarations SQL dans cible version SQLite: @@ -2067,7 +2067,7 @@ Browsing other pages will be possible after the row counting is done. Are you sure you want to delete index %1? - Confirmez la suppression de l'indexe %1? + Confirmez la suppression de l’indexe %1? @@ -2092,7 +2092,7 @@ Browsing other pages will be possible after the row counting is done. Error while dropping %1: %2 - Erreur à l'abandon %1: %2 + Erreur à l’abandon %1: %2 @@ -2140,7 +2140,7 @@ Browsing other pages will be possible after the row counting is done. Add a database - Ajout d'une base de données + Ajout d’une base de données @@ -2185,7 +2185,7 @@ Browsing other pages will be possible after the row counting is done. Integrity check - Contrôle d'intégrité + Contrôle d’intégrité @@ -2225,7 +2225,7 @@ Browsing other pages will be possible after the row counting is done. Reset autoincrement sequence - Réinitialise l'autoincrémentation + Réinitialise l’autoincrémentation @@ -2338,7 +2338,7 @@ Browsing other pages will be possible after the row counting is done. Entry with name %1 already exists in group %2. - L'entrée nommée %1 existe déjà dans le group %2. + L’entrée nommée %1 existe déjà dans le group %2. @@ -2360,24 +2360,24 @@ Tous les objets de ce groupe seront déplacés dans le groupe parent. Are you sure you want to delete database '%1'? - Etes-vous certain de vouloir supprimer la base de données: %1? + Etes-vous certain de vouloir supprimer la base de données: « %1 » ? Cannot import, because no import plugin is loaded. - Import impossible, car aucun plugin d'import n'est chargé. + Import impossible, car aucun plugin d’import n’est chargé. Cannot export, because no export plugin is loaded. - Export impossible, car aucun plugin d'import n'est chargé. + Export impossible, car aucun plugin d’import n’est chargé. Error while executing VACUUM on the database %1: %2 - Erreur pendant l'exécution de VACCUM sur la base de données %1: %2 + Erreur pendant l’exécution de VACCUM sur la base de données %1: %2 @@ -2387,31 +2387,31 @@ Tous les objets de ce groupe seront déplacés dans le groupe parent. Integrity check (%1) - Contrôle d'intégrité (%1) + Contrôle d’intégrité (%1) Reset autoincrement - Remise à zéro de l'autoincrément + Remise à zéro de l’autoincrément Are you sure you want to reset autoincrement value for table '%1'? - Etes-vous certain de vouloir réinitialiser l'outoincrémentation de la table %1? + Etes-vous certain de vouloir réinitialiser l’outoincrémentation de la table « %1 » ? An error occurred while trying to reset autoincrement value for table '%1': %2 - Une erreur est survenue pendant la réinitialisation de la valeur de l'autoincrémentation de la table '%1': %2 + Une erreur est survenue pendant la réinitialisation de la valeur de l’autoincrémentation de la table « %1 » : %2 Autoincrement value for table '%1' has been reset successfly. - La valeur de l'autoincrémentaion de la table %1 a été réinitialisé avec succès. + La valeur de l’autoincrémentaion de la table %1 a été réinitialisé avec succès. - Are you sure you want to delete all data from table '%1'? + Are you sure you want to delete all data from table « %1 » ? @@ -2437,7 +2437,7 @@ Tous les objets de ce groupe seront déplacés dans le groupe parent. Remainig objects from deleted group will be moved in place where the group used to be. - Les objets restants du groupe supprimé seront déplacés où le groupe a eu l'habitude d'être. + Les objets restants du groupe supprimé seront déplacés où le groupe a eu l’habitude d’être. @@ -2589,8 +2589,8 @@ Tous les objets de ce groupe seront déplacés dans le groupe parent. Following object already exists in the target database. Please enter new, unique name, or press '%1' to abort the operation: - L'objet suivant existe déjà dans la base de données cible. -Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interrompre l'opération : + L’objet suivant existe déjà dans la base de données cible. +Entrez SVP un nouveau nom, unique, ou cliquez « %1 » pour d’interrompre l’opération : @@ -2600,7 +2600,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Following error occurred while converting SQL statements to the target SQLite version: - L'erreur suivante est survenue en convertissant des déclarations de SQL de la version cible SQLite : + L’erreur suivante est survenue en convertissant des déclarations de SQL de la version cible SQLite : @@ -2621,7 +2621,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro -- Date and time of execution: %3 %4 -- Requête éxécutée sur la base de données %1(%2) --- Date et heure d'exécution: %3 +-- Date et heure d’exécution: %3 %4 @@ -2698,7 +2698,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Clear execution history sql editor - Vider l'historique d'exécution + Vider l’historique d’exécution @@ -2710,7 +2710,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Create view from query sql editor - Créer une vue à partir d'une requête + Créer une vue à partir d’une requête @@ -2726,13 +2726,13 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Show next tab sql editor - Afficher l'onglet suivant + Afficher l’onglet suivant Show previous tab sql editor - Afficher l'onget précédent + Afficher l’onget précédent @@ -2744,7 +2744,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Focus SQL editor above sql editor - Focus sur l'éditeur SQL ci-dessus + Focus sur l’éditeur SQL ci-dessus @@ -2764,27 +2764,27 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Clear execution history - Supprimer l'historique d'exécution + Supprimer l’historique d’exécution Are you sure you want to erase the entire SQL execution history? This cannot be undone. - Etes vous certain de vouloir supprimer la totalité de l'historique d'exécution SQL? Aucun retour possible. + Etes vous certain de vouloir supprimer la totalité de l’historique d’exécution SQL? Aucun retour possible. Cannot export, because no export plugin is loaded. - Impossible d'exporter, car aucun plugin d'expertation n'est chargés. + Impossible d’exporter, car aucun plugin d’expertation n’est chargés. No database selected in the SQL editor. Cannot create a view for unknown database. - Aucune base de données den sélectionnée dans l'éditeur SQL. Impossible de créer une vue sur une base de données inconnue. + Aucune base de données den sélectionnée dans l’éditeur SQL. Impossible de créer une vue sur une base de données inconnue. Editor window "%1" has uncommited data. - Fenêtre d'éditeur "%1" n'a pas enregistrer les données. + Fenêtre d’éditeur "%1" n’a pas enregistrer les données. @@ -2855,7 +2855,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro When this option is unchecked, then only table DDL (CREATE TABLE statement) is exported. - Lorsque cette option n'est contrôlée, alors seulement le DDL de la table (CREATE TABLE...) est exporté. + Lorsque cette option n’est contrôlée, alors seulement le DDL de la table (CREATE TABLE...) est exporté. @@ -2875,7 +2875,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Note, that exporting table indexes and triggers may be unsupported by some output formats. - Notez, ces index de table d'exportation et les déclencheurs peuvent être non supportées par quelques formats de sortie. + Notez, ces index de table d’exportation et les déclencheurs peuvent être non supportées par quelques formats de sortie. @@ -2921,7 +2921,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Export format - Format d'exportation + Format d’exportation @@ -2931,7 +2931,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Exported file path - Chemin du fichier d'exportation + Chemin du fichier d’exportation @@ -2973,7 +2973,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Enter valid query to export. - Saississez une requête valide à exporter. + Saississez une requête valide à exporter. @@ -2983,22 +2983,22 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro You must provide a file name to export to. - Vous devez fournir le nom d'un fichier à exporter. + Vous devez fournir le nom d’un fichier à exporter. Path you provided is an existing directory. You cannot overwrite it. - Le chemin fourni est un répertoire existant. Vous ne pouvez pas l'écraser. + Le chemin fourni est un répertoire existant. Vous ne pouvez pas l’écraser. The directory '%1' does not exist. - Le répertoire %1 n'existe pas. + Le répertoire « %1 » n’existe pas. The file '%1' exists and will be overwritten. - Le fichier '%1' existe et sera écrasé. + Le fichier « %1 » existe et sera écrasé. @@ -3013,7 +3013,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Internal error during export. This is a bug. Please report it. - Erreur interne pendant l'exportation. c'est un bug. SVP veuillez le reporter. + Erreur interne pendant l’exportation. c’est un bug. SVP veuillez le reporter. @@ -3134,18 +3134,18 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Initialization code: - Code d'initialisation: + Code d’initialisation: Function implementation code: - Fonction de code d'implémentation: + Fonction de code d’implémentation: Final step implementation code: - Etape finale de code d'implémentaion: + Etape finale de code d’implémentaion: @@ -3185,22 +3185,22 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Rename function argument - Renomme l'argument de la fonction + Renomme l’argument de la fonction Delete function argument - Supprime l'argument de la fonction + Supprime l’argument de la fonction Move function argument up - Monte l'argument de la fonction + Monte l’argument de la fonction Move function argument down - Descend l'argument de la fonction + Descend l’argument de la fonction @@ -3230,7 +3230,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Enter a non-empty implementation code. - Saississez un code d'implémentation non vide. + Saississez un code d’implémentation non vide. @@ -3241,7 +3241,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Functions editor window has uncommited modifications. - L'éditeur de fonction n'a pas enregistré les modifications. + L’éditeur de fonction n’a pas enregistré les modifications. @@ -3324,7 +3324,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Select import plugin. - Sélectionnez un plugin d'importation. + Sélectionnez un plugin d’importation. @@ -3334,7 +3334,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro The file '%1' does not exist. - Le fichier '%1' n'existe pas. + Le fichier « %1 » n’existe pas. @@ -3344,7 +3344,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Pick file to import from - Sélectionnez le fichier d'importation + Sélectionnez le fichier d’importation @@ -3368,7 +3368,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Partial index condition - Condition partielle d'index + Condition partielle d’index @@ -3398,17 +3398,17 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Tried to open index dialog for closed or inexisting database. - Vous tentez d'ouvrir le dialogue de l'index d'une base de données fermée ou inexistante. + Vous tentez d’ouvrir le dialogue de l’index d’une base de données fermée ou inexistante. Could not process index %1 correctly. Unable to open an index dialog. - Impossible de définir l'index %1 correctement. Ouvrir un dialogue d'index valide. + Impossible de définir l’index %1 correctement. Ouvrir un dialogue d’index valide. Pick the table for the index. - Sélectionnez la table pour l'index. + Sélectionnez la table pour l’index. @@ -3448,7 +3448,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro An error occurred while executing SQL statements: %1 - Une erreur survenue à l'exécution de l'SQL: + Une erreur survenue à l’exécution de l’SQL: %1 @@ -3470,12 +3470,12 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Database toolbar - Barre d'outils de base de données + Barre d’outils de base de données Structure toolbar - Barre d'outils de structure + Barre d’outils de structure @@ -3490,7 +3490,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro View toolbar - Barre d'outils vues + Barre d’outils vues @@ -3510,7 +3510,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Running in debug mode. Press %1 or use 'Help / Open debug console' menu entry to open the debug console. - Passage en mode débogue. Cliquez %1 ou utilisez l'entrée du menu ' l'Aide / Ouvrir la console de débogage'. + Passage en mode débogue. Cliquez %1 ou utilisez l’entrée du menu « l’Aide / Ouvrir la console de débogage ». @@ -3520,7 +3520,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro You need to restart application to make the language change take effect. - Vous devez relancer l'application pour que le langage prenne effet. + Vous devez relancer l’application pour que le langage prenne effet. @@ -3595,7 +3595,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Close selected window - Fermeture fenêtre sélectionnée + Fermeture fenêtre sélectionnée @@ -3640,7 +3640,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro About - Apropos + À propos de… @@ -3670,7 +3670,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Report history - Raport d'historique + Rapport d’historique @@ -3721,12 +3721,12 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Cannot export, because no export plugin is loaded. - Exportation impossible, aucun plugin d'exportation n'est chargé. + Exportation impossible, aucun plugin d’exportation n’est chargé. Cannot import, because no import plugin is loaded. - Importation impossible, aucun plugin d'importation n'est chargé. + Importation impossible, aucun plugin d’importation n’est chargé. @@ -3761,7 +3761,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Could not add database %1 to list. - Impossible d'ajouter la base de données %1 à la liste. + Impossible d’ajouter la base de données %1 à la liste. @@ -3793,12 +3793,12 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Configure editors for this data type - Configurer l'éditeur pour ce type de données + Configurer l’éditeur pour ce type de données Data editor plugin '%1' not loaded, while it is defined for editing '%1' data type. - Plugin d"éditeur de données '%1' non chargé, ausii il n'ai pas défini pourle type de données '%1'. + Plugin d"éditeur de données « %1 » non chargé, ausii il n’ai pas défini pourle type de données « %1 ». @@ -3999,7 +3999,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro The update will be automatically downloaded and installed. This will also restart application at the end. - La mise à jour sera automatiquement téléchargée et installée. Un redémarrage de l'application sera aussi effectué à la fin. + La mise à jour sera automatiquement téléchargée et installée. Un redémarrage de l’application sera aussi effectué à la fin. @@ -4094,17 +4094,17 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Cannot edit columns that are result of compound %1 statements (one that includes %2, %3 or %4 keywords). - impossible d'éditer les colonnes qui ont le résultat composé des déclarations %1 (inclus %2, %3 ou %4 mots-clés). + impossible d’éditer les colonnes qui ont le résultat composé des déclarations %1 (inclus %2, %3 ou %4 mots-clés). The query execution mechanism had problems with extracting ROWID's properly. This might be a bug in the application. You may want to report this. - Le mécanisme d'exécution de la requête a eu des problèmes avec l'extraction du ROWID'S. Ceci pourrait être un bogue de l'application. Vous pouvez le rapporter. + Le mécanisme d’exécution de la requête a eu des problèmes avec l’extraction du ROWID’S. Ceci pourrait être un bogue de l’application. Vous pouvez le rapporter. Requested column is a result of SQL expression, instead of a simple column selection. Such columns cannot be edited. - La colonne demandée est un résultat d'expression de SQL, au lieu d'une sélection de colonne simple. De telles colonnes ne peuvent pas être éditées. + La colonne demandée est un résultat d’expression de SQL, au lieu d’une sélection de colonne simple. De telles colonnes ne peuvent pas être éditées. @@ -4114,22 +4114,22 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Cannot edit results of query other than %1. - Impossible d'éditer les résultats de la requëte autrement que %1. + Impossible d’éditer les résultats de la requëte autrement que %1. Cannot edit columns that are result of aggregated %1 statements. - Impossible d'éditer les colonnes qui sont le résultat de déclarations agrégées %1. + Impossible d’éditer les colonnes qui sont le résultat de déclarations agrégées %1. Cannot edit columns that are result of %1 statement. - Impossible d'éditer les colonnesqui sont le résultat de déclaration %1. + Impossible d’éditer les colonnesqui sont le résultat de déclaration %1. Cannot edit columns that are result of common table expression statement (%1). - Impossible d'éditer les colonnes qui sont le résultat de table commune de déclaration (%1). + Impossible d’éditer les colonnes qui sont le résultat de table commune de déclaration (%1). @@ -4191,7 +4191,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Rollback changes to cell(s) contents - Annule les modifications de cellule(s) + Annule les modifications de cellule(s) @@ -4246,7 +4246,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Delete selected item - Suppression de l'item sélectionné + Suppression de l’item sélectionné @@ -4276,7 +4276,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Copy selected item(s) - Copie d'item(s) sélectionné(s) + Copie d’item(s) sélectionné(s) @@ -4313,7 +4313,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Data form view - Formulaire vue de données + Formulaire vue de données @@ -4363,7 +4363,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Open SQL editor - Ouvrir l'éditeur SQL + Ouvrir l’éditeur SQL @@ -4438,7 +4438,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Select whole editor contents - Sélectionnez le contenu entier de l'éditeur + Sélectionnez le contenu entier de l’éditeur @@ -4448,7 +4448,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Load contents from a file - Charger le contenu d'un fichier + Charger le contenu d’un fichier @@ -4524,17 +4524,17 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Reports history window - Fenêtre d'historique + Fenêtre d’historique Delete selected entry - Effacer l'entrée sélectionnée + Effacer l’entrée sélectionnée SQL editor window - Fenêtre de l'éditeur SQL + Fenêtre de l’éditeur SQL @@ -4559,12 +4559,12 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Go to next editor tab - Aller à l'onglet d'éditeur suivant + Aller à l’onglet d’éditeur suivant Go to previous editor tab - Aller à l'onglet d'éditeur précédent + Aller à l’onglet d’éditeur précédent @@ -4639,12 +4639,12 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Edit selected index - Modifie l'index sélectionné + Modifie l’index sélectionné Delete selected index - Supprime l'index sélectionné + Supprime l’index sélectionné @@ -4673,13 +4673,13 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Go to next tab - Aller à l'onglet suivant + Aller à l’onglet suivant Go to previous tab - Aller à l'onglet précédent + Aller à l’onglet précédent @@ -4689,7 +4689,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Refresh view trigger list - Actualise l'affichage de la liste des déclencheur + Actualise l’affichage de la liste des déclencheur @@ -4704,7 +4704,7 @@ Entrez SVP un nouveau nom, unique, ou cliquez '%1' pour d'interro Are you sure you want to quit the application? Following items are pending: - Confirmez la fermeture de l'application: + Confirmez la fermeture de l’application: @@ -4732,7 +4732,7 @@ Following items are pending: Regular expression matching - Correspondance d'expression régulière + Correspondance d’expression régulière @@ -4928,12 +4928,12 @@ recherche suivant Syntax completion can be used only when a valid database is set for the SQL editor. - L'achèvement de syntaxe peut être utilisé seulement quand une base de données valable est utilisée dans l'éditeur SQL. + L’achèvement de syntaxe peut être utilisé seulement quand une base de données valable est utilisée dans l’éditeur SQL. Contents of the SQL editor are huge, so errors detecting and existing objects highlighting are temporarily disabled. - Le contenu l'éditeur SQL est important, aussi la détectiond'objets en erreur est temporairement mise hors de service. + Le contenu l’éditeur SQL est important, aussi la détectiond’objets en erreur est temporairement mise hors de service. @@ -4943,7 +4943,7 @@ recherche suivant Could not open file '%1' for writing: %2 - Impossible d'ouvrir en écriture le fichier '%1': %2 + Impossible d’ouvrir en écriture le fichier « %1 » : %2 @@ -4958,7 +4958,7 @@ recherche suivant Could not open file '%1' for reading: %2 - Impossible d'ouvrir en lecture le fichier '%1': %2 + Impossible d’ouvrir en lecture le fichier « %1 » : %2 @@ -4995,7 +4995,7 @@ recherche suivant This cell is not editable, because: %1 - Cette cellule n'est pas modifiable: %1 + Cette cellule n’est pas modifiable: %1 @@ -5038,7 +5038,7 @@ recherche suivant Cannot commit the data for a cell that refers to the already closed database. - Impossible d'enregistrer les données pour la cell qui référe à une base de données déjà fermée. + Impossible d’enregistrer les données pour la cell qui référe à une base de données déjà fermée. @@ -5048,28 +5048,28 @@ recherche suivant An error occurred while commiting the transaction: %1 - Une erreur est survenuelors de l'enregistrement de la transaction: %1 + Une erreur est survenuelors de l’enregistrement de la transaction: %1 An error occurred while rolling back the transaction: %1 - Une erreur est survenuelors de l'annulation de la transaction: %1 + Une erreur est survenuelors de l’annulation de la transaction: %1 Tried to commit a cell which is not editable (yet modified and waiting for commit)! This is a bug. Please report it. - Tentative d'enregistrement d'une une cellule qui n'est pas modifiable! Ceci est un bogue. Rapportez-le SVP. + Tentative d’enregistrement d’une une cellule qui n’est pas modifiable! Ceci est un bogue. Rapportez-le SVP. An error occurred while commiting the data: %1 - Une erreur est survenuelors de l'enregistrement des données: %1 + Une erreur est survenuelors de l’enregistrement des données: %1 Error while executing SQL query on database '%1': %2 - Erreur pendant l'exécution de la requête sur la base de données %1: %2 + Erreur pendant l’exécution de la requête sur la base de données « %1 » : %2 @@ -5122,7 +5122,7 @@ recherche suivant Edit value in editor - Valeur modifiée par l'éditeur + Valeur modifiée par l’éditeur @@ -5185,12 +5185,12 @@ recherche suivant Error while commiting new row: %1 - Erreur à l'nregistrement d'une nouvelle ligne: %1 + Erreur à l’nregistrement d’une nouvelle ligne: %1 Error while deleting row from table %1: %2 - Erreur à la suppression d'une ligne de la table %1: %2 + Erreur à la suppression d’une ligne de la table %1: %2 @@ -5445,7 +5445,7 @@ but it's okay to use them anyway. Import data to table table window - Importer les données d'une table + Importer les données d’une table @@ -5512,7 +5512,7 @@ but it's okay to use them anyway. Reset autoincrement value table window - Réinitialisation de l'incrémentatio, + Réinitialisation de l’incrémentation @@ -5572,7 +5572,7 @@ but it's okay to use them anyway. Refresh index list table window - Actualiser la liste d'index + Actualiser la liste d’index @@ -5596,7 +5596,7 @@ but it's okay to use them anyway. Refresh trigger list table window - Actualiser la liste d'index + Actualiser la liste d’index @@ -5620,7 +5620,7 @@ but it's okay to use them anyway. Are you sure you want to delete column '%1'? table window - Etes-vous certain de vouloir supprimer lla colonne: %1? + Etes-vous certain de vouloir supprimer la colonne : « %1 » ? @@ -5639,12 +5639,12 @@ Voudriez-vous procéder? Could not load data for table %1. Error details: %2 - Impossible de charger les données de table %1. Détails d' erreur: %2 + Impossible de charger les données de table %1. Détails d’ erreur: %2 Could not process the %1 table correctly. Unable to open a table window. - Impossible de lancer correctement la table %1. Impossible d'ouvrir la fenêtre de table. + Impossible de lancer correctement la table %1. Impossible d’ouvrir la fenêtre de table. @@ -5672,7 +5672,7 @@ Voudriez-vous procéder? Could not restore window, because the table %1 doesn't exist in the database %2. - Impossible de restaurer la fenêtre, car la vue %1 n'existe pas dans la base de données %2.. + Impossible de restaurer la fenêtre, car la vue %1 n’existe pas dans la base de données %2.. @@ -5684,27 +5684,27 @@ Voudriez-vous procéder? Could not commit table structure. Error message: %1 table window - Impossible d'enregistrer la structure de table. Message d'erreur: %1 + Impossible d’enregistrer la structure de table. Message d’erreur: %1 Reset autoincrement - Réinitialisation de l'incrémentation + Réinitialisation de l’incrémentation Are you sure you want to reset autoincrement value for table '%1'? - Etes-vous certain de vouloir réinitialiser l'autoincrémentation de la table %1? + Etes-vous certain de vouloir réinitialiser l’autoincrémentation de la table %1? An error occurred while trying to reset autoincrement value for table '%1': %2 - Une erreur est survenue pendant la réinitialisation de la valeur de l'autoincrémentation de la table '%1': %2 + Une erreur est survenue pendant la réinitialisation de la valeur de l’autoincrémentation de la table « %1 »: %2 Autoincrement value for table '%1' has been reset successfly. - La valeur de l'autoincrémentaion de la table %1 a été réinitialisé avec succès. + La valeur de l’autoincrémentaion de la table %1 a été réinitialisé avec succès. @@ -5726,18 +5726,18 @@ Are you sure you want to create a table with blank name? Cannot create table %1, if it has no primary key defined. Either uncheck the %2, or define a primary key. - Impossible de créer la table %1, s'l n'y a pas de clé primaire de définie. Toute fois ne pas contrôler %2 ou définir une clé primaire. + Impossible de créer la table %1, s’il n’y a pas de clé primaire de définie. Toute fois ne pas contrôler %2 ou définir une clé primaire. Cannot use autoincrement for primary key when %1 clause is used. Either uncheck the %2, or the autoincrement in a primary key. - Impossible d'utiliser l'autoincrémentation pour une clé primaire quand la clause %1 est utilisée. Toute fois ne pas contrôler %2, ou utiliser l'autoincrémentation sur une clé primaire. + Impossible d’utiliser l’autoincrémentation pour une clé primaire quand la clause %1 est utilisée. Toute fois ne pas contrôler %2, ou utiliser l’autoincrémentation sur une clé primaire. Are you sure you want to delete table constraint '%1'? table window - Etes-vous sûr de vouloir supprimer la contrainte '%1'? + Etes-vous sûr de vouloir supprimer la contrainte « %1 » ? @@ -5748,12 +5748,12 @@ Are you sure you want to create a table with blank name? Cannot export, because no export plugin is loaded. - Export impossible, car aucun plugin d'import n'est chargé. + Export impossible, car aucun plugin d’import n’est chargé. Cannot import, because no import plugin is loaded. - Import impossible, car aucun plugin d'import n'est chargé. + Import impossible, car aucun plugin d’import n’est chargé. @@ -5764,13 +5764,13 @@ Are you sure you want to create a table with blank name? There are uncommited structure modifications. You cannot browse or edit data until you have table structure settled. Do you want to commit the structure, or do you want to go back to the structure tab? - Il ya des modifications de structure non enregistrées. Vous ne pouvez pas naviguer ou modifier des données jusqu'à ce que vous ailliez installer la structure de table. -Voulez-vous enregistrer la structure, ou voulez-vous retourner à l'onglet de structure ? + Il ya des modifications de structure non enregistrées. Vous ne pouvez pas naviguer ou modifier des données jusqu’à ce que vous ailliez installer la structure de table. +Voulez-vous enregistrer la structure, ou voulez-vous retourner à l’onglet de structure ? Go back to structure tab - Retour à l'onglet de structure + Retour à l’onglet de structure @@ -5799,7 +5799,7 @@ Voulez-vous enregistrer la structure, ou voulez-vous retourner à l'onglet Partial index condition table window indexes - Condition partielle d'index + Condition partielle d’index @@ -5828,17 +5828,17 @@ Voulez-vous enregistrer la structure, ou voulez-vous retourner à l'onglet Table window "%1" has uncommited structure modifications and data. - La fenêtre de table "%1" n'a pas enregistré les modifications de structure et de données. + La fenêtre de table "%1" n’a pas enregistré les modifications de structure et de données. Table window "%1" has uncommited data. - La fenêtre de table "%1" n'a pas enregistrer les données. + La fenêtre de table "%1" n’a pas enregistrer les données. Table window "%1" has uncommited structure modifications. - La fenêtre de table "%1" n'a pas enregistré les modifications de structure. + La fenêtre de table "%1" n’a pas enregistré les modifications de structure. @@ -5886,7 +5886,7 @@ Voulez-vous enregistrer la structure, ou voulez-vous retourner à l'onglet The scope is still not fully supported by the SQLite database. - La portée n'est toujours pas entièrement supportée par la base de données SQLITE. + La portée n’est toujours pas entièrement supportée par la base de données SQLITE. @@ -5901,7 +5901,7 @@ Voulez-vous enregistrer la structure, ou voulez-vous retourner à l'onglet List of columns for UPDATE OF action. - Liste des colonnes pour l'action UPDATE OF. + Liste des colonnes pour l’action UPDATE OF. @@ -5931,7 +5931,7 @@ Voulez-vous enregistrer la structure, ou voulez-vous retourner à l'onglet Could not process trigger %1 correctly. Unable to open a trigger dialog. - Impossible d'exécuter correctement le déclencheur %1. Ouverture invalide du dialogue de déclencheur. + Impossible d’exécuter correctement le déclencheur %1. Ouverture invalide du dialogue de déclencheur. @@ -5953,7 +5953,7 @@ Voulez-vous enregistrer la structure, ou voulez-vous retourner à l'onglet An error occurred while executing SQL statements: %1 - Une erreur survenue lors de l'exécution de l'intruction SQL: %1 + Une erreur survenue lors de l’exécution de l’intruction SQL: %1 @@ -6016,7 +6016,7 @@ Voulez-vous enregistrer la structure, ou voulez-vous retourner à l'onglet Could not restore window, because the view %1 doesn't exist in the database %2. - Impossible de restaurer la fenêtre, car la vue %1 n'existe pas dans la base de données %2.. + Impossible de restaurer la fenêtre, car la vue %1 n’existe pas dans la base de données %2.. @@ -6073,7 +6073,7 @@ Voulez-vous enregistrer la structure, ou voulez-vous retourner à l'onglet Create new trigger view window - Création d'un nouveau déclencheur + Création d’un nouveau déclencheur @@ -6090,22 +6090,22 @@ Voulez-vous enregistrer la structure, ou voulez-vous retourner à l'onglet View window "%1" has uncommited structure modifications and data. - La fenêtre de la vue "%1" n'a pas enregistré les modifications de structure et de données. + La fenêtre de la vue "%1" n’a pas enregistré les modifications de structure et de données. View window "%1" has uncommited data. - La fenêtre de la vue "%1" n'a pas enregistré les modifications de données. + La fenêtre de la vue "%1" n’a pas enregistré les modifications de données. View window "%1" has uncommited structure modifications. - La fenêtre de la vue "%1" n'a pas enregistré les modifications de structure. + La fenêtre de la vue "%1" n’a pas enregistré les modifications de structure. Could not load data for view %1. Error details: %2 - Impossible de charher les données de vue %1. Détails d' erreur: %2 + Impossible de charher les données de vue %1. Détails d’ erreur: %2 @@ -6116,13 +6116,14 @@ Voulez-vous enregistrer la structure, ou voulez-vous retourner à l'onglet There are uncommited structure modifications. You cannot browse or edit data until you have the view structure settled. Do you want to commit the structure, or do you want to go back to the structure tab? - Des modifications de structure n'ont pa été enregistrées. Vous ne pouvez pas naviger ou éditer des données jusqu'à ce que vous installliez la structure de vue. -Voulez-vousenregistrere la structure, ou voulez-vous retourner à l'onglet de structure? + Des modifications de structure n’ont pa été enregistrées. + Vous ne pouvez pas naviger ou éditer des données jusqu’à ce que vous installliez la structure de vue. +Voulez-vous enregistrer la structure, ou voulez-vous retourner à l’onglet de structure ? Go back to structure tab - Retour à l'onlet de structure + Retour à l’onlet de structure @@ -6133,7 +6134,7 @@ Voulez-vousenregistrere la structure, ou voulez-vous retourner à l'onglet Could not commit view changes. Error message: %1 view window - Impossible d'enregistrer les modifivations de vue. Message d'erreur: %1 + Impossible d’enregistrer les modifivations de vue. Message d’erreur: %1 @@ -6162,7 +6163,7 @@ Voulez-vousenregistrere la structure, ou voulez-vous retourner à l'onglet Could not process the %1 view correctly. Unable to open a view window. - Impossible de lancer correctement la vue %1. Impossible d'ouvrir la fenêtre de vue. + Impossible de lancer correctement la vue %1. Impossible d’ouvrir la fenêtre de vue. @@ -6186,11 +6187,11 @@ Details: %1 The view could not be modified due to internal SQLiteStudio error. Please report this! - La vue ne peut être modifiée a cause d'une erreur interne de SQLiteStudio. SVP repportez l'erreur! + La vue ne peut être modifiée a cause d’une erreur interne de SQLiteStudio. SVP repportez l’erreur! - The view code could not be parsed properly for execution. This is a SQLiteStudio's bug. Please report it. + The view code could not be parsed properly for execution. This is a SQLiteStudio’s bug. Please report it. La vue ne être correctement analysée avant exécution.Cest un bug SQLiteStudion. SVP reporter le. diff --git a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_it.qm b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_it.qm new file mode 100644 index 0000000..9dad8df Binary files /dev/null and b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_it.qm differ diff --git a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_it.ts b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_it.ts index 16fc700..2803575 100644 --- a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_it.ts +++ b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_it.ts @@ -1,6 +1,6 @@ - + AboutDialog @@ -586,95 +586,110 @@ - + Add constraint column dialog - + Edit constraint column dialog - - + + Delete constraint column dialog - + Move constraint up column dialog - + Move constraint down column dialog - + Add a primary key column dialog - + Add a foreign key column dialog - + Add an unique constraint column dialog - + Add a check constraint column dialog - + Add a not null constraint column dialog - + Add a collate constraint column dialog - + Add a default constraint column dialog - + Are you sure you want to delete constraint '%1'? column dialog - + Correct the constraint's configuration. - + This constraint is not officially supported by SQLite 2, but it's okay to use it. + + + Scale is not allowed for INTEGER PRIMARY KEY columns. + + + + + Precision cannot be defined without the scale. + + + + + Precision is not allowed for INTEGER PRIMARY KEY columns. + + ColumnDialogConstraintsModel @@ -888,557 +903,616 @@ but it's okay to use it. ConfigDialog - + Configuration - + Search - + General - + Keyboard shortcuts - + Look & feel - + Style - + Fonts - + Colors - + Plugins - + Code formatters - + Data browsing - + Data editors - + + Database dialog window + + + + + <p>When adding new database it is marked to be "permanent" (stored in configuration) by default. Checking this option makes every new database to NOT be "permanent" by default.</p> + + + + + Do not mark database to be "permanent" by default + + + + + <p>When this option is enabled, then files dropped from file manager onto database list will be automatically added to the list, bypassing standard database dialog. If for various reasons automatic process fails, then standard dialog will be presented to the user.</p> + + + + + Try to bypass dialog completly when dropping database file onto the list + + + + Data browsing and editing - + Number of data rows per page: - - + + <p>When the data is read into grid view columns width is automatically adjusted. This value limits the initial width for the adjustment, but user can still resize the column manually over this limit.</p> - + Limit initial data column width to (in pixels): - - Inserting new row in data grid + + <p>When this is enabled and user holds mouse pointer over a cell in any data view (query results, a table data, a view data) a tooltip will appear with details about the cell - it includes details like column data type, constraints, ROWID and others.</p> - - Before currently selected row + + Show column and row details tooltip in data view + + + + + Inserting new row in data grid - - - - General.InsertRowPlacement + + Before currently selected row - + After currently selected row - + At the end of data view - + + <p>When enabled, Table Windows will show up with the data tab, instead of the structure tab.</p> + + + + + <p>When enabled the "Data" tab will be placed as first tab in every Table Window, instead of being at second place.</p> + + + + + Place data tab as first tab in a Table Window + + + + + <p>When enabled, View Windows will show up with the data tab, instead of the structure tab.</p> + + + + + <p>When enabled the "Data" tab will be placed as first tab in every View Window, instead of being at second place.</p> + + + + + Place data tab as first tab in a View Window + + + + Data types - + Available editors: - + Editors selected for this data type: - + Schema editing - + Number of DDL changes kept in history. - + DDL history size: - + Don't show DDL preview dialog when commiting schema changes - + SQL queries - - + + Number of queries kept in the history. - + History size: - + <p>If there is more than one query in the SQL editor window, then (if this option is enabled) only a single query will be executed - the one under the keyboard insertion cursor. Otherwise all queries will be executed. You can always limit queries to be executed by selecting those queries before calling to execute.</p> - + Execute only the query under the cursor - + Updates - + Automatically check for updates at startup - + Session - + Restore last session (active MDI windows) after startup - + + Status Field + + + + + <p>When user manually closes the Status panel, this option makes sure that if any new message is printed in the Status panel it will be reopened. If it's disabled, then Status panel can only be open manually by the user from the "View" menu.</p> + + + + + Always open Status panel when new message is printed + + + + Filter shortcuts by name or key combination - + Action - + Key combination - - + + Language - + Changing language requires application restart to take effect. - + Compact layout - + <p>Compact layout reduces all margins and spacing on the UI to minimum, making space for displaying more data. It makes the interface a little bit less aesthetic, but allows to display more data at once.</p> - + Use compact layout - - General.CompactLayout - - - - + + Database list - + If switched off, then columns will be sorted in the order they are typed in CREATE TABLE statement. - + Sort table columns alphabetically - + Expand tables node when connected to a database - + <p>Additional labels are those displayed next to the names on the databases list (they are blue, unless configured otherwise). Enabling this option will result in labels for databases, invalid databases and aggregated nodes (column group, index group, trigger group). For more labels see options below.<p> - + Display additional labels on the list - + For regular tables labels will show number of columns, indexes and triggers for each of tables. - + Display labels for regular tables - + Virtual tables will be marked with a 'virtual' label. - + Display labels for virtual tables - + Expand views node when connected to a database - + If this option is switched off, then objects will be sorted in order they appear in sqlite_master table (which is in order they were created) - + Sort objects (tables, indexes, triggers and views) alphabetically - + Display system tables and indexes on the list - + Table windows - - When enabled, Table Windows will show up with the data tab, instead of the structure tab. - - - - + Open Table Windows with the data tab for start - + View windows - - When enabled, View Windows will show up with the data tab, instead of the structure tab. - - - - + Open View Windows with the data tab for start - + Main window dock areas - + Left and right areas occupy corners - + Top and bottom areas occupy corners - + Hide built-in plugins - + Current style: - + Preview - + Enabled - + Disabled - + Active formatter plugin - + SQL editor font - + Database list font - + Database list additional label font - + Data view font - + Status field font - + SQL editor colors - + Current line background - + <p>SQL strings are enclosed with single quote characters.</p> - + String foreground - + <p>Bind parameters are placeholders for values yet to be provided by the user. They have one of the forms:</p><ul><li>:param_name</li><li>$param_name</li><li>@param_name</li><li>?</li></ul> - + Bind parameter foreground - + Highlighted parenthesis background - + <p>BLOB values are binary values represented as hexadecimal numbers, like:</p><ul><li>X'12B4'</li><li>x'46A2F4'</li></ul> - + BLOB value foreground - + Regular foreground - + Line numbers area background - + Keyword foreground - + Number foreground - + Comment foreground - + <p>Valid objects are name of tables, indexes, triggers, or views that exist in the SQLite database.</p> - + Valid objects foreground - + Data view colors - + <p>Any data changes will be outlined with this color, until they're commited to the database.</p> - + Uncommited data outline color - + <p>In case of error while commiting data changes, the problematic cell will be outlined with this color.</p> - + Commit error outline color - + NULL value foreground - + Deleted row background - + Database list colors - + <p>Additional labels are those which tell you SQLite version, number of objects deeper in the tree, etc.</p> - + Additional labels foreground - + Status field colors - + Information message foreground - + Warning message foreground - + Error message foreground @@ -1490,43 +1564,43 @@ but it's okay to use it. - + Plugins are loaded/unloaded immediately when checked/unchecked, but modified list of plugins to load at startup is not saved until you commit the whole configuration dialog. - + %1 (built-in) plugins manager in configuration dialog - + Details - + No plugins in this category. - + Add new data type - + Rename selected data type - + Delete selected data type - + Help for configuring data type editors @@ -1678,137 +1752,137 @@ but it's okay to use it. DataView - + Filter data data view - + Grid view - + Form view - + Refresh table data data view - + First page data view - + Previous page data view - + Next page data view - + Last page data view - + Apply filter data view - + Commit changes for selected cells data view - + Rollback changes for selected cells data view - + Show grid view of results sql editor - + Show form view of results sql editor - + Filter by text data view - + Filter by the Regular Expression data view - + Filter by SQL expression data view - + Tabs on top data view - + Tabs at bottom data view - + Place new rows above selected row data view - + Place new rows below selected row data view - + Place new rows at the end of the data view data view - + Total number of rows is being counted. Browsing other pages will be possible after the row counting is done. - + Row: %1 @@ -1930,7 +2004,7 @@ Browsing other pages will be possible after the row counting is done. - + File @@ -1976,47 +2050,47 @@ Browsing other pages will be possible after the row counting is done. - + Browse for existing database file on local computer - + Browse - + Enter an unique database name. - + This name is already in use. Please enter unique name. - + Enter a database file path. - + This database is already on the list under name: %1 - + Select a database type. - + Auto-generated - + Type the name @@ -2065,9 +2139,31 @@ Browsing other pages will be possible after the row counting is done. + Error while dropping %1: %2 + + + Delete objects + + + + + Are you sure you want to delete following objects: +%1 + + + + + Cannot start transaction. Details: %1 + + + + + Cannot commit transaction. Details: %1 + + DbTree @@ -2082,343 +2178,349 @@ Browsing other pages will be possible after the row counting is done. - + Copy - + Paste - + Select all - + Create a group - + Delete the group - + Rename the group - + Add a database - + Edit the database - + Remove the database - + Connect to the database - + Disconnect from the database - + Import - + Export the database - + Convert database type - + Vacuum - + Integrity check - + Create a table - + Edit the table - + Delete the table - + Export the table - + Import into the table - + Populate table - + Create similar table - + Reset autoincrement sequence - + Create an index - + Edit the index - + Delete the index - + Create a trigger - + Edit the trigger - + Delete the trigger - + Create a view - + Edit the view - + Delete the view - + Add a column - + Edit the column - + Delete the column - + Delete selected items - + Clear filter - + Refresh all database schemas - + Refresh selected database schema - - + + Erase table data - - + + Database - + Grouping - - + + Generate query for table + + + + + Create group - + Group name - + Entry with name %1 already exists in group %2. - + Delete group - + Are you sure you want to delete group %1? All objects from this group will be moved to parent group. - - Delete database + + Are you sure you want to remove database '%1' from the list? - - Are you sure you want to delete database '%1'? + + Are you sure you want to remove following databases from the list: +%1 - - - Cannot import, because no import plugin is loaded. + + Remove database - - - Cannot export, because no export plugin is loaded. + + Vacuum (%1) - - Error while executing VACUUM on the database %1: %2 + + + Cannot import, because no import plugin is loaded. + - VACUUM execution finished successfully. + Cannot export, because no export plugin is loaded. - + Integrity check (%1) - + Reset autoincrement - + Are you sure you want to reset autoincrement value for table '%1'? - + An error occurred while trying to reset autoincrement value for table '%1': %2 - + Autoincrement value for table '%1' has been reset successfly. - + Are you sure you want to delete all data from table '%1'? - + An error occurred while trying to delete data from table '%1': %2 - + All data has been deleted for table '%1'. - + Following objects will be deleted: %1. - + Following databases will be removed from list: %1. - + Remainig objects from deleted group will be moved in place where the group used to be. - + %1<br><br>Are you sure you want to continue? - + Delete objects @@ -2453,123 +2555,128 @@ All objects from this group will be moved to parent group. DbTreeModel - + Database: %1 dbtree tooltip - + Version: dbtree tooltip - + File size: dbtree tooltip - + Encoding: dbtree tooltip - + Error: dbtree tooltip - + Table : %1 dbtree tooltip - + Columns (%1): dbtree tooltip - + Indexes (%1): dbtree tooltip - + Triggers (%1): dbtree tooltip - + Copy - + Move - + Include data - + Include indexes - + Include triggers - + Abort - + + Could not add dropped database file '%1' automatically. Manual setup is necessary. + + + + Referenced tables - + Do you want to include following referenced tables as well: %1 - + Name conflict - + Following object already exists in the target database. Please enter new, unique name, or press '%1' to abort the operation: - + SQL statements conversion - + Following error occurred while converting SQL statements to the target SQLite version: - + Would you like to ignore those errors and proceed? @@ -3320,124 +3427,197 @@ Please enter new, unique name, or press '%1' to abort the operation: - + On table: - + Index name: - + Partial index condition - + Unique index - + Column - + Collation - + Sort - + + Delete selected indexed expression + + + + + Moves selected index column up in the order, making it more significant in the index. + + + + + Moves selected index column down in the order, making it less significant in the index. + + + + + Edit selected indexed expression + + + + + Add indexed expression + + + + DDL - + Tried to open index dialog for closed or inexisting database. - + Could not process index %1 correctly. Unable to open an index dialog. - + + Unique index cannot have indexed expressions. Either remove expressions from list below, or uncheck this option. + + + + Pick the table for the index. - + Select at least one column. - + Enter a valid condition. - + default index dialog - + Sort order table constraints - - + + Error index dialog - + Cannot create unique index, because values in selected columns are not unique. Would you like to execute SELECT query to see problematic values? - + An error occurred while executing SQL statements: %1 - LanguageDialog + IndexExprColumnDialog - - Language + + Indexed expression - - Please choose language: + + Expression to index - - - MainWindow - - Database toolbar + + This expression is already indexed by the index. - - Structure toolbar + + Column should be indexed directly, not by expression. Either extend this expression to contain something more than just column name, or abort and select this column in index dialog directly. + + + + + Column '%1' does not belong to the table covered by this index. Indexed expressions can refer only to columns from the indexed table. + + + + + It's forbidden to use 'SELECT' statements in indexed expressions. + + + + + Enter an indexed expression. + + + + + Invalid expression. + + + + + LanguageDialog + + + Language + + + + + Please choose language: + + + + + MainWindow + + + Database toolbar + + + + + Structure toolbar @@ -3456,273 +3636,273 @@ Please enter new, unique name, or press '%1' to abort the operation: - + Configuration widgets - + Syntax highlighting engines - + Data editors - + Running in debug mode. Press %1 or use 'Help / Open debug console' menu entry to open the debug console. - + Running in debug mode. Debug messages are printed to the standard output. - + You need to restart application to make the language change take effect. - + Open SQL editor - + Open DDL history - + Open SQL functions editor - + Open collations editor - + Import - + Export - + Open configuration dialog - + Tile windows - + Tile windows horizontally - + Tile windows vertically - + Cascade windows - + Next window - + Previous window - + Hide status field - + Close selected window - + Close all windows but selected - + Close all windows - + Restore recently closed window - + Rename selected window - + Open Debug Console - + Open CSS Console - + Report a bug - + Propose a new feature - + About - + Licenses - + Open home page - + Open forum page - + User Manual - + SQLite documentation - + Report history - + Check for updates - + Database menubar - + Structure menubar - + View menubar - + Window list menubar view menu - + Tools menubar - + Help - + Could not set style: %1 main window - + Cannot export, because no export plugin is loaded. - + Cannot import, because no import plugin is loaded. - + Rename window - + Enter new name for the window: - + New updates are available. <a href="%1">Click here for details</a>. - + You're running the most recent version. No updates are available. - + Database passed in command line parameters (%1) was already on the list under name: %2 - + Database passed in command line parameters (%1) has been temporarily added to the list under name: %2 - + Could not add database %1 to list. @@ -4122,127 +4302,127 @@ Please enter new, unique name, or press '%1' to abort the operation: - + Data grid view - + Copy cell(s) contents to clipboard - + Paste cell(s) contents from clipboard - + Set empty value to selected cell(s) - + Set NULL value to selected cell(s) - + Commit changes to cell(s) contents - + Rollback changes to cell(s) contents - + Delete selected data row - + Insert new data row - + Open contents of selected cell in a separate editor - + Total pages available: %1 - + Total rows loaded: %1 - + Data view (both grid and form) - + Refresh data - + Switch to grid view of the data - + Switch to form view of the data - + Database list - + Delete selected item - + Clear filter contents - + Refresh schema - + Refresh all schemas - + Add database - + Select all items - + Copy selected item(s) - + Paste from clipboard @@ -4468,6 +4648,11 @@ Please enter new, unique name, or press '%1' to abort the operation:Copy selected block of text and paste it a line above + + + Toggle comment + + All SQLite databases @@ -4540,106 +4725,106 @@ Please enter new, unique name, or press '%1' to abort the operation: - + Table window - + Refresh table structure - + Add new column - + Edit selected column - + Delete selected column - + Export table data - + Import data to the table - + Add new table constraint - + Edit selected table constraint - + Delete selected table constraint - + Refresh table index list - + Add new index - + Edit selected index - + Delete selected index - + Refresh table trigger list - + Add new trigger - + Edit selected trigger - + Delete selected trigger - + Go to next tab - + Go to previous tab @@ -4883,47 +5068,53 @@ find next - + + Toggle comment + sql editor + + + + Could not open file '%1' for writing: %2 - + Saved SQL contents to file: %1 - + Syntax completion can be used only when a valid database is set for the SQL editor. - + Contents of the SQL editor are huge, so errors detecting and existing objects highlighting are temporarily disabled. - + Save to file - + SQL scripts (*.sql);;All files (*) - + Open file - + Could not open file '%1' for reading: %2 - + Reached the end of document. Hit the find again to restart the search. @@ -4931,36 +5122,36 @@ find next SqlQueryItem - + Column: data view tooltip - + Data type: data view - + Table: data view tooltip - + Constraints: data view tooltip - + This cell is not editable, because: %1 - + Cannot load the data for a cell that refers to the already closed database. @@ -4968,83 +5159,88 @@ find next SqlQueryItemDelegate - - + + Cannot edit this cell. Details: %2 - + The row is marked for deletion. + + + Foreign key for column %2 has more than %1 possible values. It's too much to display in drop down list. You need to edit value manually. + + SqlQueryModel - - + + Only one query can be executed simultaneously. - + Uncommited data - + There are uncommited data changes. Do you want to proceed anyway? All uncommited changes will be lost. - + Cannot commit the data for a cell that refers to the already closed database. - + Could not begin transaction on the database. Details: %1 - + An error occurred while commiting the transaction: %1 - + An error occurred while rolling back the transaction: %1 - + Tried to commit a cell which is not editable (yet modified and waiting for commit)! This is a bug. Please report it. - + An error occurred while commiting the data: %1 - - + + Error while executing SQL query on database '%1': %2 - + Error while loading query results: %1 - + Insert multiple rows - + Number of rows to insert: @@ -5052,92 +5248,117 @@ find next SqlQueryView - + + Go to referenced row in... + + + + Copy - + Copy as... - + Paste - + Paste as... - + Set NULL values - + Erase values - + Edit value in editor - + Commit - + Rollback - + Commit selected cells - + Rollback selected cells - + Define columns to sort by - + Remove custom sorting - + Insert row - + Insert multiple rows - + Delete selected row - + + Generate query for selected cells + + + + No items selected to paste clipboard contents to. - + + Go to referenced row in table '%1' + + + + + table '%1' + + + + + Referenced row (%1) + + + + Edit value @@ -5145,12 +5366,12 @@ find next SqlTableModel - + Error while commiting new row: %1 - + Error while deleting row from table %1: %2 @@ -5342,19 +5563,58 @@ but it's okay to use them anyway. TableStructureModel - + Name table structure columns - + Data type table structure columns + + + Primary +Key + table structure columns + + + + + Foreign +Key + table structure columns + + + + + Unique + table structure columns + + + + + Check + table structure columns + + + + + Not +NULL + table structure columns + + + Collate + table structure columns + + + + Default value table structure columns @@ -5374,6 +5634,7 @@ but it's okay to use them anyway. + Data @@ -5398,396 +5659,406 @@ but it's okay to use them anyway. - + Export table table window - + Import data to table table window - + Populate table table window - + Refresh structure table window - + Commit structure changes table window - + Rollback structure changes table window - + Add column table window - + Edit column table window - - + + Delete column table window - + Move column up table window - + Move column down table window - + Create similar table table window - + Reset autoincrement value table window - + Add table constraint table window - + Edit table constraint table window - + Delete table constraint table window - + Move table constraint up table window - + Move table constraint down table window - + Add table primary key table window - + Add table foreign key table window - + Add table unique constraint table window - + Add table check constraint table window - + Refresh index list table window - + Create index table window - + Edit index table window - + Delete index table window - + Refresh trigger list table window - + Create trigger table window - + Edit trigger table window - + Delete trigger table window - + Are you sure you want to delete column '%1'? table window - + Following problems will take place while modifying the table. Would you like to proceed? table window - + Table modification table window - + Could not load data for table %1. Error details: %2 - + Could not process the %1 table correctly. Unable to open a table window. - + Could not restore window %1, because no database or table was stored in session for this window. - + Could not restore window '%1', because no database or table was stored in session for this window. - + Could not restore window '%1', because database %2 could not be resolved. - + Could not restore window '%1'', because the table %2 doesn't exist in the database %3. - - + + New table %1 - + + Commited changes for table '%1' successfly. + + + + + Commited changes for table '%1' (named before '%2') successfly. + + + + Could not commit table structure. Error message: %1 table window - + Reset autoincrement - + Are you sure you want to reset autoincrement value for table '%1'? - + An error occurred while trying to reset autoincrement value for table '%1': %2 - + Autoincrement value for table '%1' has been reset successfly. - + Empty name - + A blank name for the table is allowed in SQLite, but it is not recommended. Are you sure you want to create a table with blank name? - + Cannot create a table without at least one column. - + Cannot create table %1, if it has no primary key defined. Either uncheck the %2, or define a primary key. - + Cannot use autoincrement for primary key when %1 clause is used. Either uncheck the %2, or the autoincrement in a primary key. - + Are you sure you want to delete table constraint '%1'? table window - + Delete constraint table window - + Cannot export, because no export plugin is loaded. - + Cannot import, because no import plugin is loaded. - + Uncommited changes - + There are uncommited structure modifications. You cannot browse or edit data until you have table structure settled. Do you want to commit the structure, or do you want to go back to the structure tab? - + Go back to structure tab - + Commit modifications and browse data. - + Name table window indexes - + Unique table window indexes - + Columns table window indexes - + Partial index condition table window indexes - + Name table window triggers - + Event table window triggers - + Condition table window triggers - + Details table window triggers - + Table window "%1" has uncommited structure modifications and data. - + Table window "%1" has uncommited data. - + Table window "%1" has uncommited structure modifications. @@ -5943,201 +6214,272 @@ Do you want to commit the structure, or do you want to go back to the structure - + + Output column names + + + + + Data - + Triggers - + DDL - - + + Could not restore window '%1', because no database or view was stored in session for this window. - + Could not restore window '%1', because database %2 could not be resolved. - + Could not restore window '%1', because database %2 could not be open. - + Could not restore window '%1', because the view %2 doesn't exist in the database %3. - - + + New view %1 - + Refresh the view view window - + Commit the view changes view window - + Rollback the view changes view window - + + Explicit column names + + + + + Generate output column names automatically basing on result columns of the view. + + + + + Add column + view window + + + + + Edit column + view window + + + + + Delete column + view window + + + + + Move column up + view window + + + + + Move column down + view window + + + + Refresh trigger list view window - + Create new trigger view window - + Edit selected trigger view window - + Delete selected trigger view window - + View window "%1" has uncommited structure modifications and data. - + View window "%1" has uncommited data. - + View window "%1" has uncommited structure modifications. - + Could not load data for view %1. Error details: %2 - + Uncommited changes - + There are uncommited structure modifications. You cannot browse or edit data until you have the view structure settled. Do you want to commit the structure, or do you want to go back to the structure tab? - + Go back to structure tab - + Commit modifications and browse data. - + + Commited changes for view '%1' successfly. + + + + + Commited changes for view '%1' (named before '%2') successfly. + + + + Could not commit view changes. Error message: %1 view window - + + Override columns + + + + + Currently defined columns will be overriden. Do you want to continue? + + + + + Could not determinate columns returned from the view. The query is problably incomplete or contains errors. + + + + Name view window triggers - + Instead of view window triggers - + Condition view window triggers - + Details table window triggers - + Could not process the %1 view correctly. Unable to open a view window. - + Empty name - + A blank name for the view is allowed in SQLite, but it is not recommended. Are you sure you want to create a view with blank name? - + The SELECT statement could not be parsed. Please correct the query and retry. Details: %1 - + The view could not be modified due to internal SQLiteStudio error. Please report this! - + The view code could not be parsed properly for execution. This is a SQLiteStudio's bug. Please report it. - + Following problems will take place while modifying the view. Would you like to proceed? view window - + View modification view window diff --git a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_pl.ts b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_pl.ts index 8671753..50dd7ce 100644 --- a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_pl.ts +++ b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_pl.ts @@ -1,6 +1,6 @@ - + AboutDialog @@ -588,96 +588,111 @@ Tryb zaawansowany - + Add constraint column dialog Dodaj ograniczenie - + Edit constraint column dialog Edytuj ograniczenie - - + + Delete constraint column dialog Usuń ograniczenie - + Move constraint up column dialog Przenieś ograniczenie w górę - + Move constraint down column dialog Przenieś ograniczenie w dół - + Add a primary key column dialog Dodaj klucz główny - + Add a foreign key column dialog Dodaj klucz obcy - + Add an unique constraint column dialog Dodaj ograniczenie wartości unikalnych - + Add a check constraint column dialog Dodaj ograniczenie sprawdzania wartości - + Add a not null constraint column dialog Dodaj ograniczenie niepustych wartości - + Add a collate constraint column dialog Dodaj ograniczenie zestawienia - + Add a default constraint column dialog Dodaj ograniczenie wartości domyślnej - + Are you sure you want to delete constraint '%1'? column dialog Czy na pewno chcesz usunąć ograniczenie '%1'? - + Correct the constraint's configuration. Popraw konfigurację ograniczenia. - + This constraint is not officially supported by SQLite 2, but it's okay to use it. To ograniczenie nie jest oficjalnie wspireane przez SQLite 2, ale można go używać. + + + Scale is not allowed for INTEGER PRIMARY KEY columns. + Skala nie jest dozwolona dla kolumn INTEGER PRIMARY KEY. + + + + Precision cannot be defined without the scale. + Precyzja nie może być zdefiniowana bez skali. + + + + Precision is not allowed for INTEGER PRIMARY KEY columns. + Precyzja nie jest dozwolona dla kolumn INTEGER PRIMARY KEY. + ColumnDialogConstraintsModel @@ -891,366 +906,353 @@ ale można go używać. ConfigDialog - + Configuration Konfiguracja - + Search Szukaj - + General Ogólne - + Keyboard shortcuts Skróty klawiszowe - + Look & feel Wygląd i zachowanie - + Style Style - + Fonts Czcionki - + Colors Kolory - + Plugins Wtyczki - + Code formatters Formatery kodu - + Data browsing Przeglądanie danych - + Data editors Edytory danych - + Data browsing and editing Przeglądanie i edycja danych - + Number of data rows per page: Liczba wierszy danych na stronie: - - + + <p>When the data is read into grid view columns width is automatically adjusted. This value limits the initial width for the adjustment, but user can still resize the column manually over this limit.</p> <p>Kiedy dane są wczytane do widoku siatki, szerokość kolumn jest automatycznie dostosowywana. Ta wartość ogranicza początkową szerokość tego dostosowywania, ale użytkownik nadal może rozszerzać kolumnę ręcznie poza ten limit.</p> - + Limit initial data column width to (in pixels): Ogranicz początkową szerokość kolumn danych (w pikselach): - + Inserting new row in data grid - + Wstawianie nowego wiersza w widoku siatki danych. - + Before currently selected row - - - - - - - General.InsertRowPlacement - + Przed aktualnie wybranym wierszem - + After currently selected row - + Po aktualnie wybranym wierszu. - + At the end of data view - + Na końcu widoku siatki danych - + Data types Type danych - + Available editors: Dostępne edytory: - + Editors selected for this data type: Edytory wybrane dla tego typu danych: - + Schema editing Edycja schematu - + Number of DDL changes kept in history. Liczba zmian DDL trzymanych w historii. - + DDL history size: Rozmiar historii DDL: - + Don't show DDL preview dialog when commiting schema changes Nie pokazuj okna podglądu DDL podczas zatwierdzania zmian schematu - + SQL queries Zapytania SQL - - + + Number of queries kept in the history. Liczba zapytań trzymana w historii. - + History size: Rozmiar historii: - + <p>If there is more than one query in the SQL editor window, then (if this option is enabled) only a single query will be executed - the one under the keyboard insertion cursor. Otherwise all queries will be executed. You can always limit queries to be executed by selecting those queries before calling to execute.</p> <p>Jeśli w oknie edytora SQL jest więcej niż jedno zapytanie, to (jeśli ta opcja jest włączona) tylko jedno zapytanie będzie wykonana - to, które znajduje się pod kursorem pisania. W przeciwnym wypadku wszystkie zapytania będą wykonywane. Zawsze możesz ograniczyć zapytania do wywołania przez zaznaczenie tych zapytań, które chcesz wywołać.</p> - + Execute only the query under the cursor Wykonuj tylko zapytania będące pod kursorem - + Updates Aktualizacje - + Automatically check for updates at startup Sprawdzaj aktualizacje automatycznie przy starcie - + Session Sesje - + Restore last session (active MDI windows) after startup Przywróć ostatnią sesję (aktywne okna MDI) po starcie - + Filter shortcuts by name or key combination Filtruj skróty po nazwie, lub kombinacji klawiszy - + Action Akcja - + Key combination Kombinacja klawiszy - + Changing language requires application restart to take effect. Zmiana języka wymaga restartu aplikacji, aby zadziałać. - + Compact layout - + Układ kompaktowy - + <p>Compact layout reduces all margins and spacing on the UI to minimum, making space for displaying more data. It makes the interface a little bit less aesthetic, but allows to display more data at once.</p> - + <p>Układ kompaktowy zmniejsza wszystkie marginesy i odstępy na interfejsie do minimum, robiąc więcej miejsca na wyświetlanie danych. Powoduje to, że interfejs jest nieco mniej estetyczny, ale pozwala to na prezentację większej ilości danych naraz.</p> - + Use compact layout - - - - - General.CompactLayout - + Użyj układu kompaktowego - + + Database list Lista baz - + If switched off, then columns will be sorted in the order they are typed in CREATE TABLE statement. Gdy wyłączone, to kolumny będą ułożone w takiej kolejności, w jakiej wystąpiły w zapytaniu CREATE TABLE. - + Sort table columns alphabetically Sortuj kolumny tabel alfabetycznie. - + Expand tables node when connected to a database Rozwiń listę tabel po połączeniu z bazą danych - + <p>Additional labels are those displayed next to the names on the databases list (they are blue, unless configured otherwise). Enabling this option will result in labels for databases, invalid databases and aggregated nodes (column group, index group, trigger group). For more labels see options below.<p> <p>Dodatkowe etykiety, to te wyświetlane obok nazw na liście baz danych (są niebieskie, chyba że skonfigurowano je inaczej). Włączenie tej opcji spowoduje wyświetlenie etykiet dla baz danych, niepoprawnych baz danych, oraz dla węzłów agregujących (grupa kolumn, grupa indeksów, grupa wyzwalaczy). Więcej etykiet jest dostępne niżej.</p> - + Display additional labels on the list Wyświetlaj dodatkowe etykiety na liście - + For regular tables labels will show number of columns, indexes and triggers for each of tables. Dla zwykłych tabel etykiety będą pokazywać liczbę kolumn, inseksów, oraz wyzwalaczy dla tych tabel. - + Display labels for regular tables Wyświetlaj etykiety dla zwykłych tabel - + Virtual tables will be marked with a 'virtual' label. Tabele wirtualne będą oznaczone etykietą 'wirtualna'. - + Display labels for virtual tables Wyświetlaj etykiety dla tabel wirtualnych - + Expand views node when connected to a database Rozwiń listę widoków po połączeniu z bazą. - + If this option is switched off, then objects will be sorted in order they appear in sqlite_master table (which is in order they were created) Gdy ta opcja jest wyłączona, to wszystkie obiekty będą ułożone w takiej kolejności, w jakiej występują w tabeli sqlite_master (czyli w takiej, w jakiej zostały stworzone) - + Sort objects (tables, indexes, triggers and views) alphabetically Sortuj obiekty (tabele, indeksy, wyzwalacze i widoki) alfabetycznie - + Display system tables and indexes on the list Wyświetlaj tabele i indeksy systemowe na liście - + Table windows Okna tabel - When enabled, Table Windows will show up with the data tab, instead of the structure tab. - Gdy włączone, Okna Tabel będą się pokazywać z zakładką danych, zamiast z zakładką struktury. + Gdy włączone, Okna Tabel będą się pokazywać z zakładką danych, zamiast z zakładką struktury. - + Open Table Windows with the data tab for start Otwieraj Okna Tabeli z zakładką danych na początek - + View windows Okna Widoków - When enabled, View Windows will show up with the data tab, instead of the structure tab. - Gdy włączone, Okna Widoków będą się pokazywać z zakładką danych, zamiast z zakładką struktury. + Gdy włączone, Okna Widoków będą się pokazywać z zakładką danych, zamiast z zakładką struktury. - + Open View Windows with the data tab for start Otwieraj Okna Widoku z zakładką danych na początek - + Main window dock areas - + Strefy dokowania głównego okna - + Left and right areas occupy corners - + Lewa i prawa strefa zajmują rogi - + Top and bottom areas occupy corners - + Górna i dolna strefa zajmują rogi - + Hide built-in plugins Ukryj wtyczki wbudowane - + Current style: Aktualny styl: - + Preview Podgląd - + Enabled Włączone @@ -1259,193 +1261,273 @@ ale można go używać. Kolumna - + Disabled Wyłączone - - + + Language Język - + + Database dialog window + Okno dialogowe bazy danych + + + + <p>When adding new database it is marked to be "permanent" (stored in configuration) by default. Checking this option makes every new database to NOT be "permanent" by default.</p> + <p>Podczas dodawania nowej bazy danych jest ona domyślnie zaznaczana jako "trwała" (zapisywana w konfiguracji). Włączenie tej opcji powoduje, że każda nowa baza danych NIE będzie zaznaczana domyślnie jako "trwała".</p> + + + + Do not mark database to be "permanent" by default + Nie zaznaczaj bazy danych domyślnie jako "trwała" + + + + <p>When this option is enabled, then files dropped from file manager onto database list will be automatically added to the list, bypassing standard database dialog. If for various reasons automatic process fails, then standard dialog will be presented to the user.</p> + <p>Gdy ta opcja jest włączona, to pliki upuszczone z menadżera plików na listę baz danych będą automatycznie dodawane do list, pomijając standardowe okno bazy danych. Jeśli z różnych powodów automatyczny proces się nie powiedzie, to użytkownikowi ukaże się standardowe okno.</p> + + + + Try to bypass dialog completly when dropping database file onto the list + Próbuj całkowicie pomijać dialog podczas upuszczania pliku bazy na listę + + + + <p>When this is enabled and user holds mouse pointer over a cell in any data view (query results, a table data, a view data) a tooltip will appear with details about the cell - it includes details like column data type, constraints, ROWID and others.</p> + <p>Gdy to jest włączone i użytkownik zatrzyma kursor myszy nad komórką w widoku siatki danych (wyniki zapytania, dane tabeli, dane widoku), to pojawi się podpowiedź ze szczegółami odnośnie komórki - zawiera ona szczegóły , jak typ danych kolumny, ograniczenia, ROWID i inne.</p> + + + + Show column and row details tooltip in data view + Pokazuj podpowiedź ze szczegółami o kolumnie i wierszu w widoku siatki danych + + + + <p>When enabled, Table Windows will show up with the data tab, instead of the structure tab.</p> + <p>Gdy włączone, Okna Tabeli będą się otwierać na zakładce danych, zamiast na zakładce struktury.</p> + + + + <p>When enabled the "Data" tab will be placed as first tab in every Table Window, instead of being at second place.</p> + <p>Gdy włączone, to zakładka "Dane" będzie umieszczona jako pierwsza w każdym Oknie Tabeli, zamiast jako druga.</p> + + + + Place data tab as first tab in a Table Window + Ustaw zakładkę danych jako pierwszą w Oknie Tabeli + + + + <p>When enabled, View Windows will show up with the data tab, instead of the structure tab.</p> + <p>Gdy włączone, Okna Widoku będą się otwierać na zakładce danych, zamiast na zakładce struktury.</p> + + + + <p>When enabled the "Data" tab will be placed as first tab in every View Window, instead of being at second place.</p> + <p>Gdy włączone, to zakładka "Dane" będzie umieszczona jako pierwsza w każdym Oknie Widoku, zamiast jako druga.</p> + + + + Place data tab as first tab in a View Window + Ustaw zakładkę danych jako pierwszą w Oknie Widoku + + + + Status Field + Pole Statusu + + + + <p>When user manually closes the Status panel, this option makes sure that if any new message is printed in the Status panel it will be reopened. If it's disabled, then Status panel can only be open manually by the user from the "View" menu.</p> + <p>Kiedy użytkownik ręcznie zamyka panel Statusu, ta opcja zapewnia, że zostanie ono otwarte ponownie, gdy jest wyświetlona nowa wiadomość. Jeśli jest ona wyłączona, to panel Statusu może być otwarte tylko ręcznie z menu "Widok".</p> + + + + Always open Status panel when new message is printed + Zawsze otwieraj panel Statusu, gdy wyświetlona jest nowa wiadomość + + + Active formatter plugin Aktywna wtyczka formatera - + SQL editor font Czcionka edytora SQL - + Database list font Czcionka listy baz danych - + Database list additional label font Czcionka dodatkowych etykiety listy baz danych - + Data view font Czcionka widoku danych - + Status field font Czcionka pola statusu - + SQL editor colors Kolory edytora SQL - + Current line background Tło bieżącej linii - + <p>SQL strings are enclosed with single quote characters.</p> <p>Łańcuchy znaków SQL są zamknięte pomiędzy znakami apostrofu.</p> - + String foreground Czcionka łańcucha znaków - + <p>Bind parameters are placeholders for values yet to be provided by the user. They have one of the forms:</p><ul><li>:param_name</li><li>$param_name</li><li>@param_name</li><li>?</li></ul> <b>Parametry wiążące to wyrażenia zastępcze dla wartości, które mają być dopiero dostarczone przez użytkownika. Mają one jedną z form: </p><ul><li>:nazwa_parametru</li><li>$nazwa_parametru</li><li>@nazwa_parametru</li><li>?</li></ul> - + Bind parameter foreground Czcionka parametru wiążącego - + Highlighted parenthesis background Tło podświetlonych nawiasów - + <p>BLOB values are binary values represented as hexadecimal numbers, like:</p><ul><li>X'12B4'</li><li>x'46A2F4'</li></ul> <p>Wartości BLOB są wartościami binarnymi, reprezentowanymi jako liczby heksadecymalne, jak np:</p><ul><li>X'12B4'</li><li>x'46A2F4'</li></ul> - + BLOB value foreground - + Regular foreground Standardowa czcionka - + Line numbers area background Tło obszaru numerów linii - + Keyword foreground Czcionka słowa kluczowego - + Number foreground Czcionka liczby - + Comment foreground Czcionka komentarza - + <p>Valid objects are name of tables, indexes, triggers, or views that exist in the SQLite database.</p> <p>Poprawne obiekty to nazwy tabel, indekstów, wyzwalaczy i widoków, które istnieją w basie SQLite.</p> - + Valid objects foreground Czcionka poprawnych obiektów - + Data view colors Kolory widoku danych - + <p>Any data changes will be outlined with this color, until they're commited to the database.</p> <p>Jakakolwiek zmiana danych będzie obrysowana tym kolorem, dopóki nie zostanie zatwierdzona do bazy danych.</p> - + Uncommited data outline color Kolor obrysu niezatwierdzonych danych - + <p>In case of error while commiting data changes, the problematic cell will be outlined with this color.</p> <p>W przypadku błędu podczas zatwierdzania zmian danych, komórka będąca przyczyną problemu zostanie obrysowana tym kolorem.</p> - + Commit error outline color Kolor obrysu błędu zatwierdzania - + NULL value foreground Kolor czcionki wartości NULL - + Deleted row background Tło wiersza usuniętego - + Database list colors Kolory listy baz danych - + <p>Additional labels are those which tell you SQLite version, number of objects deeper in the tree, etc.</p> <p>Dodatkowe etykiety to te, które mówią o wersji SQLite, liczbie obiektów w głębszych częściach drzewa, itp.</p> - + Additional labels foreground Czcionka dodatkowych etykiet - + Status field colors Kolory pola statusu - + Information message foreground Czcionka wiadomości informującej - + Warning message foreground Czcionka wiadomości ostrzegającej - + Error message foreground Czcionka wiadomości błędu @@ -1497,43 +1579,43 @@ ale można go używać. Szczegóły wtyczki - + Plugins are loaded/unloaded immediately when checked/unchecked, but modified list of plugins to load at startup is not saved until you commit the whole configuration dialog. Wtyczki są ładowane/wyładowywane natychmiast po zaznaczeniu/odznaczeniu, ale zmodyfikowana lista wtyczek, które należy załadować przy starcie nie jest zapisana, dopóki nie zatwierdzisz całego okna configuracji. - + %1 (built-in) plugins manager in configuration dialog %1 (wbudowany) - + Details Szczegóły - + No plugins in this category. Brak wtyczek w tej kategorii. - + Add new data type Dodaj nowy typ danych - + Rename selected data type Zmień nazwę wybranego typu danych - + Delete selected data type Usuń wybrany typ danych - + Help for configuring data type editors Pomoc w konfiguracji edytorów typów danych @@ -1679,144 +1761,144 @@ ale można go używać. SQLiteStudio CSS console - + Konsola CSS SQLiteStudio DataView - + Filter data data view Filtruj dane - + Grid view Widok siatki - + Form view Widok formularza - + Refresh table data data view Odśwież dane tabeli - + First page data view Pierwsza strona - + Previous page data view Poprzednia strona - + Next page data view Następna strona - + Last page data view Ostatnia strona - + Apply filter data view Zastosuj filtr - + Commit changes for selected cells data view Zatwierdź zmiany dla wybranych komórek - + Rollback changes for selected cells data view Wycofaj zmiany dla wybranych komórek - + Show grid view of results sql editor Pokaż widok siatki dla wyników - + Show form view of results sql editor Pokaż widok formularza dla wyników - + Filter by text data view Filtruj po tekście - + Filter by the Regular Expression data view Filtruj używając Wyrażeń Regularnych - + Filter by SQL expression data view Filtruj używając wyrażenia SQL - + Tabs on top data view Karty na górze - + Tabs at bottom data view Karty na dole - + Place new rows above selected row data view - + Wstawiaj nowe wiersze nad aktualnie wybranym wierszem - + Place new rows below selected row data view - + Wstawiaj nowe wiersze pod aktualnie wybranym wierszem - + Place new rows at the end of the data view data view - + Wstawiaj nowe wiersze na końcu widoku siatki danych - + Total number of rows is being counted. Browsing other pages will be possible after the row counting is done. Całkowita liczba wierszy jest liczona. Przeglądanie pozostałych stron będzie możliwe kiedy liczenie wierszy zostanie zakończone. - + Row: %1 Wiersz: %1 @@ -1958,11 +2040,11 @@ Przeglądanie pozostałych stron będzie możliwe kiedy liczenie wierszy zostani Name - Nazwa + Nazwa Type - Typ + Typ Browse for database file on local computer @@ -1975,7 +2057,7 @@ Przeglądanie pozostałych stron będzie możliwe kiedy liczenie wierszy zostani - + File Plik @@ -1991,7 +2073,7 @@ Przeglądanie pozostałych stron będzie możliwe kiedy liczenie wierszy zostani Permanent - Trwała + Trwała @@ -2001,54 +2083,54 @@ Przeglądanie pozostałych stron będzie możliwe kiedy liczenie wierszy zostani Test database connection - Testuj połączenie z bazą + Testuj połączenie z bazą - + Browse for existing database file on local computer Przeglądaj lokalny komputer w poszukiwaniu istniejącej bazy - + Browse Przeglądaj - + Enter an unique database name. Wprowadź unikalną nazwę bazy danych. - + This name is already in use. Please enter unique name. Ta nazwa jest już w użyciu. Proszę wprowadzić unikalną nazwę. - + Enter a database file path. Wprowadź ścieżkę do pliku bazy danych. - + This database is already on the list under name: %1 Ta baza jest już na liście pod nazwą: %1 - + Select a database type. Wybierz typ bazy danych. - + Auto-generated Auto-generowana The name will be auto-generated - Nazwa będzie generowana automatycznie + Nazwa będzie generowana automatycznie - + Type the name Wprowadź nazwę @@ -2097,9 +2179,32 @@ Przeglądanie pozostałych stron będzie możliwe kiedy liczenie wierszy zostani + Error while dropping %1: %2 Błąd podczas porzucania %1: %2 + + + Delete objects + Usuń obiekty + + + + Are you sure you want to delete following objects: +%1 + Czy na pewno chcesz usunąć następujące obiekty: +%1 + + + + Cannot start transaction. Details: %1 + Nie można wystartować transakcji. Szczegóły: %1 + + + + Cannot commit transaction. Details: %1 + Nie można zatwierdzić transakcji. Szczegóły: %1 + DbTree @@ -2114,131 +2219,158 @@ Przeglądanie pozostałych stron będzie możliwe kiedy liczenie wierszy zostani Filtruj po nazwie - + Copy Kopiuj - + Paste Wklej - + Select all Zaznacz wszystko - + Create a group Utwórz grupę - + Delete the group Usuń grupę - + Rename the group Zmień nazwę grupy - + Add a database Dodaj bazę danych - + Edit the database Edytuj bazę danych - + Remove the database Usuń bazę danych - + Connect to the database Połącz z bazą danych - + Disconnect from the database Rozłącz się z bazą danych - + Import Importuj - + Export the database Eksportuj bazę danych - + Convert database type Konwertuj typ bazy danych - + Vacuum Odkurz - + Integrity check Sprawdź spójność - + Create a table Utwórz tabelę - + Edit the table Edytuj tabelę - + + Generate query for table + Generuj zapytanie dla tabeli + + + Entry with name %1 already exists in group %2. Pozycja o nazwie %1 istnieje już w grupie %2. + + + Are you sure you want to remove database '%1' from the list? + Czy napewno chcesz wycofać bazę '%1' z listy? + + + + Are you sure you want to remove following databases from the list: +%1 + Czy na pewno chcesz wycofać następujące bazy z listy: +%1 + + + + Remove database + Wycofaj bazę + + + + Vacuum (%1) + Odkurz (%1) + Drop the table Porzuć tabelę - + Export the table Eksportuj tabelę - + Import into the table Importuj do tabeli - + Populate table Zaludnij tabelę - + Create similar table Utwórz podobną tabelę - + Create an index Utwórz indeks - + Edit the index Edytuj indeks @@ -2247,12 +2379,12 @@ Przeglądanie pozostałych stron będzie możliwe kiedy liczenie wierszy zostani Porzuć indeks - + Create a trigger Utwórz wyzwalacz - + Edit the trigger Edytuj wyzwalacz @@ -2261,12 +2393,12 @@ Przeglądanie pozostałych stron będzie możliwe kiedy liczenie wierszy zostani Porzuć wyzwalacz - + Create a view Utwórz widok - + Edit the view Edytuj widok @@ -2275,199 +2407,195 @@ Przeglądanie pozostałych stron będzie możliwe kiedy liczenie wierszy zostani Porzuć widok - + Add a column Dodaj kolumnę - + Edit the column Edytuj kolumnę - + Delete the column Usuń kolumnę - + Delete selected items Usuń wybrane elementy - + Clear filter Wyczyść filtr - + Refresh all database schemas Odśwież schematy wszystkich baz danych - + Refresh selected database schema Odśwież schemat wybranej bazy danych - + Delete the table Usuń tabelę - + Reset autoincrement sequence Wyzeruj sekwencję autoinkrementacji - + Delete the index Usuń indeks - + Delete the trigger Usuń wyzwalacz - + Delete the view Usuń widok - - + + Erase table data - + Wymaż dane tabeli - - + + Database Baza danych - + Grouping Grupowanie - - + + Create group Utwórz grupę - + Group name Nazwa grupy - + Delete group Usuń grupę - + Are you sure you want to delete group %1? All objects from this group will be moved to parent group. Czy na pewno chcesz usunąć grupę %1? Wszystkie obiekty z tej grupy zostaną przeniesione do nadrzędnej grupy. - Delete database - Usuń bazę danych + Usuń bazę danych - Are you sure you want to delete database '%1'? - Czy na pewno chcesz usunąć bazę danych '%1'? + Czy na pewno chcesz usunąć bazę danych '%1'? - - + + Cannot import, because no import plugin is loaded. Nie można zaimportować, ponieważ żadna wtyczka importu nie została załadowana. - - + + Cannot export, because no export plugin is loaded. Nie można wyeksportować, ponieważ żadna wtyczka eksportu nie została załadowana. - Error while executing VACUUM on the database %1: %2 - Błąd podczas wykonywania VACUUM na bazie danych %1: %2 + Błąd podczas wykonywania VACUUM na bazie danych %1: %2 - VACUUM execution finished successfully. - Wykonanie VACUUM przebiegło pomyślnie. + Wykonanie VACUUM przebiegło pomyślnie. - + Integrity check (%1) Sprawdzanie spójności (%1) - + Reset autoincrement Wyzeruj autoinkrementację - + Are you sure you want to reset autoincrement value for table '%1'? Czy na pewno chcesz wyzerować wartość autoinkrementacji dla tabeli '%1'? - + An error occurred while trying to reset autoincrement value for table '%1': %2 Wystąpił błąd podczas próby wyzerowania wartości autoinkrementacji dla tabeli '%1': %2 - + Autoincrement value for table '%1' has been reset successfly. Wartość autoinkrementacji dla tabeli '%1' została pomyślnie wyzerowana. - + Are you sure you want to delete all data from table '%1'? - + Czy na pewno chcesz usunąć wszystkie dane z tabeli '%1'? - + An error occurred while trying to delete data from table '%1': %2 - + Wystąpił błąd podczas próby usunięcia danych z tabeli '%1': %2 - + All data has been deleted for table '%1'. - + Wszystkie dane z tabeli '%1' zostały usunięte. - + Following objects will be deleted: %1. Następujące obiekty zostaną usunięte: %1 - + Following databases will be removed from list: %1. Następujące bazy danych zostaną usunięte z listy: %1 - + Remainig objects from deleted group will be moved in place where the group used to be. Pozostałe obiekty z usuniętej grupy będą przeniesione w miejsce, gdzie dotychczas była ta grupa. - + %1<br><br>Are you sure you want to continue? %1<br><br>Czy na pewno chcesz kontynuować? - + Delete objects Usuń obiekty @@ -2502,25 +2630,25 @@ Wszystkie obiekty z tej grupy zostaną przeniesione do nadrzędnej grupy. DbTreeModel - + Database: %1 dbtree tooltip Baza danych: %1 - + Version: dbtree tooltip Wersja: - + File size: dbtree tooltip Rozmiar pliku: - + Encoding: dbtree tooltip Kodowanie: @@ -2528,104 +2656,109 @@ Wszystkie obiekty z tej grupy zostaną przeniesione do nadrzędnej grupy. Error details: dbtree tooltip - Szczegóły błędu: + Szczegóły błędu: - + Error: dbtree tooltip - + Błąd: - + Table : %1 dbtree tooltip Tablela: : %1 - + Columns (%1): dbtree tooltip Kolumny (%1): - + Indexes (%1): dbtree tooltip Indeksy (%1): - + Triggers (%1): dbtree tooltip Wyzwalacze (%1): - + Copy Kopiuj - + Move Przenieś - + Include data Również dane - + Include indexes Również indeksy - + Include triggers Również wyzwalacze - + Abort Przerwij - + + Could not add dropped database file '%1' automatically. Manual setup is necessary. + Nie udało się automatycznie dodać upuszczonego pliku bazy '%1'. Niezbędna ręczna ingerencja. + + + Referenced tables Tabele powiązane - + Do you want to include following referenced tables as well: %1 Czy chcesz zawrzeć również powiązane tabele: %1 - + Name conflict Konflikt nazwy - + Following object already exists in the target database. Please enter new, unique name, or press '%1' to abort the operation: Następująy obiekt istnieje już w docelowej bazie danych. Proszę podać nową, unikalną nazwę, lub nacisnąć '%1', aby przerwać operację. - + SQL statements conversion Konwersja zapytań SQL - + Following error occurred while converting SQL statements to the target SQLite version: Następujące błędy wystąpiły podczas konwersji zapytań SQL do docelowej wersji SQLite: - + Would you like to ignore those errors and proceed? Czy chcesz zignorować te błędy i kontynuować? @@ -3382,102 +3515,175 @@ Proszę podać nową, unikalną nazwę, lub nacisnąć '%1', aby przer Indeks - + On table: Na tabeli: - + Index name: Nazwa indeksu: - + Partial index condition Warunek indeksu częściowego: - + Unique index Indeks unikalny - + Column Kolumna - + Collation Zestawienie - + Sort Sortowanie - + + Delete selected indexed expression + Usuń wybrane wyrażenie indeksowane. + + + + Moves selected index column up in the order, making it more significant in the index. + Przenosi wybraną indeksowaną kolumnę wyżej w kolejności, czyniąc ją ważniejszą w indeksie. + + + + Moves selected index column down in the order, making it less significant in the index. + Przenosi wybraną indeksowaną kolumnę niżej w kolejności, czyniąc ją mniej ważną w indeksie. + + + + Edit selected indexed expression + Edytuj wybrane wyrażenie indeksowane + + + + Add indexed expression + Dodaj wyrażenie indeksowane + + + DDL DDL - + Tried to open index dialog for closed or inexisting database. Próbowano otworzyć okno indeksu dla zamkniętej lub nieistniejącej bazy. - + Could not process index %1 correctly. Unable to open an index dialog. Nie udało się przetworzyć poprawnie indeksu %1. Nie można otworzyć okna indeksu. - + + Unique index cannot have indexed expressions. Either remove expressions from list below, or uncheck this option. + Unikalny indeks nie może zawierać wyrażeń indeksowanych. Albo usuń wyrażenia z poniższej listy, albo odznacz tę opcję. + + + Pick the table for the index. Wybierz tabelę dla indeksu. - + Select at least one column. Zaznacz przynajmniej jedną kolumnę. - + Enter a valid condition. Wprowadź poprawny warunek. - + default index dialog domyślne - + Sort order table constraints Kierunek sortowania - - + + Error index dialog Błąd - + Cannot create unique index, because values in selected columns are not unique. Would you like to execute SELECT query to see problematic values? Nie można utworzyć indeksu, ponieważ wartości w wybranych kolumnach nie są unikalne. Czy chcesz wykonać zapytanie SELECT, aby zobaczyć wartości stwarzające problem? - + An error occurred while executing SQL statements: %1 Wystąpił błąd podczas wykonywania zapytań SQL: %1 + + IndexExprColumnDialog + + + Indexed expression + Wyrażenie indeksowane + + + + Expression to index + Wyrażenie do indeksowania + + + + This expression is already indexed by the index. + To wyrażenie jest już indeksowane przez indeks. + + + + Column should be indexed directly, not by expression. Either extend this expression to contain something more than just column name, or abort and select this column in index dialog directly. + Kolumna powinna być indeksowana bezpośrednio, nie przez wyrażenie. Albo rozszerz to wyrażenie, aby zwierało coś więcej niż tylko nazwę kolumny, albo przerwij i wybierz tą kolumnę bezpośrednio w oknie dialogowym indeksu. + + + + Column '%1' does not belong to the table covered by this index. Indexed expressions can refer only to columns from the indexed table. + Kolumna '%1' nie należy do tabeli objętej tym indeksem. Wyrażenia indeksowane mogą odnosić się jedynie do kolumn z indeksowanej tabeli. + + + + It's forbidden to use 'SELECT' statements in indexed expressions. + Nie można używać zapytań 'SELECT' w wyrażeniach indeksowanych. + + + + Enter an indexed expression. + Wprowadź wyrażenie indeksowane. + + + + Invalid expression. + Niepoprawne wyrażenie. + + LanguageDialog @@ -3519,273 +3725,273 @@ Proszę podać nową, unikalną nazwę, lub nacisnąć '%1', aby przer Pasek narzędzi widoku - + Configuration widgets Kontrolki konfiguracji - + Syntax highlighting engines Silniki podświetlania składni - + Data editors Edytory danych - + Running in debug mode. Press %1 or use 'Help / Open debug console' menu entry to open the debug console. Uruchomiono tryb debugowania. Wciśnij %1 lub wybierz menu 'Pomoc / Otwórz konsolę debugowania' aby otworzyć konsolę debugowania. - + Running in debug mode. Debug messages are printed to the standard output. Uruchomiono tryb debugowania. Wiadomości debugujące są wyświetlane na standardowym wyjściu. - + You need to restart application to make the language change take effect. Należy zrestartować aplikację, aby nastąpiła zmiana języka. - + Open SQL editor Otwórz edytor SQL - + Open DDL history Otwórz historię DDL - + Open SQL functions editor Otwórz edytor funkcji SQL - + Open collations editor Otwórz edytor zestawień - + Import Importuj - + Export Eksportuj - + Open configuration dialog Otwórz okno konfiguracji - + Tile windows Ustaw okna w płytki - + Tile windows horizontally Ustaw okno poziomo - + Tile windows vertically Ustaw okna pionowo - + Cascade windows Ustaw okna caskadowo - + Next window Następne okno - + Previous window Poprzednie okno - + Hide status field Ukryj pole statusu - + Close selected window Zamknij wybrane okno - + Close all windows but selected Zamknij wszystkie okna, oprócz wybranego - + Close all windows Zamknij wszystkie okna - + Restore recently closed window Przywróć ostatnio zamknięte okno - + Rename selected window Zmień nazwę wybranego okna - + Open Debug Console Otwórz Konsolę Debugowania - + Open CSS Console - + Otwórz konsolę CSS - + Report a bug Zgłoś błąd - + Propose a new feature Zgłoś pomysł - + About O programie - + Licenses Licencje - + Open home page Otwórz stronę domową - + Open forum page Otwórz stronę forum - + User Manual Podręcznik Użytkownika - + SQLite documentation Dokumentacja SQLite - + Report history Historia zgłoszeń - + Check for updates Sprawdź aktualizacje - + Database menubar Baza danych - + Structure menubar Struktura - + View menubar Widok - + Window list menubar view menu Lista okien - + Tools menubar Narzędzia - + Help Pomoc - + Could not set style: %1 main window Nie udało się ustawić stylu: %1 - + Cannot export, because no export plugin is loaded. Nie można wyeksportować, ponieważ żadna wtyczka eksportu nie została załadowana. - + Cannot import, because no import plugin is loaded. Nie można zaimportować, ponieważ żadna wtyczka importu nie została załadowana. - + Rename window Zmień nazwę okna - + Enter new name for the window: Wprowadź nową nazwę dla okna: - + New updates are available. <a href="%1">Click here for details</a>. Nowe aktualizacje są dostępne: <a href="%1">Kliknij aby poznać szczegóły</a>. - + You're running the most recent version. No updates are available. Uruchomiona jest najnowsza wersja. Nie ma dostępnych aktualizacji. - + Database passed in command line parameters (%1) was already on the list under name: %2 Baza danych podana w parametrach linii poleceń (%1) była już na liście pod nazwą: %2 - + Database passed in command line parameters (%1) has been temporarily added to the list under name: %2 Baza danych podana w linii poleceń (%1) jest tymczasowo dodana do listy pod nazwą: %2 - + Could not add database %1 to list. Nie udało się dodać bazy danych %1 do listy. @@ -4091,7 +4297,7 @@ Proszę podać nową, unikalną nazwę, lub nacisnąć '%1', aby przer Abort - Przerwij + Przerwij @@ -4189,127 +4395,127 @@ Proszę podać nową, unikalną nazwę, lub nacisnąć '%1', aby przer nazwa zestawienia: %1 - + Data grid view Widok siatki danych - + Copy cell(s) contents to clipboard Skopiuj zawartość komórek do schowka. - + Paste cell(s) contents from clipboard Wklej zawartość komórkek ze schowka. - + Set empty value to selected cell(s) Ustaw pustą wartość dla wybranych komórek - + Set NULL value to selected cell(s) Ustaw wartość NULL dla wybranych komórek - + Commit changes to cell(s) contents Zatwierdź zmiany dla zawartości komórek - + Rollback changes to cell(s) contents Wycofaj zmiany dla zawartości komórek - + Delete selected data row Usuń wybrane wiersze danych - + Insert new data row Wstaw nowy wiersz danych - + Open contents of selected cell in a separate editor Otwórz zawartość wybranej komórki w osobnym edytorze - + Total pages available: %1 Liczba dostępnych stron: %1 - + Total rows loaded: %1 Liczba załadowanych wierszy: %1 - + Data view (both grid and form) Widok danych (zarówno siatki i formularza) - + Refresh data Odśwież dane - + Switch to grid view of the data Przełącz do widoku siatki danych - + Switch to form view of the data Przełącz do widoku formularza danych - + Database list Lista baz - + Delete selected item Usuń zaznaczony element - + Clear filter contents Wyczyść zawartość filtra - + Refresh schema Odśwież schemat - + Refresh all schemas Odśwież wszystkie schematy - + Add database Dodaj bazę danych - + Select all items Zaznacz wszystkie elementy - + Copy selected item(s) Kopiuj zaznaczone elementy - + Paste from clipboard @@ -4423,7 +4629,7 @@ Proszę podać nową, unikalną nazwę, lub nacisnąć '%1', aby przer Open CSS Console - + Otwórz konsolę CSS @@ -4535,6 +4741,11 @@ Proszę podać nową, unikalną nazwę, lub nacisnąć '%1', aby przer Copy selected block of text and paste it a line above Skopiuj wybrany blok tekstu i wklej go powyżej + + + Toggle comment + Przełącz komentarz + All SQLite databases @@ -4607,106 +4818,106 @@ Proszę podać nową, unikalną nazwę, lub nacisnąć '%1', aby przer Przenieś aktywność klawiatury do edytora SQL powyżej - + Table window Okno tabeli - + Refresh table structure Odśwież strukturę tabeli - + Add new column Dodaj nową kolumnę - + Edit selected column Edytuj wybraną kolumnę - + Delete selected column Usuń wybraną kolumnę - + Export table data Eksportuj dane tabeli - + Import data to the table Importuj dane do tabeli - + Add new table constraint Dodaj nowe ograniczenie tabeli - + Edit selected table constraint Edytuj wybrane ograniczenie tabeli - + Delete selected table constraint Usuń wybrane ograniczenie tabeli - + Refresh table index list Odśwież listę indeksów tabeli - + Add new index Dodaj nowy indeks - + Edit selected index Edytuj wybrany indeks - + Delete selected index Usuń wybrany indeks - + Refresh table trigger list Odśwież listę wyzwalaczy tabeli - + Add new trigger Dodaj nowy wyzwalacz - + Edit selected trigger Edytuj wybrany wyzwalacz - + Delete selected trigger Usuń wybrany wyzwalacz - + Go to next tab Przejdź do następnej karty - + Go to previous tab Przejdź do poprzedniej karty @@ -4890,7 +5101,7 @@ znajdź następny Select file to save SQL sql editor - + Wybierz plik do zapisu SQL @@ -4953,47 +5164,53 @@ znajdź następny Zastąp - + + Toggle comment + sql editor + Przełącz komentarz + + + Saved SQL contents to file: %1 - + Zapisano zawartość SQL do pliku: %1 - + Syntax completion can be used only when a valid database is set for the SQL editor. Dopełnianie składni może być użyte tylko wtedy, gdy poprawna baza danych jest ustawiona w edytorze SQL. - + Contents of the SQL editor are huge, so errors detecting and existing objects highlighting are temporarily disabled. Zawartość edytora SQL jest ogromna, więc sprawdzanie błędów i podświetlanie istniejących obiektów zostało tymczasowo wyłączone. - + Save to file Zapisz do pliku - + Could not open file '%1' for writing: %2 Nie udało się otworzyć pliku '%1' do zapisu: %2 - + SQL scripts (*.sql);;All files (*) Skrypty SQL (*.sql);;Wszystkie pliki (*) - + Open file Otwórz plik - + Could not open file '%1' for reading: %2 Nie udało się otworzyć pliku '%1' do odczytu: %2 - + Reached the end of document. Hit the find again to restart the search. Osiągnięto koniec dokumentu. Wciśnij szukanie ponownie, aby zrestartować szukanie. @@ -5001,36 +5218,36 @@ znajdź następny SqlQueryItem - + Column: data view tooltip Kolumna: - + Data type: data view Typ danych: - + Table: data view tooltip Tabela: - + Constraints: data view tooltip Ograniczenie: - + This cell is not editable, because: %1 Tej komórki nie można edytować, ponieważ: %1 - + Cannot load the data for a cell that refers to the already closed database. Nie można załadować danych dla komórki, która odwołuje się do zamkniętej już bazy danych. @@ -5038,68 +5255,73 @@ znajdź następny SqlQueryItemDelegate - - + + Cannot edit this cell. Details: %2 Nie można edytować tej komórki. Szczegóły: %2 - + The row is marked for deletion. Wiersz jest zaznaczony do usunięcia. + + + Foreign key for column %2 has more than %1 possible values. It's too much to display in drop down list. You need to edit value manually. + Klucz obcy dla kolumny %2 ma więcej niż %1 możliwych wartości. To zbyt wiele, by wyświetlić w liście rozwijanej. Musisz edytować wartość ręcznie. + SqlQueryModel - - + + Only one query can be executed simultaneously. Tylko jedno zapytanie może być wykonywane w danym momencie. - + Uncommited data Niezatwierdzone dane - + There are uncommited data changes. Do you want to proceed anyway? All uncommited changes will be lost. Niektóre zmiany w danych nie zostały zatwierdzone. Czy na pewno chcesz kontynuować? Wszystkie niezatwierdzone zmiany zostaną utracone. - + Cannot commit the data for a cell that refers to the already closed database. Nie można zatwierdzić danych dla komórki, która odnosi się do zamkniętej już bazy danych. - + Could not begin transaction on the database. Details: %1 Nie udało się rozpocząć transakcji na bazie danych. Szczegóły: %1 - + An error occurred while commiting the transaction: %1 Wystąpił błąd podczas zatwierdzania transakcji: %1 - + An error occurred while rolling back the transaction: %1 Wystąpił błąd podczas wycofywania transakcji: %1 - + Tried to commit a cell which is not editable (yet modified and waiting for commit)! This is a bug. Please report it. Próbowano zatwierdzić komórkę, której nie można edytować (a mimo to została zmodyfikowana i czeka na zatwierdzenie)! To jest błąd. Proszę to zgłosić. - + An error occurred while commiting the data: %1 Wystąpił błąd podczas zatwierdzania danych: %1 - - + + Error while executing SQL query on database '%1': %2 Błąd podczas wykonywania zapytania SQL na bazie '%1': %2 @@ -5108,17 +5330,17 @@ znajdź następny Błąd podczas wykonywania zapytania SQL: %1 - + Error while loading query results: %1 Błąd podczas wczytywania wyników zapytania: %1 - + Insert multiple rows Wstaw wiele wierszy - + Number of rows to insert: Liczba wierszy do wstawienia: @@ -5126,92 +5348,117 @@ znajdź następny SqlQueryView - + + Go to referenced row in... + Idź do powiązanego wiersza w... + + + Copy Kopiuj - + Copy as... Kopiuj jako... - + Paste Wklej - + Paste as... Wklej jako... - + Set NULL values Ustaw wartości NULL - + Erase values Wymaż wartości - + Edit value in editor Edytuj wartość w edytorze - + Commit Zatwierdź - + Rollback Wycofaj - + Commit selected cells Zatwierdź zaznaczone komórki - + Rollback selected cells Wycofaj zaznaczone komórki - + Define columns to sort by Zdefiniuj kolumny po których sortować - + Remove custom sorting Wycofaj własne sortowanie - + Insert row Wstaw wiersz - + Insert multiple rows Wstaw wiele wierszy - + Delete selected row Usuń zaznaczony wiersz - + + Generate query for selected cells + Generuj zapytanie dla wybranych komórek + + + No items selected to paste clipboard contents to. Nie wybrano elementów do których należy wkleić zawartość schowka. - + + Go to referenced row in table '%1' + Idź do powiązanego wiersza w tabeli '%1' + + + + table '%1' + tabela '%1' + + + + Referenced row (%1) + Powiązany wiersz (%1) + + + Edit value Edytuj wartość @@ -5219,12 +5466,12 @@ znajdź następny SqlTableModel - + Error while commiting new row: %1 Błąd podczas zatwierdzania nowego wiersza: %1 - + Error while deleting row from table %1: %2 Błąd podczas usuwania wiersza z tabeli %1: %2 @@ -5417,19 +5664,61 @@ ale można ich używać. TableStructureModel - + Name table structure columns Nazwa - + Data type table structure columns Typ danych + + + Primary +Key + table structure columns + Klucz +Główny + + + + Foreign +Key + table structure columns + Klucz +Obcy + + + + Unique + table structure columns + Wartości +unikalne + + + + Check + table structure columns + Warunek + + + + Not +NULL + table structure columns + Niepuste + + Collate + table structure columns + Zestawienie + + + Default value table structure columns Domyślna wartość @@ -5449,6 +5738,7 @@ ale można ich używać. + Data Dane @@ -5473,194 +5763,194 @@ ale można ich używać. DDL - + Export table table window Eksportuj tabelę - + Import data to table table window Importuj do tabeli - + Populate table table window Zaludnij tabelę - + Refresh structure table window Odśwież strukturę - + Commit structure changes table window Zatwierdź zmiany w strukturze - + Rollback structure changes table window Wycofaj zmiany w strukturze - + Add column table window Dodaj kolumnę - + Edit column table window Edytuj kolumnę - - + + Delete column table window Usuń kolumnę - + Move column up table window Przesuń kolumnę w górę - + Move column down table window Przesuń kolumnę w dół - + Create similar table table window Utwórz podobną tabelę - + Reset autoincrement value table window Wyzeruj wartość autoinkrementacji - + Add table constraint table window Dodaj ograniczenie tabeli - + Edit table constraint table window Edytuj ograniczenie tabeli - + Delete table constraint table window Usuń ograniczenie tabeli - + Move table constraint up table window Przesuń ograniczenie tabeli w górę - + Move table constraint down table window Przesuń ograniczenie tabeli w dół - + Add table primary key table window Dodaj klucz główny tabeli - + Add table foreign key table window Dodaj klucz obcy tabeli - + Add table unique constraint table window Dodaj ograniczenie unikalnych wartości tabeli - + Add table check constraint table window Dodaj ograniczenie warunkiem tabeli - + Refresh index list table window Odśwież listę indeksów - + Create index table window Utwórz indeks - + Edit index table window Edytuj indeks - + Delete index table window Usuń indeks - + Refresh trigger list table window Odśwież listę wyzwalaczy - + Create trigger table window Utwórz wyzwalacz - + Edit trigger table window Edytuj wyzwalacz - + Delete trigger table window Usuń wyzwalacz - + Are you sure you want to delete column '%1'? table window Czy na pewno chcesz usunąć kolumnę '%1'? - + Following problems will take place while modifying the table. Would you like to proceed? table window @@ -5668,212 +5958,222 @@ Would you like to proceed? Czy chcesz kontynuować? - + Table modification table window Modyfikacja tabeli - + Could not load data for table %1. Error details: %2 Nie udało się załadować danych dla tabeli %1. Szczegóły błędu: %2 - + Could not process the %1 table correctly. Unable to open a table window. Nie udało się przetworzyć poprawnie tabeli %1. Nie można otworzyć okna tabeli. - + Could not restore window %1, because no database or table was stored in session for this window. - + Nie można przywrócić okna %1, ponieważ nie ma bazy danych lub tabeli zachowanej w sesji dla tego okna. - + Could not restore window '%1', because no database or table was stored in session for this window. - + Nie można przywrócić okna %1, ponieważ nie ma bazy danych lub tabeli zachowanej w sesji dla tego okna. - + Could not restore window '%1', because database %2 could not be resolved. - + Nie udało się przywrócić okna '%1', ponieważ nie udało się ustalić bazy danych %2. - + Could not restore window '%1'', because the table %2 doesn't exist in the database %3. - + Nie można przywrócić okna '%1', ponieważ tabela %2 już nie jestnieje w bazie danych %3. Could not restore window, because database %1 could not be resolved. - Nie można przywrócić okna, ponieważ nie znaleziono bazy danych %1. + Nie można przywrócić okna, ponieważ nie znaleziono bazy danych %1. Could not restore window, because the table %1 doesn't exist in the database %2. - Nie można przywrócić okna, ponieważ tabela %1 już nie jestnieje w bazie danych %2. + Nie można przywrócić okna, ponieważ tabela %1 już nie jestnieje w bazie danych %2. - - + + New table %1 Nowa tabela %1 - + + Commited changes for table '%1' successfly. + Pomyślnie zatwierdzono zmiany dla tabeli '%1'. + + + + Commited changes for table '%1' (named before '%2') successfly. + Pomyślnie zatwierdzono zmiany dla tabeli '%1' (nazwanej wcześniej '%2'). + + + Could not commit table structure. Error message: %1 table window Nie udało się zatwierdzić struktury tabeli. Treść błędu: %1 - + Reset autoincrement Wyzeruj autoinkrementację - + Are you sure you want to reset autoincrement value for table '%1'? Czy na pewno chcesz wyzerować wartość autoinkrementacji dla tabeli '%1'? - + An error occurred while trying to reset autoincrement value for table '%1': %2 Wystąpił błąd podczas próby wyzerowania wartości autoinkrementacji dla tabeli '%1': %2 - + Autoincrement value for table '%1' has been reset successfly. Wartość autoinkrementacji dla tabeli '%1' została pomyślnie wyzerowana. - + Empty name Pusta nazwa - + A blank name for the table is allowed in SQLite, but it is not recommended. Are you sure you want to create a table with blank name? Pusta nazwa dla tabeli jest dozwolona w SQLite, ale nie jest zalecana. Czy na pewno chcesz utworzyć tabelę o pustej nazwie? - + Cannot create a table without at least one column. Nie można utworzyć tabeli bez przynajmniej jednej kolumny. - + Cannot create table %1, if it has no primary key defined. Either uncheck the %2, or define a primary key. Nie można utworzyć tabeli %1, jeśli nie ma zdefiniowanego klucza głównego. Albo udznacz %2, albo zdefiniuj klucz główny. - + Cannot use autoincrement for primary key when %1 clause is used. Either uncheck the %2, or the autoincrement in a primary key. Nie można użyć autoinkrementacji dla klucza głównego, kiedy klauzula %1 jest użyta. Albo odnacz %2, albo autonkrementację w kluczu głównym. - + Are you sure you want to delete table constraint '%1'? table window Czy na pewno chcesz usunąć ograniczenie tabeli '%1'? - + Delete constraint table window Usuń ograniczenie - + Cannot export, because no export plugin is loaded. Nie można wyeksportować, ponieważ żadna wtyczka eksportu nie została załadowana. - + Cannot import, because no import plugin is loaded. Nie można zaimportować, ponieważ żadna wtyczka importu nie została załadowana. - + Uncommited changes Niezatwierdzone dane - + There are uncommited structure modifications. You cannot browse or edit data until you have table structure settled. Do you want to commit the structure, or do you want to go back to the structure tab? Zmiany w strukturze nie zostały zatwierdzone. Nie można przeglądać, ani edytować danych, dopóki struktura tabeli nie zostanie ustalona. Czy chcesz zatwierdzić strukturę, czy jednak chcesz wrócić do karty struktury? - + Go back to structure tab Wróć do karty struktury - + Commit modifications and browse data. Zatwierdź modyfikacje i przeglądaj dane. - + Name table window indexes Nazwa - + Unique table window indexes Wartości unikalne - + Columns table window indexes Kolumny - + Partial index condition table window indexes Warunek indeksu częściowego: - + Name table window triggers Nazwa - + Event table window triggers Zdarzenie - + Condition table window triggers Warunek - + Details table window triggers Szczegóły - + Table window "%1" has uncommited structure modifications and data. Okno tabeli "%1" ma niezatwierdzone modyfikacje struktury i danych. - + Table window "%1" has uncommited data. Okno tabeli "%1" ma niezatwierdzone dane. - + Table window "%1" has uncommited structure modifications. Okno tabeli "%1" ma niezatwierdzone modyfikacje struktury. @@ -6030,209 +6330,280 @@ Czy chcesz zatwierdzić strukturę, czy jednak chcesz wrócić do karty struktur Nazwa widoku: - + + Output column names + Nazwy kolumn wyjściowych + + + + Data Dane - + Triggers Wyzwalacze - + DDL DDL Could not restore window, because database %1 could not be resolved. - Nie można przywrócić okna, ponieważ nie znaleziono bazy danych %1. + Nie można przywrócić okna, ponieważ nie znaleziono bazy danych %1. Could not restore window, because database %1 could not be open. - Nie można przywrócić okna, ponieważ nie udało się otworzyć bazy danych %1. + Nie można przywrócić okna, ponieważ nie udało się otworzyć bazy danych %1. Could not restore window, because the view %1 doesn't exist in the database %2. - Nie można przywrócić okna, ponieważ widok %1 już nie jestnieje w bazie danych %2. + Nie można przywrócić okna, ponieważ widok %1 już nie jestnieje w bazie danych %2. - - + + Could not restore window '%1', because no database or view was stored in session for this window. - + Nie można przywrócić okna %1, ponieważ nie ma bazy danych lub tabeli zachowanej w sesji dla tego okna. - + Could not restore window '%1', because database %2 could not be resolved. - + Nie udało się przywrócić okna '%1', ponieważ nie udało się ustalić bazy danych %2. - + Could not restore window '%1', because database %2 could not be open. - + Nie można przywrócić okna '%1', ponieważ nie można było otworzyć bazy danych %2. - + Could not restore window '%1', because the view %2 doesn't exist in the database %3. - + Nie można przywrócić okna '%1', ponieważ widok %2 już nie jestnieje w bazie danych %3. - - + + New view %1 Nowy widok %1 - + Refresh the view view window Odśwież widok - + Commit the view changes view window Zatwierdź zmiany w widoku - + Rollback the view changes view window Wycofaj zmiany w widoku - + + Explicit column names + Jawne nazwy kolumn + + + + Generate output column names automatically basing on result columns of the view. + Generuj automatycznie nazwy kolumn wyjściowych bazując na kolumnach wynikowych widoku. + + + + Add column + view window + Dodaj kolumnę + + + + Edit column + view window + Edytuj kolumnę + + + + Delete column + view window + Usuń kolumnę + + + + Move column up + view window + Przesuń kolumnę w górę + + + + Move column down + view window + Przesuń kolumnę w dół + + + Refresh trigger list view window Odśwież listę wyzwalaczy - + Create new trigger view window Utwórz nowy wyzwalacz - + Edit selected trigger view window Edytuj wybrany wyzwalacz - + Delete selected trigger view window Usuń wybrany wyzwalacz - + View window "%1" has uncommited structure modifications and data. Okno widoku "%1" ma niezatwierdzone modyfikacje struktury i danych. - + View window "%1" has uncommited data. Okno widoku "%1" ma niezatwierdzone dane. - + View window "%1" has uncommited structure modifications. Okno widoku "%1" ma niezatwierdzone modyfikacje struktury. - + Could not load data for view %1. Error details: %2 Nie udało się załadować danych dla widoku %1. Szczegóły błędu: %2 - + Uncommited changes Niezatwierdzone dane - + There are uncommited structure modifications. You cannot browse or edit data until you have the view structure settled. Do you want to commit the structure, or do you want to go back to the structure tab? Zmiany w strukturze nie zostały zatwierdzone. Nie można przeglądać, ani edytować danych, dopóki struktura widoku nie zostanie ustalona. Czy chcesz zatwierdzić strukturę, czy jednak chcesz wrócić do karty struktury? - + Go back to structure tab Wróć do karty struktury - + Commit modifications and browse data. Zatwierdź modyfikacje i przeglądaj dane. - + + Commited changes for view '%1' successfly. + Pomyślnie zatwierdzono zmiany dla widoku '%1'. + + + + Commited changes for view '%1' (named before '%2') successfly. + Pomyślnie zatwierdzono zmiany dla widoku '%1' (nazwanego wcześniej '%2'). + + + Could not commit view changes. Error message: %1 view window Nie udało się zatwierdzić widoku. Treść błędu: %1 - + + Override columns + Nadpisz kolumny + + + + Currently defined columns will be overriden. Do you want to continue? + Aktualnie zdefiniowane kolumny zostaną nadpisane. Czy chcesz kontynuować? + + + + Could not determinate columns returned from the view. The query is problably incomplete or contains errors. + Nie udało się ustalić kolumn zwracanych z widoku. Zapytanie jest prawdopodobnie niekompletne lub zawiera błędy. + + + Name view window triggers Nazwa - + Instead of view window triggers Zamiast - + Condition view window triggers Warunek - + Details table window triggers Szczegóły - + Could not process the %1 view correctly. Unable to open a view window. Nie udało się przetworzyć poprawnie widoku %1. Nie można otworzyć okna widoku. - + Empty name Pusta nazwa - + A blank name for the view is allowed in SQLite, but it is not recommended. Are you sure you want to create a view with blank name? Pusta nazwa dla widoku jest dozwolona w SQLite, ale nie jest zalecana. Czy na pewno chcesz utworzyć widok o pustej nazwie? - + The SELECT statement could not be parsed. Please correct the query and retry. Details: %1 Zapytanie SELECT nie mogło być poprawnie przeanalizowane. Proszę poprawić zapytanie i spróbować ponownie. Szczegóły: %1 - + The view could not be modified due to internal SQLiteStudio error. Please report this! Widok nie mógł być zmodyfikowany w związku z wewnętrznym błędem SQLiteStudio. Proszę to zgłosić! - + The view code could not be parsed properly for execution. This is a SQLiteStudio's bug. Please report it. Kod widok nie mógł być poprawnie przeanalizowany. To jest błąd SQLiteStudio Proszę to zgłosić! - + Following problems will take place while modifying the view. Would you like to proceed? view window @@ -6240,7 +6611,7 @@ Would you like to proceed? Czy chcesz kontynuować? - + View modification view window Modyfikacja widoku diff --git a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_pt_BR.ts b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_pt_BR.ts index 9d1c8bb..0130532 100644 --- a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_pt_BR.ts +++ b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_pt_BR.ts @@ -1,6 +1,6 @@ - + AboutDialog @@ -586,95 +586,110 @@ - + Add constraint column dialog - + Edit constraint column dialog - - + + Delete constraint column dialog - + Move constraint up column dialog - + Move constraint down column dialog - + Add a primary key column dialog - + Add a foreign key column dialog - + Add an unique constraint column dialog - + Add a check constraint column dialog - + Add a not null constraint column dialog - + Add a collate constraint column dialog - + Add a default constraint column dialog - + Are you sure you want to delete constraint '%1'? column dialog - + Correct the constraint's configuration. - + This constraint is not officially supported by SQLite 2, but it's okay to use it. + + + Scale is not allowed for INTEGER PRIMARY KEY columns. + + + + + Precision cannot be defined without the scale. + + + + + Precision is not allowed for INTEGER PRIMARY KEY columns. + + ColumnDialogConstraintsModel @@ -888,557 +903,616 @@ but it's okay to use it. ConfigDialog - + Configuration - + Search - + General - + Keyboard shortcuts - + Look & feel - + Style - + Fonts - + Colors - + Plugins - + Code formatters - + Data browsing - + Data editors - + + Database dialog window + + + + + <p>When adding new database it is marked to be "permanent" (stored in configuration) by default. Checking this option makes every new database to NOT be "permanent" by default.</p> + + + + + Do not mark database to be "permanent" by default + + + + + <p>When this option is enabled, then files dropped from file manager onto database list will be automatically added to the list, bypassing standard database dialog. If for various reasons automatic process fails, then standard dialog will be presented to the user.</p> + + + + + Try to bypass dialog completly when dropping database file onto the list + + + + Data browsing and editing - + Number of data rows per page: - - + + <p>When the data is read into grid view columns width is automatically adjusted. This value limits the initial width for the adjustment, but user can still resize the column manually over this limit.</p> - + Limit initial data column width to (in pixels): - - Inserting new row in data grid + + <p>When this is enabled and user holds mouse pointer over a cell in any data view (query results, a table data, a view data) a tooltip will appear with details about the cell - it includes details like column data type, constraints, ROWID and others.</p> - - Before currently selected row + + Show column and row details tooltip in data view + + + + + Inserting new row in data grid - - - - General.InsertRowPlacement + + Before currently selected row - + After currently selected row - + At the end of data view - + + <p>When enabled, Table Windows will show up with the data tab, instead of the structure tab.</p> + + + + + <p>When enabled the "Data" tab will be placed as first tab in every Table Window, instead of being at second place.</p> + + + + + Place data tab as first tab in a Table Window + + + + + <p>When enabled, View Windows will show up with the data tab, instead of the structure tab.</p> + + + + + <p>When enabled the "Data" tab will be placed as first tab in every View Window, instead of being at second place.</p> + + + + + Place data tab as first tab in a View Window + + + + Data types - + Available editors: - + Editors selected for this data type: - + Schema editing - + Number of DDL changes kept in history. - + DDL history size: - + Don't show DDL preview dialog when commiting schema changes - + SQL queries - - + + Number of queries kept in the history. - + History size: - + <p>If there is more than one query in the SQL editor window, then (if this option is enabled) only a single query will be executed - the one under the keyboard insertion cursor. Otherwise all queries will be executed. You can always limit queries to be executed by selecting those queries before calling to execute.</p> - + Execute only the query under the cursor - + Updates - + Automatically check for updates at startup - + Session - + Restore last session (active MDI windows) after startup - + + Status Field + + + + + <p>When user manually closes the Status panel, this option makes sure that if any new message is printed in the Status panel it will be reopened. If it's disabled, then Status panel can only be open manually by the user from the "View" menu.</p> + + + + + Always open Status panel when new message is printed + + + + Filter shortcuts by name or key combination - + Action - + Key combination - - + + Language - + Changing language requires application restart to take effect. - + Compact layout - + <p>Compact layout reduces all margins and spacing on the UI to minimum, making space for displaying more data. It makes the interface a little bit less aesthetic, but allows to display more data at once.</p> - + Use compact layout - - General.CompactLayout - - - - + + Database list - + If switched off, then columns will be sorted in the order they are typed in CREATE TABLE statement. - + Sort table columns alphabetically - + Expand tables node when connected to a database - + <p>Additional labels are those displayed next to the names on the databases list (they are blue, unless configured otherwise). Enabling this option will result in labels for databases, invalid databases and aggregated nodes (column group, index group, trigger group). For more labels see options below.<p> - + Display additional labels on the list - + For regular tables labels will show number of columns, indexes and triggers for each of tables. - + Display labels for regular tables - + Virtual tables will be marked with a 'virtual' label. - + Display labels for virtual tables - + Expand views node when connected to a database - + If this option is switched off, then objects will be sorted in order they appear in sqlite_master table (which is in order they were created) - + Sort objects (tables, indexes, triggers and views) alphabetically - + Display system tables and indexes on the list - + Table windows - - When enabled, Table Windows will show up with the data tab, instead of the structure tab. - - - - + Open Table Windows with the data tab for start - + View windows - - When enabled, View Windows will show up with the data tab, instead of the structure tab. - - - - + Open View Windows with the data tab for start - + Main window dock areas - + Left and right areas occupy corners - + Top and bottom areas occupy corners - + Hide built-in plugins - + Current style: - + Preview - + Enabled - + Disabled - + Active formatter plugin - + SQL editor font - + Database list font - + Database list additional label font - + Data view font - + Status field font - + SQL editor colors - + Current line background - + <p>SQL strings are enclosed with single quote characters.</p> - + String foreground - + <p>Bind parameters are placeholders for values yet to be provided by the user. They have one of the forms:</p><ul><li>:param_name</li><li>$param_name</li><li>@param_name</li><li>?</li></ul> - + Bind parameter foreground - + Highlighted parenthesis background - + <p>BLOB values are binary values represented as hexadecimal numbers, like:</p><ul><li>X'12B4'</li><li>x'46A2F4'</li></ul> - + BLOB value foreground - + Regular foreground - + Line numbers area background - + Keyword foreground - + Number foreground - + Comment foreground - + <p>Valid objects are name of tables, indexes, triggers, or views that exist in the SQLite database.</p> - + Valid objects foreground - + Data view colors - + <p>Any data changes will be outlined with this color, until they're commited to the database.</p> - + Uncommited data outline color - + <p>In case of error while commiting data changes, the problematic cell will be outlined with this color.</p> - + Commit error outline color - + NULL value foreground - + Deleted row background - + Database list colors - + <p>Additional labels are those which tell you SQLite version, number of objects deeper in the tree, etc.</p> - + Additional labels foreground - + Status field colors - + Information message foreground - + Warning message foreground - + Error message foreground @@ -1490,43 +1564,43 @@ but it's okay to use it. - + Plugins are loaded/unloaded immediately when checked/unchecked, but modified list of plugins to load at startup is not saved until you commit the whole configuration dialog. - + %1 (built-in) plugins manager in configuration dialog - + Details - + No plugins in this category. - + Add new data type - + Rename selected data type - + Delete selected data type - + Help for configuring data type editors @@ -1678,137 +1752,137 @@ but it's okay to use it. DataView - + Filter data data view - + Grid view - + Form view - + Refresh table data data view - + First page data view - + Previous page data view - + Next page data view - + Last page data view - + Apply filter data view - + Commit changes for selected cells data view - + Rollback changes for selected cells data view - + Show grid view of results sql editor - + Show form view of results sql editor - + Filter by text data view - + Filter by the Regular Expression data view - + Filter by SQL expression data view - + Tabs on top data view - + Tabs at bottom data view - + Place new rows above selected row data view - + Place new rows below selected row data view - + Place new rows at the end of the data view data view - + Total number of rows is being counted. Browsing other pages will be possible after the row counting is done. - + Row: %1 @@ -1955,7 +2029,7 @@ Browsing other pages will be possible after the row counting is done. - + File @@ -1976,47 +2050,47 @@ Browsing other pages will be possible after the row counting is done. - + Browse for existing database file on local computer - + Browse - + Enter an unique database name. - + This name is already in use. Please enter unique name. - + Enter a database file path. - + This database is already on the list under name: %1 - + Select a database type. - + Auto-generated - + Type the name @@ -2065,9 +2139,31 @@ Browsing other pages will be possible after the row counting is done. + Error while dropping %1: %2 + + + Delete objects + + + + + Are you sure you want to delete following objects: +%1 + + + + + Cannot start transaction. Details: %1 + + + + + Cannot commit transaction. Details: %1 + + DbTree @@ -2082,343 +2178,349 @@ Browsing other pages will be possible after the row counting is done. - + Copy - + Paste - + Select all - + Create a group - + Delete the group - + Rename the group - + Add a database - + Edit the database - + Remove the database - + Connect to the database - + Disconnect from the database - + Import - + Export the database - + Convert database type - + Vacuum - + Integrity check - + Create a table - + Edit the table - + Delete the table - + Export the table - + Import into the table - + Populate table - + Create similar table - + Reset autoincrement sequence - + Create an index - + Edit the index - + Delete the index - + Create a trigger - + Edit the trigger - + Delete the trigger - + Create a view - + Edit the view - + Delete the view - + Add a column - + Edit the column - + Delete the column - + Delete selected items - + Clear filter - + Refresh all database schemas - + Refresh selected database schema - - + + Erase table data - - + + Database - + Grouping - - + + Generate query for table + + + + + Create group - + Group name - + Entry with name %1 already exists in group %2. - + Delete group - + Are you sure you want to delete group %1? All objects from this group will be moved to parent group. - - Delete database + + Are you sure you want to remove database '%1' from the list? - - Are you sure you want to delete database '%1'? + + Are you sure you want to remove following databases from the list: +%1 - - - Cannot import, because no import plugin is loaded. + + Remove database - - - Cannot export, because no export plugin is loaded. + + Vacuum (%1) - - Error while executing VACUUM on the database %1: %2 + + + Cannot import, because no import plugin is loaded. + - VACUUM execution finished successfully. + Cannot export, because no export plugin is loaded. - + Integrity check (%1) - + Reset autoincrement - + Are you sure you want to reset autoincrement value for table '%1'? - + An error occurred while trying to reset autoincrement value for table '%1': %2 - + Autoincrement value for table '%1' has been reset successfly. - + Are you sure you want to delete all data from table '%1'? - + An error occurred while trying to delete data from table '%1': %2 - + All data has been deleted for table '%1'. - + Following objects will be deleted: %1. - + Following databases will be removed from list: %1. - + Remainig objects from deleted group will be moved in place where the group used to be. - + %1<br><br>Are you sure you want to continue? - + Delete objects @@ -2453,123 +2555,128 @@ All objects from this group will be moved to parent group. DbTreeModel - + Database: %1 dbtree tooltip - + Version: dbtree tooltip - + File size: dbtree tooltip - + Encoding: dbtree tooltip - + Error: dbtree tooltip - + Table : %1 dbtree tooltip - + Columns (%1): dbtree tooltip - + Indexes (%1): dbtree tooltip - + Triggers (%1): dbtree tooltip - + Copy - + Move - + Include data - + Include indexes - + Include triggers - + Abort - + + Could not add dropped database file '%1' automatically. Manual setup is necessary. + + + + Referenced tables - + Do you want to include following referenced tables as well: %1 - + Name conflict - + Following object already exists in the target database. Please enter new, unique name, or press '%1' to abort the operation: - + SQL statements conversion - + Following error occurred while converting SQL statements to the target SQLite version: - + Would you like to ignore those errors and proceed? @@ -3320,124 +3427,197 @@ Please enter new, unique name, or press '%1' to abort the operation: - + On table: - + Index name: - + Partial index condition - + Unique index - + Column - + Collation - + Sort - + + Delete selected indexed expression + + + + + Moves selected index column up in the order, making it more significant in the index. + + + + + Moves selected index column down in the order, making it less significant in the index. + + + + + Edit selected indexed expression + + + + + Add indexed expression + + + + DDL - + Tried to open index dialog for closed or inexisting database. - + Could not process index %1 correctly. Unable to open an index dialog. - + + Unique index cannot have indexed expressions. Either remove expressions from list below, or uncheck this option. + + + + Pick the table for the index. - + Select at least one column. - + Enter a valid condition. - + default index dialog - + Sort order table constraints - - + + Error index dialog - + Cannot create unique index, because values in selected columns are not unique. Would you like to execute SELECT query to see problematic values? - + An error occurred while executing SQL statements: %1 - LanguageDialog + IndexExprColumnDialog - - Language + + Indexed expression - - Please choose language: + + Expression to index - - - MainWindow - - Database toolbar + + This expression is already indexed by the index. - - Structure toolbar + + Column should be indexed directly, not by expression. Either extend this expression to contain something more than just column name, or abort and select this column in index dialog directly. + + + + + Column '%1' does not belong to the table covered by this index. Indexed expressions can refer only to columns from the indexed table. + + + + + It's forbidden to use 'SELECT' statements in indexed expressions. + + + + + Enter an indexed expression. + + + + + Invalid expression. + + + + + LanguageDialog + + + Language + + + + + Please choose language: + + + + + MainWindow + + + Database toolbar + + + + + Structure toolbar @@ -3456,273 +3636,273 @@ Please enter new, unique name, or press '%1' to abort the operation: - + Configuration widgets - + Syntax highlighting engines - + Data editors - + Running in debug mode. Press %1 or use 'Help / Open debug console' menu entry to open the debug console. - + Running in debug mode. Debug messages are printed to the standard output. - + You need to restart application to make the language change take effect. - + Open SQL editor - + Open DDL history - + Open SQL functions editor - + Open collations editor - + Import - + Export - + Open configuration dialog - + Tile windows - + Tile windows horizontally - + Tile windows vertically - + Cascade windows - + Next window - + Previous window - + Hide status field - + Close selected window - + Close all windows but selected - + Close all windows - + Restore recently closed window - + Rename selected window - + Open Debug Console - + Open CSS Console - + Report a bug - + Propose a new feature - + About - + Licenses - + Open home page - + Open forum page - + User Manual - + SQLite documentation - + Report history - + Check for updates - + Database menubar - + Structure menubar - + View menubar - + Window list menubar view menu - + Tools menubar - + Help - + Could not set style: %1 main window - + Cannot export, because no export plugin is loaded. - + Cannot import, because no import plugin is loaded. - + Rename window - + Enter new name for the window: - + New updates are available. <a href="%1">Click here for details</a>. - + You're running the most recent version. No updates are available. - + Database passed in command line parameters (%1) was already on the list under name: %2 - + Database passed in command line parameters (%1) has been temporarily added to the list under name: %2 - + Could not add database %1 to list. @@ -4122,127 +4302,127 @@ Please enter new, unique name, or press '%1' to abort the operation: - + Data grid view - + Copy cell(s) contents to clipboard - + Paste cell(s) contents from clipboard - + Set empty value to selected cell(s) - + Set NULL value to selected cell(s) - + Commit changes to cell(s) contents - + Rollback changes to cell(s) contents - + Delete selected data row - + Insert new data row - + Open contents of selected cell in a separate editor - + Total pages available: %1 - + Total rows loaded: %1 - + Data view (both grid and form) - + Refresh data - + Switch to grid view of the data - + Switch to form view of the data - + Database list - + Delete selected item - + Clear filter contents - + Refresh schema - + Refresh all schemas - + Add database - + Select all items - + Copy selected item(s) - + Paste from clipboard @@ -4468,6 +4648,11 @@ Please enter new, unique name, or press '%1' to abort the operation:Copy selected block of text and paste it a line above + + + Toggle comment + + All SQLite databases @@ -4540,106 +4725,106 @@ Please enter new, unique name, or press '%1' to abort the operation: - + Table window - + Refresh table structure - + Add new column - + Edit selected column - + Delete selected column - + Export table data - + Import data to the table - + Add new table constraint - + Edit selected table constraint - + Delete selected table constraint - + Refresh table index list - + Add new index - + Edit selected index - + Delete selected index - + Refresh table trigger list - + Add new trigger - + Edit selected trigger - + Delete selected trigger - + Go to next tab - + Go to previous tab @@ -4883,47 +5068,53 @@ find next - + + Toggle comment + sql editor + + + + Saved SQL contents to file: %1 - + Syntax completion can be used only when a valid database is set for the SQL editor. - + Contents of the SQL editor are huge, so errors detecting and existing objects highlighting are temporarily disabled. - + Save to file - + Could not open file '%1' for writing: %2 - + SQL scripts (*.sql);;All files (*) - + Open file - + Could not open file '%1' for reading: %2 - + Reached the end of document. Hit the find again to restart the search. @@ -4931,36 +5122,36 @@ find next SqlQueryItem - + Column: data view tooltip - + Data type: data view - + Table: data view tooltip - + Constraints: data view tooltip - + This cell is not editable, because: %1 - + Cannot load the data for a cell that refers to the already closed database. @@ -4968,83 +5159,88 @@ find next SqlQueryItemDelegate - - + + Cannot edit this cell. Details: %2 - + The row is marked for deletion. + + + Foreign key for column %2 has more than %1 possible values. It's too much to display in drop down list. You need to edit value manually. + + SqlQueryModel - - + + Only one query can be executed simultaneously. - + Uncommited data - + There are uncommited data changes. Do you want to proceed anyway? All uncommited changes will be lost. - + Cannot commit the data for a cell that refers to the already closed database. - + Could not begin transaction on the database. Details: %1 - + An error occurred while commiting the transaction: %1 - + An error occurred while rolling back the transaction: %1 - + Tried to commit a cell which is not editable (yet modified and waiting for commit)! This is a bug. Please report it. - + An error occurred while commiting the data: %1 - - + + Error while executing SQL query on database '%1': %2 - + Error while loading query results: %1 - + Insert multiple rows - + Number of rows to insert: @@ -5052,92 +5248,117 @@ find next SqlQueryView - + + Go to referenced row in... + + + + Copy - + Copy as... - + Paste - + Paste as... - + Set NULL values - + Erase values - + Edit value in editor - + Commit - + Rollback - + Commit selected cells - + Rollback selected cells - + Define columns to sort by - + Remove custom sorting - + Insert row - + Insert multiple rows - + Delete selected row - + + Generate query for selected cells + + + + No items selected to paste clipboard contents to. - + + Go to referenced row in table '%1' + + + + + table '%1' + + + + + Referenced row (%1) + + + + Edit value @@ -5145,12 +5366,12 @@ find next SqlTableModel - + Error while commiting new row: %1 - + Error while deleting row from table %1: %2 @@ -5342,19 +5563,58 @@ but it's okay to use them anyway. TableStructureModel - + Name table structure columns - + Data type table structure columns + + + Primary +Key + table structure columns + + + + + Foreign +Key + table structure columns + + + + + Unique + table structure columns + + + + + Check + table structure columns + + + + + Not +NULL + table structure columns + + + Collate + table structure columns + + + + Default value table structure columns @@ -5374,6 +5634,7 @@ but it's okay to use them anyway. + Data @@ -5398,396 +5659,406 @@ but it's okay to use them anyway. - + Export table table window - + Import data to table table window - + Populate table table window - + Refresh structure table window - + Commit structure changes table window - + Rollback structure changes table window - + Add column table window - + Edit column table window - - + + Delete column table window - + Move column up table window - + Move column down table window - + Create similar table table window - + Reset autoincrement value table window - + Add table constraint table window - + Edit table constraint table window - + Delete table constraint table window - + Move table constraint up table window - + Move table constraint down table window - + Add table primary key table window - + Add table foreign key table window - + Add table unique constraint table window - + Add table check constraint table window - + Refresh index list table window - + Create index table window - + Edit index table window - + Delete index table window - + Refresh trigger list table window - + Create trigger table window - + Edit trigger table window - + Delete trigger table window - + Are you sure you want to delete column '%1'? table window - + Following problems will take place while modifying the table. Would you like to proceed? table window - + Table modification table window - + Could not load data for table %1. Error details: %2 - + Could not process the %1 table correctly. Unable to open a table window. - + Could not restore window %1, because no database or table was stored in session for this window. - + Could not restore window '%1', because no database or table was stored in session for this window. - + Could not restore window '%1', because database %2 could not be resolved. - + Could not restore window '%1'', because the table %2 doesn't exist in the database %3. - - + + New table %1 - + + Commited changes for table '%1' successfly. + + + + + Commited changes for table '%1' (named before '%2') successfly. + + + + Could not commit table structure. Error message: %1 table window - + Reset autoincrement - + Are you sure you want to reset autoincrement value for table '%1'? - + An error occurred while trying to reset autoincrement value for table '%1': %2 - + Autoincrement value for table '%1' has been reset successfly. - + Empty name - + A blank name for the table is allowed in SQLite, but it is not recommended. Are you sure you want to create a table with blank name? - + Cannot create a table without at least one column. - + Cannot create table %1, if it has no primary key defined. Either uncheck the %2, or define a primary key. - + Cannot use autoincrement for primary key when %1 clause is used. Either uncheck the %2, or the autoincrement in a primary key. - + Are you sure you want to delete table constraint '%1'? table window - + Delete constraint table window - + Cannot export, because no export plugin is loaded. - + Cannot import, because no import plugin is loaded. - + Uncommited changes - + There are uncommited structure modifications. You cannot browse or edit data until you have table structure settled. Do you want to commit the structure, or do you want to go back to the structure tab? - + Go back to structure tab - + Commit modifications and browse data. - + Name table window indexes - + Unique table window indexes - + Columns table window indexes - + Partial index condition table window indexes - + Name table window triggers - + Event table window triggers - + Condition table window triggers - + Details table window triggers - + Table window "%1" has uncommited structure modifications and data. - + Table window "%1" has uncommited data. - + Table window "%1" has uncommited structure modifications. @@ -5943,201 +6214,272 @@ Do you want to commit the structure, or do you want to go back to the structure - + + Output column names + + + + + Data - + Triggers - + DDL - - + + Could not restore window '%1', because no database or view was stored in session for this window. - + Could not restore window '%1', because database %2 could not be resolved. - + Could not restore window '%1', because database %2 could not be open. - + Could not restore window '%1', because the view %2 doesn't exist in the database %3. - - + + New view %1 - + Refresh the view view window - + Commit the view changes view window - + Rollback the view changes view window - + + Explicit column names + + + + + Generate output column names automatically basing on result columns of the view. + + + + + Add column + view window + + + + + Edit column + view window + + + + + Delete column + view window + + + + + Move column up + view window + + + + + Move column down + view window + + + + Refresh trigger list view window - + Create new trigger view window - + Edit selected trigger view window - + Delete selected trigger view window - + View window "%1" has uncommited structure modifications and data. - + View window "%1" has uncommited data. - + View window "%1" has uncommited structure modifications. - + Could not load data for view %1. Error details: %2 - + Uncommited changes - + There are uncommited structure modifications. You cannot browse or edit data until you have the view structure settled. Do you want to commit the structure, or do you want to go back to the structure tab? - + Go back to structure tab - + Commit modifications and browse data. - + + Commited changes for view '%1' successfly. + + + + + Commited changes for view '%1' (named before '%2') successfly. + + + + Could not commit view changes. Error message: %1 view window - + + Override columns + + + + + Currently defined columns will be overriden. Do you want to continue? + + + + + Could not determinate columns returned from the view. The query is problably incomplete or contains errors. + + + + Name view window triggers - + Instead of view window triggers - + Condition view window triggers - + Details table window triggers - + Could not process the %1 view correctly. Unable to open a view window. - + Empty name - + A blank name for the view is allowed in SQLite, but it is not recommended. Are you sure you want to create a view with blank name? - + The SELECT statement could not be parsed. Please correct the query and retry. Details: %1 - + The view could not be modified due to internal SQLiteStudio error. Please report this! - + The view code could not be parsed properly for execution. This is a SQLiteStudio's bug. Please report it. - + Following problems will take place while modifying the view. Would you like to proceed? view window - + View modification view window diff --git a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_ru.qm b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_ru.qm index 9e3d103..e07a8d5 100644 Binary files a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_ru.qm and b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_ru.qm differ diff --git a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_ru.ts b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_ru.ts index 4f0ea2c..b2eba15 100644 --- a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_ru.ts +++ b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_ru.ts @@ -588,95 +588,110 @@ Расширенный режим - + Add constraint column dialog Добавить ограничение - + Edit constraint column dialog Редактировать ограничение - - + + Delete constraint column dialog - + Move constraint up column dialog Переместить ограничение вверх - + Move constraint down column dialog Переместить ограничение вниз - + Add a primary key column dialog Добавить первичный ключ - + Add a foreign key column dialog Добавить внешний ключ - + Add an unique constraint column dialog Добавить ограничение на уникальность - + Add a check constraint column dialog Добавить проверочное ограничение - + Add a not null constraint column dialog Добавить ограничение на не null - + Add a collate constraint column dialog Добавить ограничение на сравнение - + Add a default constraint column dialog Добавить ограничение на значение по умочанию - + Are you sure you want to delete constraint '%1'? column dialog Вы действительно хотите удалить ограничение '%1'? - + Correct the constraint's configuration. Исправьте конфигурацию ограничения. - + This constraint is not officially supported by SQLite 2, but it's okay to use it. Это ограничение официально не поддерживается SQLite 2, но его использование допустимо. + + + Scale is not allowed for INTEGER PRIMARY KEY columns. + + + + + Precision cannot be defined without the scale. + + + + + Precision is not allowed for INTEGER PRIMARY KEY columns. + + ColumnDialogConstraintsModel @@ -890,557 +905,632 @@ but it's okay to use it. ConfigDialog - + Configuration Конфигурация - + Search Поиск - + General Общие - + Keyboard shortcuts Горячие клавиши - + Look & feel Внешний вид - + Style Стиль - + Fonts Шрифты - + Colors Цвета - + Plugins Модули - + Code formatters Средства форматирования кода - + Data browsing Просмотр данных - + Data editors Редакторы данных - + + Database dialog window + + + + + <p>When adding new database it is marked to be "permanent" (stored in configuration) by default. Checking this option makes every new database to NOT be "permanent" by default.</p> + + + + + Do not mark database to be "permanent" by default + + + + + <p>When this option is enabled, then files dropped from file manager onto database list will be automatically added to the list, bypassing standard database dialog. If for various reasons automatic process fails, then standard dialog will be presented to the user.</p> + + + + + Try to bypass dialog completly when dropping database file onto the list + + + + Data browsing and editing Просмотр и редактирование данных - + Number of data rows per page: Количество строк данных на странице: - - + + <p>When the data is read into grid view columns width is automatically adjusted. This value limits the initial width for the adjustment, but user can still resize the column manually over this limit.</p> <p>При загрузке даных в табличный вид ширина столбцов автоматически подстраивается. Этот параметр ограничивает начальную ширину для подстройки, при этом пользователь может вручную изменить ширину столбца сверх данного лимита.</p> - + Limit initial data column width to (in pixels): Ограничить начальную ширину столбца данных (в пикселях): - + + <p>When this is enabled and user holds mouse pointer over a cell in any data view (query results, a table data, a view data) a tooltip will appear with details about the cell - it includes details like column data type, constraints, ROWID and others.</p> + + + + + Show column and row details tooltip in data view + + + + Inserting new row in data grid Вставка новой строки в таблице данных - + Before currently selected row Перед текущей выделенной строкой - - - General.InsertRowPlacement - General.InsertRowPlacement + General.InsertRowPlacement - + After currently selected row После текущей выделенной строки - + At the end of data view В конец области просмотра данных - + + <p>When enabled, Table Windows will show up with the data tab, instead of the structure tab.</p> + + + + + <p>When enabled the "Data" tab will be placed as first tab in every Table Window, instead of being at second place.</p> + + + + + Place data tab as first tab in a Table Window + + + + + <p>When enabled, View Windows will show up with the data tab, instead of the structure tab.</p> + + + + + <p>When enabled the "Data" tab will be placed as first tab in every View Window, instead of being at second place.</p> + + + + + Place data tab as first tab in a View Window + + + + Data types Типы данных - + Available editors: Доступные редакторы: - + Editors selected for this data type: Выбранные редакторы для этого типа данных: - + Schema editing Редактирование схемы - + Number of DDL changes kept in history. Количество сохраняемых в истории изменений DDL. - + DDL history size: Размер истории DDL: - + Don't show DDL preview dialog when commiting schema changes Не показывать диалог предпросмотра DDL при подтверждении изменений схемы - + SQL queries SQL запросы - - + + Number of queries kept in the history. Количество сохраняемых в истории запросов. - + History size: Размер истории: - + <p>If there is more than one query in the SQL editor window, then (if this option is enabled) only a single query will be executed - the one under the keyboard insertion cursor. Otherwise all queries will be executed. You can always limit queries to be executed by selecting those queries before calling to execute.</p> <p>Если в окне редактора SQL введено более одного запроса, то (если данная опция активирована) будет выполнен лишь один запрос - тот, который находится под текстовым курсором. В противном случае будут исполнены все запросы. Вы можете ограничить выполняемые запросы, выделив их перед вызовом выполнения.</p> - + Execute only the query under the cursor Выполнять только запрос под курсором - + Updates Обновления - + Automatically check for updates at startup Автоматически проверять обновления при запуске - + Session Сессия - + Restore last session (active MDI windows) after startup Восстановить предыдущую сессию (активные MDI окна) после запуска - + + Status Field + + + + + <p>When user manually closes the Status panel, this option makes sure that if any new message is printed in the Status panel it will be reopened. If it's disabled, then Status panel can only be open manually by the user from the "View" menu.</p> + + + + + Always open Status panel when new message is printed + + + + Filter shortcuts by name or key combination Фильтруйте горячие клавиши по имени или комбинации клавиш - + Action Действие - + Key combination Комбинация клавиш - - + + Language Язык - + Changing language requires application restart to take effect. Для смены языка потребуется перезапустить приложение. - + Compact layout Компактный режим - + <p>Compact layout reduces all margins and spacing on the UI to minimum, making space for displaying more data. It makes the interface a little bit less aesthetic, but allows to display more data at once.</p> <p>В компактном режиме все поля и отступы в интерфейсе минимизированы для отображения большего количества данных. Интерфейс станет чуть менее эстетичным, однако это позволит уместить больше данных на экране.</p> - + Use compact layout Включить компактный режим - General.CompactLayout - General.CompactLayout + General.CompactLayout - + + Database list Список баз данных - + If switched off, then columns will be sorted in the order they are typed in CREATE TABLE statement. Если опция деактивирована, столбцы будут отсортированы в том порядке, в котором они были указаны в конструкции CREATE TABLE. - + Sort table columns alphabetically Сортировать столбцы таблицы в алфавитном порядке - + Expand tables node when connected to a database Развернуть список таблиц после подключения к базе данных - + <p>Additional labels are those displayed next to the names on the databases list (they are blue, unless configured otherwise). Enabling this option will result in labels for databases, invalid databases and aggregated nodes (column group, index group, trigger group). For more labels see options below.<p> <p>Дополнительные метки находятся справа от имён в списке баз данных (они отображаются синим цветом, если не выбран иной). При активации этой опции будут отображены метки у баз данных, некорректных баз данных и у групповых узлов (группа столбцов, группа индексов, группа триггеров). Для отображения дополнительных меток воспользуйтесь опциями ниже.<p> - + Display additional labels on the list Отображать дополнительные метки в списке - + For regular tables labels will show number of columns, indexes and triggers for each of tables. Для обычных таблиц метки будут показывать количество столбцов, индексов и триггеров у каждой таблицы. - + Display labels for regular tables Отображать метки у обычных таблиц - + Virtual tables will be marked with a 'virtual' label. Виртуальные таблицы будут помечены как 'вирутальные'. - + Display labels for virtual tables Отображать метки у виртуальных таблиц - + Expand views node when connected to a database Развернуть список представлений после подключения к базе данных - + If this option is switched off, then objects will be sorted in order they appear in sqlite_master table (which is in order they were created) Если опция деактивирована, объекты будут отсортированы в том порядке, в котором они указаны в таблице sqlite_master (т.е. в порядке создания) - + Sort objects (tables, indexes, triggers and views) alphabetically Сортировать объекты (таблицы, индексы, триггеры и представления) в алфавитном порядке - + Display system tables and indexes on the list Отображать в списке системные таблицы и индексы - + Table windows Окна таблиц - When enabled, Table Windows will show up with the data tab, instead of the structure tab. - Если опция активирована, окно таблицы будет открыто на вкладке данных вместо вкладки структуры. + Если опция активирована, окно таблицы будет открыто на вкладке данных вместо вкладки структуры. - + Open Table Windows with the data tab for start Открывать окна таблиц на вкладке данных - + View windows Окна представлений - When enabled, View Windows will show up with the data tab, instead of the structure tab. - Если опция активирована, окно представления будет открыто на вкладке данных вместо вкладки структуры. + Если опция активирована, окно представления будет открыто на вкладке данных вместо вкладки структуры. - + Open View Windows with the data tab for start Открывать окна представлений на вкладке данных - + Main window dock areas Области прикрепления вокруг главного окна - + Left and right areas occupy corners Углы занимают правая и левая области - + Top and bottom areas occupy corners Углы занимают верхняя и нижняя области - + Hide built-in plugins Скрыть встроенные модули - + Current style: Текущий стиль: - + Preview Предпросмотр - + Enabled Активно - + Disabled Неактивно - + Active formatter plugin Активный модуль форматирования - + SQL editor font Шрифт редактора SQL - + Database list font Шрифт списка баз данных - + Database list additional label font Шрифт дополнительных меток в списке баз данных - + Data view font Шрифт просмотра данных - + Status field font Шрифт окна статуса - + SQL editor colors Цвета редактора SQL - + Current line background Фон текущей строки - + <p>SQL strings are enclosed with single quote characters.</p> <p>Строки SQL обрамляются в одинарные кавычки.</p> - + String foreground Цвет строки - + <p>Bind parameters are placeholders for values yet to be provided by the user. They have one of the forms:</p><ul><li>:param_name</li><li>$param_name</li><li>@param_name</li><li>?</li></ul> <p>Подстановочные параметры предназначены для значений, которые будут в дальнейшем указаны пользователем. Они определяются одним из следующих способов:</p><ul><li>:имя_параметра</li><li>$имя_параметра</li><li>@имя_параметра</li><li>?</li></ul> - + Bind parameter foreground Цвет подстановочных параметров - + Highlighted parenthesis background Фон подсвечиваемых скобок - + <p>BLOB values are binary values represented as hexadecimal numbers, like:</p><ul><li>X'12B4'</li><li>x'46A2F4'</li></ul> <p>Данные типа BLOB — это бинарные данные, представляемые в виде шестнадцатеричных чисел, например:</p><ul><li>X'12B4'</li><li>x'46A2F4'</li></ul> - + BLOB value foreground Цвет данных типа BLOB - + Regular foreground Стандартный цвет - + Line numbers area background Фон области нумерации строк - + Keyword foreground Цвет ключевого слова - + Number foreground Цвет числа - + Comment foreground Цвет комментария - + <p>Valid objects are name of tables, indexes, triggers, or views that exist in the SQLite database.</p> <p>Распознаваемыми объектами являются имена талиц, индексов, триггеров и представлений, существующих в базе данных SQLite.</p> - + Valid objects foreground Цвет распознанных объектов - + Data view colors Цвета в окне просмотра данных - + <p>Any data changes will be outlined with this color, until they're commited to the database.</p> <p>Все изменения данных будут обрамлены этим цветом, пока не будут записаны в базу данных.</p> - + Uncommited data outline color Цвет обрамления неподтверждённых изменений - + <p>In case of error while commiting data changes, the problematic cell will be outlined with this color.</p> <p>В случае ошибки при подтверждении изменений данных, этим цветом будут обрамлены проблемные ячейки.</p> - + Commit error outline color Цвет обрамления ошибочных ячеек - + NULL value foreground Цвет значений NULL - + Deleted row background Фон удалённых строк - + Database list colors Цвета списка баз данных - + <p>Additional labels are those which tell you SQLite version, number of objects deeper in the tree, etc.</p> <p>Дополнительные метки содержат информацию о версии SQLite, о количестве объектов в глубине дерева и т.д.</p> - + Additional labels foreground Цвет дополнительных меток - + Status field colors Цвета в окне Статуса - + Information message foreground Цвет информационного сообщения - + Warning message foreground Цвет предупреждения - + Error message foreground Цвет ошибки @@ -1492,43 +1582,43 @@ but it's okay to use it. Сведения о модуле - + Plugins are loaded/unloaded immediately when checked/unchecked, but modified list of plugins to load at startup is not saved until you commit the whole configuration dialog. Модули загружаются и выгружаются сразу после активации/деактивации, однако изменения в списке загружаемых при старте модулей не будут сохранены пока вы не примените изменения в окне конфигурации. - + %1 (built-in) plugins manager in configuration dialog %1 (встроенный) - + Details Сведения - + No plugins in this category. В этой категории модулей нет. - + Add new data type Добавить новый тип данных - + Rename selected data type Переименовать выбранный тип данных - + Delete selected data type Удалить выбранный тип данных - + Help for configuring data type editors Справка по настройке редакторов типов данных @@ -1680,138 +1770,138 @@ but it's okay to use it. DataView - + Filter data data view Отфильтровать данные - + Grid view Табличный вид - + Form view Форма - + Refresh table data data view Обновить данные таблицы - + First page data view Первая страница - + Previous page data view Предыдущая страница - + Next page data view Следующая страница - + Last page data view Последняя страница - + Apply filter data view Применить фильтр - + Commit changes for selected cells data view Подтвердить изменения для выбранных ячеек - + Rollback changes for selected cells data view Откатить изменения для выбранных ячеек - + Show grid view of results sql editor Показать результаты в виде таблицы - + Show form view of results sql editor Показать результаты в виде формы - + Filter by text data view Текстовый фильтр - + Filter by the Regular Expression data view Фильтр по регулярному выражению - + Filter by SQL expression data view Фильтр по выражению SQL - + Tabs on top data view Вкладки сверху - + Tabs at bottom data view Вкладки снизу - + Place new rows above selected row data view Поместить новые строки перед выделенной строкой - + Place new rows below selected row data view Поместить новые строки после выделенной строки - + Place new rows at the end of the data view data view Поместить новые строки в конец области просмотра данных - + Total number of rows is being counted. Browsing other pages will be possible after the row counting is done. Идёт подсчёт общего числа строк. Переключение на другие страницы станет возможным после окончания подсчёта. - + Row: %1 Строка: %1 @@ -1953,11 +2043,11 @@ Browsing other pages will be possible after the row counting is done. Name - Имя + Имя Type - Тип + Тип Browse for database file on local computer @@ -1970,7 +2060,7 @@ Browsing other pages will be possible after the row counting is done. - + File Файл @@ -1986,7 +2076,7 @@ Browsing other pages will be possible after the row counting is done. Permanent - Запомнить + Запомнить @@ -1996,54 +2086,54 @@ Browsing other pages will be possible after the row counting is done. Test database connection - Тест соединения с базой данных + Тест соединения с базой данных - + Browse for existing database file on local computer Указать существующий файл базы данных на локальном компьютере - + Browse Обзор - + Enter an unique database name. Введите уникальное имя базы данных. - + This name is already in use. Please enter unique name. Данное имя уже используется. Пожалуйста, укажите уникальное имя. - + Enter a database file path. Введите путь к базе данных. - + This database is already on the list under name: %1 Указанная база данных уже находится в списке под именем %1 - + Select a database type. Выберите тип базы данных. - + Auto-generated Автоматически сгенерировано The name will be auto-generated - Имя будет сгенерировано автоматически + Имя будет сгенерировано автоматически - + Type the name Введите имя @@ -2092,9 +2182,31 @@ Browsing other pages will be possible after the row counting is done. + Error while dropping %1: %2 Ошибка при удалении %1: %2 + + + Delete objects + Удалить объекты + + + + Are you sure you want to delete following objects: +%1 + + + + + Cannot start transaction. Details: %1 + + + + + Cannot commit transaction. Details: %1 + + DbTree @@ -2109,343 +2221,365 @@ Browsing other pages will be possible after the row counting is done. Фильтр по имени - + Copy Копировать - + Paste Вставить - + Select all Выделить всё - + Create a group Создать группу - + Delete the group Удалить группу - + Rename the group Переименовать группу - + Add a database Добавить базу данных - + Edit the database Редактировать базу данных - + Remove the database Удалить базу данных - + Connect to the database Подключиться к базе данных - + Disconnect from the database Отключиться от базы данных - + Import Импорт - + Export the database Экспортировать базу данных - + Convert database type Сконвертировать тип базы данных - + Vacuum Выполнить VACUUM - + Integrity check Проверить целостность - + Create a table Создать таблицу - + Edit the table Редактировать таблицу - + Delete the table Удалить таблицу - + Export the table Экспортировать таблицу - + Import into the table Импортировать данные в таблицу - + Populate table Заполнить таблицу - + Create similar table Создать подобную таблицу - + Reset autoincrement sequence Сбросить счётчик автоинкремента - + Create an index Создать индекс - + Edit the index Редактировать индекс - + Delete the index Удалить индекс - + Create a trigger Создать триггер - + Edit the trigger Редактировать триггер - + Delete the trigger Удалить триггер - + Create a view Создать представление - + Edit the view Редактировать представление - + Delete the view Удалить представление - + Add a column Добавить столбец - + Edit the column Редактировать столбец - + Delete the column Удалить столбец - + Delete selected items Удалить выбранные элементы - + Clear filter Сбросить фильтр - + Refresh all database schemas Обновить структуры всех баз данных - + Refresh selected database schema Обновить структуру выбранной базы данных - - + + Erase table data Удалить данные из таблицы - - + + Database База данных - + Grouping Группировка - - + + Generate query for table + + + + + Create group Создать группу - + Group name Имя группы - + Entry with name %1 already exists in group %2. Элемент с именем %1 уже входит в группу %2. - + Delete group Удалить группу - + Are you sure you want to delete group %1? All objects from this group will be moved to parent group. Вы действительно хотите удалить группу %1? Все объекты из данной группы будут перемещены в родительскую группу. - + + Are you sure you want to remove database '%1' from the list? + + + + + Are you sure you want to remove following databases from the list: +%1 + + + + + Remove database + + + + + Vacuum (%1) + + + Delete database - Удалить базу данных + Удалить базу данных - Are you sure you want to delete database '%1'? - Вы действительно хотите удалить базу данных '%1'? + Вы действительно хотите удалить базу данных '%1'? - - + + Cannot import, because no import plugin is loaded. Невозможно произвести импорт, т.к. не загружено ни одного модуля импорта. - - + + Cannot export, because no export plugin is loaded. Невозможно произвести экспорт, т.к. не загружено ни одного модуля экспорта. - Error while executing VACUUM on the database %1: %2 - Ошибка при выполнении команды VACUUM для базы данных %1: %2 + Ошибка при выполнении команды VACUUM для базы данных %1: %2 - VACUUM execution finished successfully. - Выполнение команды VACUUM успешно завершено. + Выполнение команды VACUUM успешно завершено. - + Integrity check (%1) Проверка целостности (%1) - + Reset autoincrement Сброс счётчика автоинкремента - + Are you sure you want to reset autoincrement value for table '%1'? Вы действительно хотите сбросить счётчик автоинкремента у таблицы '%1'? - + An error occurred while trying to reset autoincrement value for table '%1': %2 При попытке сброса счётчика автоинкремента у таблицы '%1' произошла ошибка: %2 - + Autoincrement value for table '%1' has been reset successfly. Сброс счётчика автоинкремента у таблицы '%1' успешно выполнен. - + Are you sure you want to delete all data from table '%1'? Вы действительно хотите удалить все данные из таблицы '%1'? - + An error occurred while trying to delete data from table '%1': %2 При попытке удаления данных из таблицы '%1' произошла ошибка: %2 - + All data has been deleted for table '%1'. Из таблицы '%1' были удалены все данные. - + Following objects will be deleted: %1. Будут удалены следующие объекты: %1. - + Following databases will be removed from list: %1. Из списка будут удалены следующие базы данных: %1. - + Remainig objects from deleted group will be moved in place where the group used to be. Оставшиеся после удаления группы объекты будут перемещены туда, где ранее располагалась группа. - + %1<br><br>Are you sure you want to continue? %11<br><br>Вы действительно хотите продолжить? - + Delete objects Удалить объекты @@ -2480,25 +2614,25 @@ All objects from this group will be moved to parent group. DbTreeModel - + Database: %1 dbtree tooltip База данных: %1 - + Version: dbtree tooltip Версия: - + File size: dbtree tooltip Размер файла: - + Encoding: dbtree tooltip Кодировка: @@ -2506,104 +2640,109 @@ All objects from this group will be moved to parent group. Error details: dbtree tooltip - Подробности ошибки: + Подробности ошибки: - + Error: dbtree tooltip Ошибка: - + Table : %1 dbtree tooltip Таблица: %1 - + Columns (%1): dbtree tooltip Столбцы (%1): - + Indexes (%1): dbtree tooltip Индексы (%1): - + Triggers (%1): dbtree tooltip Триггеры (%1): - + Copy Копировать - + Move Переместить - + Include data Включая данные - + Include indexes Включая индексы - + Include triggers Включая триггеры - + Abort Прервать - + + Could not add dropped database file '%1' automatically. Manual setup is necessary. + + + + Referenced tables Связанные таблицы - + Do you want to include following referenced tables as well: %1 Вы хотите также включить следующие связанные таблицы: %1 - + Name conflict Конфликт имён - + Following object already exists in the target database. Please enter new, unique name, or press '%1' to abort the operation: Данный объект уже существует в целевой базе данных. Пожалуйста введите новое уникальное имя или нажмите %1 для прерывания операции: - + SQL statements conversion Конвертация конструкций SQL - + Following error occurred while converting SQL statements to the target SQLite version: При конвертации конструкций SQL в новую версию SQLite произошла ошибка: - + Would you like to ignore those errors and proceed? Вы хотите проигнорировать эти ошибки и продолжить? @@ -3356,102 +3495,175 @@ Please enter new, unique name, or press '%1' to abort the operation:Индекс - + On table: Для таблицы: - + Index name: Имя индекса: - + Partial index condition Условие для частичного индекса - + Unique index Уникальный индекс - + Column Столбец - + Collation Сравнение - + Sort Сортировка - + + Delete selected indexed expression + + + + + Moves selected index column up in the order, making it more significant in the index. + + + + + Moves selected index column down in the order, making it less significant in the index. + + + + + Edit selected indexed expression + + + + + Add indexed expression + + + + DDL DDL - + Tried to open index dialog for closed or inexisting database. Попытка вызвать диалог создания индекса для закрытой или несуществующей базы данных. - + Could not process index %1 correctly. Unable to open an index dialog. Не удалось корректно обработать индекс %1. Невозможно открыть окно индекса. - + + Unique index cannot have indexed expressions. Either remove expressions from list below, or uncheck this option. + + + + Pick the table for the index. Выберите таблицу для индекса. - + Select at least one column. Выберите хотя бы один столбец. - + Enter a valid condition. Введите корректное условие. - + default index dialog по умолчанию - + Sort order table constraints Порядок сортировки - - + + Error index dialog Ошибка - + Cannot create unique index, because values in selected columns are not unique. Would you like to execute SELECT query to see problematic values? Невозможно создать уникальный индекс, т.к. данные в выбранных столбцах неуникальны. Вы хотите выполнить запрос SELECT для просмотра проблемных данных? - + An error occurred while executing SQL statements: %1 При выполнении конструкций SQL произошла ошибка: %1 + + IndexExprColumnDialog + + + Indexed expression + + + + + Expression to index + + + + + This expression is already indexed by the index. + + + + + Column should be indexed directly, not by expression. Either extend this expression to contain something more than just column name, or abort and select this column in index dialog directly. + + + + + Column '%1' does not belong to the table covered by this index. Indexed expressions can refer only to columns from the indexed table. + + + + + It's forbidden to use 'SELECT' statements in indexed expressions. + + + + + Enter an indexed expression. + + + + + Invalid expression. + + + LanguageDialog @@ -3493,273 +3705,273 @@ Please enter new, unique name, or press '%1' to abort the operation:Панель отображения - + Configuration widgets Виджеты конфигурации - + Syntax highlighting engines Движки синтаксической подсветки - + Data editors Редакторы данных - + Running in debug mode. Press %1 or use 'Help / Open debug console' menu entry to open the debug console. Отладочный режим. Нажмите %1 или воспользуйтесь пунктом меню 'Справка / Открыть отладочную консоль' для открытия отладочной консоли. - + Running in debug mode. Debug messages are printed to the standard output. Отладочный режим. Отладочные сообщения выводятся в стандартный выходной поток. - + You need to restart application to make the language change take effect. Для смены языка необходимо перезапустить приложение. - + Open SQL editor Открыть редактор SQL - + Open DDL history Открыть историю DDL - + Open SQL functions editor Открыть редактор функций SQL - + Open collations editor Открыть редактор сравнений - + Import Импорт - + Export Экспорт - + Open configuration dialog Открыть диалог конфигурации - + Tile windows Расположить окна плиткой - + Tile windows horizontally Расположить окна по горизонтали - + Tile windows vertically Расположить окна по вертикали - + Cascade windows Расположить окна каскадом - + Next window Следующее окно - + Previous window Предыдущее окно - + Hide status field Скрыть окно статуса - + Close selected window Закрыть выбранное окно - + Close all windows but selected Закрыть все окна, кроме выбранного - + Close all windows Закрыть все окна - + Restore recently closed window Восстановить недавно закрытые окна - + Rename selected window Переименовать выбранное окно - + Open Debug Console Открыть отладочную консоль - + Open CSS Console Открыть консоль CSS - + Report a bug Сообщить об ошибке - + Propose a new feature Предложить новый функционал - + About О программе - + Licenses Лицензии - + Open home page Открыть домашнюю страницу - + Open forum page Открыть страницу форума - + User Manual Руководство пользователя - + SQLite documentation Документация по SQLite - + Report history История отчётов - + Check for updates Проверить обновления - + Database menubar База данных - + Structure menubar Структура - + View menubar Вид - + Window list menubar view menu Окна - + Tools menubar Инструменты - + Help Справка - + Could not set style: %1 main window Невозможно применить стиль: %1 - + Cannot export, because no export plugin is loaded. Невозможно произвести экспорт, т.к. не загружено ни одного модуля экспорта. - + Cannot import, because no import plugin is loaded. Невозможно произвести импорт, т.к. не загружено ни одного модуля импорта. - + Rename window Переименовать окно - + Enter new name for the window: Введите новое имя для окна: - + New updates are available. <a href="%1">Click here for details</a>. Доступны обновления. <a href="%1">Нажмите здесь для подробностей</a>. - + You're running the most recent version. No updates are available. Установлена последняя версия. Обновлений нет. - + Database passed in command line parameters (%1) was already on the list under name: %2 База данных, переданная через аргументы командной строки (%1), уже находится в списке под именем %2 - + Database passed in command line parameters (%1) has been temporarily added to the list under name: %2 База данных, переданная через аргументы командной строки (%1), была временно добавлена в список под именем %2 - + Could not add database %1 to list. Невозможно добавить базу данных %1 в список. @@ -4159,127 +4371,127 @@ Please enter new, unique name, or press '%1' to abort the operation:имя сравнения: %1 - + Data grid view Табличный вид данных - + Copy cell(s) contents to clipboard Копировать содержимое ячеек в буфер обмена - + Paste cell(s) contents from clipboard Вставить содержимое ячеек из буфера обмена - + Set empty value to selected cell(s) Установить пустое значение для выбранных ячеек - + Set NULL value to selected cell(s) Установить для выбранных ячеек значение NULL - + Commit changes to cell(s) contents Подтвердить изменение содержимого ячеек - + Rollback changes to cell(s) contents Откатить изменения содержимого ячеек - + Delete selected data row Удалить выбранную строку данных - + Insert new data row Вставить новую строку данных - + Open contents of selected cell in a separate editor Открыть содержимое выбранной ячейки в отдельном редакторе - + Total pages available: %1 Всего доступно страниц: %1 - + Total rows loaded: %1 Всего загружено строк: %1 - + Data view (both grid and form) Окно данных (и табличный вид, и форма) - + Refresh data Обновить данные - + Switch to grid view of the data Переключиться с табличного вида на форму - + Switch to form view of the data Переключиться из формы на табличный вид - + Database list Список баз данных - + Delete selected item Удалить выбранный элемент - + Clear filter contents Сбросить содержимое фильтра - + Refresh schema Обновить структуру - + Refresh all schemas Обновить структуры всех баз данных - + Add database Добавить базу данных - + Select all items Выделить все элементы - + Copy selected item(s) Копировать выбранные элементы - + Paste from clipboard @@ -4505,6 +4717,11 @@ Please enter new, unique name, or press '%1' to abort the operation:Copy selected block of text and paste it a line above Скопировать блок текста и вставить его строчкой выше + + + Toggle comment + + All SQLite databases @@ -4577,106 +4794,106 @@ Please enter new, unique name, or press '%1' to abort the operation:Переместить фокус ввода в окно редактора SQL вверху - + Table window Окно таблицы - + Refresh table structure Обновить структуру таблицы - + Add new column Добавить новый столбец - + Edit selected column Редактировать выбранный столбец - + Delete selected column Удалить выбранный столбец - + Export table data Экспортировать данные таблицы - + Import data to the table Импортировать данные в таблицу - + Add new table constraint Добавить новое ограничение на таблицу - + Edit selected table constraint Редактировать выбранное ограничение на таблицу - + Delete selected table constraint Удалить выбранное ограничение на таблицу - + Refresh table index list Обновить список индексов таблицы - + Add new index Добавить новый индекс - + Edit selected index Редактировать выбранный индекс - + Delete selected index Удалить выбранный индекс - + Refresh table trigger list Обновить список триггеров таблицы - + Add new trigger Добавить новый триггер - + Edit selected trigger Редактировать выбранный триггер - + Delete selected trigger Удалить выбранный триггер - + Go to next tab Перейти к следующей вкладке - + Go to previous tab Перейти к предыдущей вкладке @@ -4922,47 +5139,53 @@ find next Заменить - + + Toggle comment + sql editor + + + + Saved SQL contents to file: %1 SQL-код сохранён в файле %1 - + Syntax completion can be used only when a valid database is set for the SQL editor. Дополнение синтаксиса может быть использовано только после назначения корректной базы данных редактору SQL. - + Contents of the SQL editor are huge, so errors detecting and existing objects highlighting are temporarily disabled. Размер содержимого редактора SQL слишком велико, поэтому обнаружение ошибок и подсветка существующих объектов временно отключена. - + Save to file Сохранить в файл - + Could not open file '%1' for writing: %2 Невозможно открыть файл '%1' для записи: %2 - + SQL scripts (*.sql);;All files (*) Скрипты SQL (*.sql);;Все файлы (*) - + Open file Открыть файл - + Could not open file '%1' for reading: %2 Невозможно открыть файл '%1' для чтения: %2 - + Reached the end of document. Hit the find again to restart the search. Достигнут конец документа. Нажмите Найти снова для перезапуска поиска. @@ -4970,36 +5193,36 @@ find next SqlQueryItem - + Column: data view tooltip Столбец: - + Data type: data view Тип данных: - + Table: data view tooltip Таблица: - + Constraints: data view tooltip Ограничения: - + This cell is not editable, because: %1 Эта ячейка нередактируема, причина: %1 - + Cannot load the data for a cell that refers to the already closed database. Невозможно загрузить данные ячейки, которая ссылается на уже закрытую базу данных. @@ -5007,83 +5230,88 @@ find next SqlQueryItemDelegate - - + + Cannot edit this cell. Details: %2 Невозможно редактировать данную ячейку. Подробности: %2 - + The row is marked for deletion. Строка помечена для удаления. + + + Foreign key for column %2 has more than %1 possible values. It's too much to display in drop down list. You need to edit value manually. + + SqlQueryModel - - + + Only one query can be executed simultaneously. Одновременно может быть выполнен только один запрос. - + Uncommited data Неподтверждённые данные - + There are uncommited data changes. Do you want to proceed anyway? All uncommited changes will be lost. Имеются неподтверждённые изменения данных. Вы действительно хотите продолжить? Все неподтверждённые изменения будут утеряны. - + Cannot commit the data for a cell that refers to the already closed database. Невозможно подтвердить данные для ячейки, которая ссылается на уже закрытую базу данных. - + Could not begin transaction on the database. Details: %1 Невозможно начать транзакцию в базе данных. Подробности: %1 - + An error occurred while commiting the transaction: %1 При завершении транзакции возникла ошибка: %1 - + An error occurred while rolling back the transaction: %1 При отмене транзакции возникла ошибка: %1 - + Tried to commit a cell which is not editable (yet modified and waiting for commit)! This is a bug. Please report it. Попытка подтверждения данных для нередактируемой ячейки (которая тем не менее была изменена и ожидает подтверждения). Это программная ошибка. Пожалуйста, отправьте о ней отчёт. - + An error occurred while commiting the data: %1 При подтверждении данных произошла ошибка: %1 - - + + Error while executing SQL query on database '%1': %2 Ошибка при выполнении SQL запроса к базе данных '%1': %2 - + Error while loading query results: %1 Ошибка при загрузке результатов запроса: %1 - + Insert multiple rows Вставить несколько строк - + Number of rows to insert: Количество вставляемых строк: @@ -5091,92 +5319,117 @@ find next SqlQueryView - + + Go to referenced row in... + + + + Copy Копировать - + Copy as... Копировать как... - + Paste Вставить - + Paste as... Вставить как... - + Set NULL values Установить значения на NULL - + Erase values Стереть содержимое - + Edit value in editor Править содержимое в редакторе - + Commit Подтвердить - + Rollback Откатить - + Commit selected cells Подтвердить выбранные ячейки - + Rollback selected cells Откатить выбранные ячейки - + Define columns to sort by Определить столбцы для сортировки - + Remove custom sorting Сбросить указанную сортировку - + Insert row Вставить строку - + Insert multiple rows Вставить несколько строк - + Delete selected row Удалить выбранную строку - + + Generate query for selected cells + + + + No items selected to paste clipboard contents to. Не выбраны элементы для вставки в них содержимого буфера обмена. - + + Go to referenced row in table '%1' + + + + + table '%1' + + + + + Referenced row (%1) + + + + Edit value Править содержимое @@ -5184,12 +5437,12 @@ find next SqlTableModel - + Error while commiting new row: %1 Ошибка при подтверждении новой строки: %1 - + Error while deleting row from table %1: %2 Ошибка при удалении строки из таблицы %1: %2 @@ -5382,19 +5635,58 @@ but it's okay to use them anyway. TableStructureModel - + Name table structure columns Имя - + Data type table structure columns Тип данных + + + Primary +Key + table structure columns + + + + + Foreign +Key + table structure columns + + + + + Unique + table structure columns + Уникальность + + + + Check + table structure columns + Проверка + + + + Not +NULL + table structure columns + + + Collate + table structure columns + Сравнение + + + Default value table structure columns Значение по умолчанию @@ -5414,6 +5706,7 @@ but it's okay to use them anyway. + Data Данные @@ -5438,194 +5731,194 @@ but it's okay to use them anyway. DDL - + Export table table window Экспортировать таблицу - + Import data to table table window Импортировать данные в таблицу - + Populate table table window Заполнить таблицу - + Refresh structure table window Обновить структуру - + Commit structure changes table window Подтвердить изменения структуры - + Rollback structure changes table window Откатить изменения структуры - + Add column table window Добавить столбец - + Edit column table window Редактировать столбец - - + + Delete column table window Удалить столбец - + Move column up table window Переместить столбец вверх - + Move column down table window Переместить столбец вниз - + Create similar table table window Создать подобную таблицу - + Reset autoincrement value table window Сбросить счётчик автоинкремента - + Add table constraint table window Добавить ограничение на таблицу - + Edit table constraint table window Редактировать ограничение на таблицу - + Delete table constraint table window Удалить ограничение на таблицу - + Move table constraint up table window Переместить ограничение на таблицу вверх - + Move table constraint down table window Переместить ограничение на таблицу вниз - + Add table primary key table window Добавить первичный ключ таблицы - + Add table foreign key table window Добавить внешний ключ таблицы - + Add table unique constraint table window Добавить табличное ограничение на уникальность - + Add table check constraint table window Добавить проверочное ограничение на таблицу - + Refresh index list table window Обновить список индексов - + Create index table window Создать индекс - + Edit index table window Редактировать индекс - + Delete index table window Удалить индекс - + Refresh trigger list table window Обновить список триггеров - + Create trigger table window Создать триггер - + Edit trigger table window Редактировать триггер - + Delete trigger table window Удалить триггер - + Are you sure you want to delete column '%1'? table window Вы действительно хотите удалить столбец '%1'? - + Following problems will take place while modifying the table. Would you like to proceed? table window @@ -5633,212 +5926,222 @@ Would you like to proceed? Вы хотите продолжить? - + Table modification table window Изменение таблицы - + Could not load data for table %1. Error details: %2 Невозможно загрузить данные таблицы %1. Подробности ошибки: %2 - + Could not process the %1 table correctly. Unable to open a table window. Не удалось корректно обработать таблицу %1. Невозможно открыть окно таблицы. - + Could not restore window %1, because no database or table was stored in session for this window. Невозможно восстановить окно %1, так как в сессии для этого окна не была сохранена база данных или таблица. - + Could not restore window '%1', because no database or table was stored in session for this window. Невозможно восстановить окно '%1', так как в сессии для этого окна не была сохранена база данных или таблица. - + Could not restore window '%1', because database %2 could not be resolved. Невозможно восстановить окно '%1', так как невозможно определить базу данных %2 - + Could not restore window '%1'', because the table %2 doesn't exist in the database %3. Невозможно восстановить окно '%1', так как таблица %2 не существует в базе данных %3. Could not restore window, because database %1 could not be resolved. - Невозможно восстановить окно, так как невозможно определить базу данных %1 + Невозможно восстановить окно, так как невозможно определить базу данных %1 Could not restore window, because the table %1 doesn't exist in the database %2. - Невозможно восстановить окно, так как таблица %1 не существует в базе данных %2. + Невозможно восстановить окно, так как таблица %1 не существует в базе данных %2. - - + + New table %1 Новая таблица %1 - + + Commited changes for table '%1' successfly. + + + + + Commited changes for table '%1' (named before '%2') successfly. + + + + Could not commit table structure. Error message: %1 table window Невозможно подтвердить структуру таблицы. Сообщение об ошибке: %1 - + Reset autoincrement Сброс счётчика автоинкремента - + Are you sure you want to reset autoincrement value for table '%1'? Вы действительно хотите сбросить счётчик автоинкремента у таблицы '%1'? - + An error occurred while trying to reset autoincrement value for table '%1': %2 При попытке сброса счётчика автоинкремента у таблицы '%1' произошла ошибка: %2 - + Autoincrement value for table '%1' has been reset successfly. Сброс счётчика автоинкремента у таблицы '%1' успешно выполнен. - + Empty name Пустое имя - + A blank name for the table is allowed in SQLite, but it is not recommended. Are you sure you want to create a table with blank name? SQLite позволяет таблице иметь пустое имя, хотя это не рекомендуется. Вы действительно хотите создать таблицу с пустым именем? - + Cannot create a table without at least one column. Невозможно создать таблицу без хотя бы одного столбца. - + Cannot create table %1, if it has no primary key defined. Either uncheck the %2, or define a primary key. Невозможно создать таблицу %1, если не определён первичный ключ. Отключите %2, либо определите первичный ключ. - + Cannot use autoincrement for primary key when %1 clause is used. Either uncheck the %2, or the autoincrement in a primary key. Невозможно использовать автоинкремент первичного ключа при использовании оператора %1. Отключите либо %2, либо автоинкремент первичного ключа. - + Are you sure you want to delete table constraint '%1'? table window Вы действительно хотите удалить ограничение на таблицу '%1'? - + Delete constraint table window Удалить ограничение - + Cannot export, because no export plugin is loaded. Невозможно произвести экспорт, т.к. не загружено ни одного модуля экспорта. - + Cannot import, because no import plugin is loaded. Невозможно произвести импорт, т.к. не загружено ни одного модуля импорта. - + Uncommited changes Неподтверждённые изменения - + There are uncommited structure modifications. You cannot browse or edit data until you have table structure settled. Do you want to commit the structure, or do you want to go back to the structure tab? Имеются неподтверждённые изменения структуры. Невозможно просматривать или редактировать данные, пока структура таблицы не подтверждена. Подтвердить структуру таблицы или вернуться на вкладку структуры? - + Go back to structure tab Вернуться на вкладку структуры - + Commit modifications and browse data. Подтвердить изменения и перейти к данным. - + Name table window indexes Имя - + Unique table window indexes Уникальность - + Columns table window indexes Столбцы - + Partial index condition table window indexes Условие для частичного индекса - + Name table window triggers Имя - + Event table window triggers Событие - + Condition table window triggers Условие - + Details table window triggers Подробности - + Table window "%1" has uncommited structure modifications and data. В окне таблицы "%1" имеются неподтверждённые изменения структуры и данных. - + Table window "%1" has uncommited data. В окне таблицы "%1" имеются неподтверждённые изменения данных. - + Table window "%1" has uncommited structure modifications. В окне таблицы "%1" имеются неподтверждённые изменения структуры. @@ -5995,209 +6298,280 @@ Do you want to commit the structure, or do you want to go back to the structure Имя представления: - + + Output column names + + + + + Data Данные - + Triggers Триггеры - + DDL DDL Could not restore window, because database %1 could not be resolved. - Невозможно восстановить окно, так как невозможно определить базу данных %1. + Невозможно восстановить окно, так как невозможно определить базу данных %1. Could not restore window, because database %1 could not be open. - Невозможно восстановить окно, так как невозможно открыть базу данных %1. + Невозможно восстановить окно, так как невозможно открыть базу данных %1. Could not restore window, because the view %1 doesn't exist in the database %2. - Невозможно восстановить окно, так как представление %1 не существует в базе данных %2. + Невозможно восстановить окно, так как представление %1 не существует в базе данных %2. - - + + Could not restore window '%1', because no database or view was stored in session for this window. Невозможно восстановить окно '%1', так как в сессии для этого окна не была сохранена база данных или представление. - + Could not restore window '%1', because database %2 could not be resolved. Невозможно восстановить окно '%1', так как невозможно определить базу данных %2. - + Could not restore window '%1', because database %2 could not be open. Невозможно восстановить окно '%1', так как невозможно открыть базу данных %2. - + Could not restore window '%1', because the view %2 doesn't exist in the database %3. Невозможно восстановить окно '%1', так как представление %2 не существует в базе данных %3. - - + + New view %1 Новое представление %1 - + Refresh the view view window Обновить представление - + Commit the view changes view window Подтвердить изменения представления - + Rollback the view changes view window Откатить изменения представления - + + Explicit column names + + + + + Generate output column names automatically basing on result columns of the view. + + + + + Add column + view window + Добавить столбец + + + + Edit column + view window + Редактировать столбец + + + + Delete column + view window + Удалить столбец + + + + Move column up + view window + Переместить столбец вверх + + + + Move column down + view window + Переместить столбец вниз + + + Refresh trigger list view window Обновить список триггеров - + Create new trigger view window Создать новый триггер - + Edit selected trigger view window Редактировать выбранный триггер - + Delete selected trigger view window Удалить выбранный триггер - + View window "%1" has uncommited structure modifications and data. В окне представления "%1" имеются неподтверждённые изменения структуры и данных. - + View window "%1" has uncommited data. В окне представления "%1" имеются неподтверждённые изменения данных. - + View window "%1" has uncommited structure modifications. В окне представления "%1" имеются неподтверждённые изменения структуры. - + Could not load data for view %1. Error details: %2 Невозможно загрузить данные представления %1. Подробности ошибки: %2 - + Uncommited changes Неподтверждённые изменения - + There are uncommited structure modifications. You cannot browse or edit data until you have the view structure settled. Do you want to commit the structure, or do you want to go back to the structure tab? Имеются неподтверждённые изменения структуры. Невозможно просматривать или редактировать данные, пока структура представления не подтверждена. Подтвердить структуру представления или вернуться на вкладку структуры? - + Go back to structure tab Вернуться на вкладку структуры - + Commit modifications and browse data. Подтвердить изменения и перейти к данным. - + + Commited changes for view '%1' successfly. + + + + + Commited changes for view '%1' (named before '%2') successfly. + + + + Could not commit view changes. Error message: %1 view window Невозможно подтвердить изменения представления. Сообщение об ошибке: %1 - + + Override columns + + + + + Currently defined columns will be overriden. Do you want to continue? + + + + + Could not determinate columns returned from the view. The query is problably incomplete or contains errors. + + + + Name view window triggers Имя - + Instead of view window triggers Вместо - + Condition view window triggers Условие - + Details table window triggers Подробности - + Could not process the %1 view correctly. Unable to open a view window. Не удалось корректно обработать представление %1. Невозможно открыть окно представления. - + Empty name Пустое имя - + A blank name for the view is allowed in SQLite, but it is not recommended. Are you sure you want to create a view with blank name? SQLite позволяет представлению иметь пустое имя, хотя это не рекомендуется. Вы действительно хотите создать представление с пустым именем? - + The SELECT statement could not be parsed. Please correct the query and retry. Details: %1 Невозможно проанализировать структуру конструкции SELECT. Пожалуйста, исправьте запрос и повторите попытку. Подробности: %1 - + The view could not be modified due to internal SQLiteStudio error. Please report this! Невозможно изменить представление из-за внутренней ошибки SQLiteStudio. Пожалуйста, сообщите о ней! - + The view code could not be parsed properly for execution. This is a SQLiteStudio's bug. Please report it. Невозможно корректно проанализировать структуру представления для выполнения. Это ошибка SQLiteStudio. Пожалуйста, сообщите о ней. - + Following problems will take place while modifying the view. Would you like to proceed? view window @@ -6205,7 +6579,7 @@ Would you like to proceed? Вы хотите продолжить? - + View modification view window Изменение представления diff --git a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_sk.qm b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_sk.qm index 47656ef..ac0f46e 100644 Binary files a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_sk.qm and b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_sk.qm differ diff --git a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_sk.ts b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_sk.ts index 39f70f8..e6625c1 100644 --- a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_sk.ts +++ b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_sk.ts @@ -588,95 +588,110 @@ Rozšírený mód - + Add constraint column dialog Pridať obmedzenie - + Edit constraint column dialog Upraviť obmedzenie - - + + Delete constraint column dialog Vymazať obmedzenie - + Move constraint up column dialog Posunúť obmedzenie hore - + Move constraint down column dialog Posunúť obmedzenie dole - + Add a primary key column dialog Pridať primárny kľúč - + Add a foreign key column dialog Pridať cudzí kľúč - + Add an unique constraint column dialog Pridať jedinečné obmedzenie - + Add a check constraint column dialog - + Add a not null constraint column dialog - + Add a collate constraint column dialog - + Add a default constraint column dialog - + Are you sure you want to delete constraint '%1'? column dialog Ste si istý, že chcete vymazať obmedzenie '%1'? - + Correct the constraint's configuration. - + This constraint is not officially supported by SQLite 2, but it's okay to use it. + + + Scale is not allowed for INTEGER PRIMARY KEY columns. + + + + + Precision cannot be defined without the scale. + + + + + Precision is not allowed for INTEGER PRIMARY KEY columns. + + ColumnDialogConstraintsModel @@ -890,530 +905,624 @@ but it's okay to use it. ConfigDialog - + Configuration Konfigurácia - + Search Hľadať - + General Všeobecné - + Keyboard shortcuts Klávesové skratky - + Look & feel Vzhľad - + Style Štýl - + Fonts Fonty - + Colors Farby - + Plugins Pluginy - + Code formatters Formát kódu - + Data browsing Prezeranie dát - + Data editors Editory dát - + + Database dialog window + + + + + <p>When adding new database it is marked to be "permanent" (stored in configuration) by default. Checking this option makes every new database to NOT be "permanent" by default.</p> + + + + + Do not mark database to be "permanent" by default + + + + + <p>When this option is enabled, then files dropped from file manager onto database list will be automatically added to the list, bypassing standard database dialog. If for various reasons automatic process fails, then standard dialog will be presented to the user.</p> + + + + + Try to bypass dialog completly when dropping database file onto the list + + + + Data browsing and editing Prezeranie a úprava dát - + Number of data rows per page: Počet data riadkov na stranu: - - + + <p>When the data is read into grid view columns width is automatically adjusted. This value limits the initial width for the adjustment, but user can still resize the column manually over this limit.</p> - + Limit initial data column width to (in pixels): - + + <p>When this is enabled and user holds mouse pointer over a cell in any data view (query results, a table data, a view data) a tooltip will appear with details about the cell - it includes details like column data type, constraints, ROWID and others.</p> + + + + + Show column and row details tooltip in data view + + + + + Inserting new row in data grid + + + + + Before currently selected row + + + + + After currently selected row + + + + + At the end of data view + + + + + <p>When enabled, Table Windows will show up with the data tab, instead of the structure tab.</p> + + + + + <p>When enabled the "Data" tab will be placed as first tab in every Table Window, instead of being at second place.</p> + + + + + Place data tab as first tab in a Table Window + + + + + <p>When enabled, View Windows will show up with the data tab, instead of the structure tab.</p> + + + + + <p>When enabled the "Data" tab will be placed as first tab in every View Window, instead of being at second place.</p> + + + + + Place data tab as first tab in a View Window + + + + Data types Datové typy - + Available editors: Dostupné editory: - + Editors selected for this data type: - + Schema editing Úprava schémy - + Number of DDL changes kept in history. Počet DDL zmien uchovávaných v histórii. - + DDL history size: Veľkosť DDL histórie: - + Don't show DDL preview dialog when commiting schema changes Nezobrazovať náhľad DDL pri potvrdzovaní zmien v schéme - + SQL queries SQL dotazy - - + + Number of queries kept in the history. Počet dotazov uchovávaných v histórii. - + History size: Veľkosť SQL histórie: - + <p>If there is more than one query in the SQL editor window, then (if this option is enabled) only a single query will be executed - the one under the keyboard insertion cursor. Otherwise all queries will be executed. You can always limit queries to be executed by selecting those queries before calling to execute.</p> <p>Ak je v SQL editore viacej ako jeden dotaz, potom(ak je táto voľba zapnutá) bude vykonaný iba jeden dotaz - ten, na ktorom je kurzor. Ináč budú vykonané všetky dotazy. Vždy si viete vybrať ktoré dotazy budú vykonané a to ich výberom\označením.</p> - + Execute only the query under the cursor Vykonať len dotaz, na ktorom stojí kurzor - + Updates Aktualizácie - + Automatically check for updates at startup Kontrolovať aktualizácie pri štarte - + Session Sedenie - + Restore last session (active MDI windows) after startup Obnoviť posledné sedenie (aktívne okná) pri štarte - + + Status Field + + + + + <p>When user manually closes the Status panel, this option makes sure that if any new message is printed in the Status panel it will be reopened. If it's disabled, then Status panel can only be open manually by the user from the "View" menu.</p> + + + + + Always open Status panel when new message is printed + + + + Filter shortcuts by name or key combination Filtrovať podľa názvu alebo klávesovej skratky - + Action Akcia - + Key combination Klávesová skratka - - + + Language Jazyk - + Changing language requires application restart to take effect. Je potrebné reštartovať aplikáciu aby sa zmena jazyka prejavila. - + Compact layout - + <p>Compact layout reduces all margins and spacing on the UI to minimum, making space for displaying more data. It makes the interface a little bit less aesthetic, but allows to display more data at once.</p> - + Use compact layout - - General.CompactLayout - - - - + + Database list Zoznam databáz - + If switched off, then columns will be sorted in the order they are typed in CREATE TABLE statement. - + Sort table columns alphabetically Zoradiť stĺpce tabuľky abecedne - + Expand tables node when connected to a database Rozbaliť zoznam tabuliek po pripojení k databáze - + <p>Additional labels are those displayed next to the names on the databases list (they are blue, unless configured otherwise). Enabling this option will result in labels for databases, invalid databases and aggregated nodes (column group, index group, trigger group). For more labels see options below.<p> - + Display additional labels on the list Zobraziť doplnkové popisky v zozname - + For regular tables labels will show number of columns, indexes and triggers for each of tables. - + Display labels for regular tables Zobraziť popisky pre regulárne tabuľky - + Virtual tables will be marked with a 'virtual' label. - + Display labels for virtual tables Zobraziť popisky pre virtuálne tabuľky - + Expand views node when connected to a database Rozbaliť zoznam pohľadov po pripojení k databáze - + If this option is switched off, then objects will be sorted in order they appear in sqlite_master table (which is in order they were created) - + Sort objects (tables, indexes, triggers and views) alphabetically Zoradiť objekty (tabuľky, indexy, spúšťače a pohľady) abecedne - + Display system tables and indexes on the list Zobraziť systémové tabuľky a indexy v zozname - + Table windows Okná tabuľky - When enabled, Table Windows will show up with the data tab, instead of the structure tab. - Ak je táto možnosť zaškrtnutá, tak sa v okne zobrazia dáta a nie štruktúra tabuľky. + Ak je táto možnosť zaškrtnutá, tak sa v okne zobrazia dáta a nie štruktúra tabuľky. - + Open Table Windows with the data tab for start Zobraziť dáta po otvorení tabuľky - + View windows Okná pohľadov - When enabled, View Windows will show up with the data tab, instead of the structure tab. - Ak je táto možnosť zaškrtnutá, tak sa v okne zobrazia dáta a nie SQL dotaz. + Ak je táto možnosť zaškrtnutá, tak sa v okne zobrazia dáta a nie SQL dotaz. - + Open View Windows with the data tab for start Zobraziť dáta po otvorení pohľadu - + Main window dock areas - + Left and right areas occupy corners - + Top and bottom areas occupy corners - + Hide built-in plugins Nezobrazovať interné pluginy - + Current style: Aktuálny štýl: - + Preview Náhľad - + Enabled Zapnutý - + Disabled Vypnutý - + Active formatter plugin Aktívny formátovací plugin - + SQL editor font Písmo SQL editora - + Database list font Font zoznamu databáz - + Database list additional label font Font doplnkového popisku - + Data view font Font dát - + Status field font Font status okna - + SQL editor colors Farby SQL editora - + Current line background - + <p>SQL strings are enclosed with single quote characters.</p> - + String foreground - + <p>Bind parameters are placeholders for values yet to be provided by the user. They have one of the forms:</p><ul><li>:param_name</li><li>$param_name</li><li>@param_name</li><li>?</li></ul> - + Bind parameter foreground - + Highlighted parenthesis background - + <p>BLOB values are binary values represented as hexadecimal numbers, like:</p><ul><li>X'12B4'</li><li>x'46A2F4'</li></ul> - + BLOB value foreground Farba BLOB hodnoty - + Regular foreground - + Line numbers area background - + Keyword foreground - + Number foreground - + Comment foreground - + <p>Valid objects are name of tables, indexes, triggers, or views that exist in the SQLite database.</p> - + Valid objects foreground - + Data view colors Farby dát - + <p>Any data changes will be outlined with this color, until they're commited to the database.</p> <p>Všetky zmeny dát budú ohraničené touto farbou, dokiaľ nebudú potvrdené.</p> - + Uncommited data outline color Farba rámčeka nepotvrdených dát - + <p>In case of error while commiting data changes, the problematic cell will be outlined with this color.</p> <p>V prípade chyby pri potvrdzovaní zmien dát, budú problematické bunky ohraničené touto farbou.</p> - + Commit error outline color Farba rámčeka s chybou potvrdenia dát - + NULL value foreground Farba NULL hodnoty - + Deleted row background Pozadie vymazaného riadka - + Database list colors Farby zoznamu databáz - + <p>Additional labels are those which tell you SQLite version, number of objects deeper in the tree, etc.</p> - + Additional labels foreground Farba doplnkového popisku - + Status field colors Farby status okna - + Information message foreground Farba informačnej správy - + Warning message foreground Farba upozornenia - + Error message foreground Farba chybovej správy @@ -1465,43 +1574,43 @@ but it's okay to use it. Detaily pluginu - + Plugins are loaded/unloaded immediately when checked/unchecked, but modified list of plugins to load at startup is not saved until you commit the whole configuration dialog. Pluginy sú načítané/uvoľnené okamžite pri zaškrtnutí/odškrtnutí ale midifikovaný zoznam pluginov načítaných pri štarte nieje uložený až kým nepotvrdíte celý konfiguračný dialóg. - + %1 (built-in) plugins manager in configuration dialog %1 (interný) - + Details Detaily - + No plugins in this category. - + Add new data type Pridať nový datový typ - + Rename selected data type Premenovať vybraný datový typ - + Delete selected data type Vymazať vybraný datový typ - + Help for configuring data type editors @@ -1653,120 +1762,138 @@ but it's okay to use it. DataView - + Filter data data view Filtrovať - + Grid view Tabuľkové zobrazenie - + Form view Formulárové zobrazenie - + Refresh table data data view Obnoviť dáta v tabuľke - + First page data view Prvá strana - + Previous page data view Predchádzajúca strana - + Next page data view Nasledujúca strana - + Last page data view Posledná strana - + Apply filter data view Aplikovať filter - + Commit changes for selected cells data view Potvrdiť zmeny pre vybrané bunky - + Rollback changes for selected cells data view Vrátiť späť zmeny pre vybrané bunky - + Show grid view of results sql editor Výsledky zobraziť v tabuľke - + Show form view of results sql editor Výsledky zobraziť vo formulári - + Filter by text data view Filtrovať pomocou textu - + Filter by the Regular Expression data view Filtrovať pomocou regulárneho výrazu - + Filter by SQL expression data view Filtrovať pomocou SQL výrazu - + Tabs on top data view Záložky hore - + Tabs at bottom data view Záložky dole - + + Place new rows above selected row + data view + + + + + Place new rows below selected row + data view + + + + + Place new rows at the end of the data view + data view + + + + Total number of rows is being counted. Browsing other pages will be possible after the row counting is done. Spočítava sa celkový počet riadkov. Prezeranie ďalších strán bude možné až po dokončení spočítavania. - + Row: %1 Riadok:%1 @@ -1908,11 +2035,11 @@ Prezeranie ďalších strán bude možné až po dokončení spočítavania. Name - Názov + Názov Type - Typ + Typ Browse for database file on local computer @@ -1925,7 +2052,7 @@ Prezeranie ďalších strán bude možné až po dokončení spočítavania. - + File Súbor @@ -1941,7 +2068,7 @@ Prezeranie ďalších strán bude možné až po dokončení spočítavania. Permanent - Uložiť natrvalo + Uložiť natrvalo @@ -1951,54 +2078,54 @@ Prezeranie ďalších strán bude možné až po dokončení spočítavania. Test database connection - Otestovať spojenie s databázou + Otestovať spojenie s databázou - + Browse for existing database file on local computer Hľadať databázový súbor na lokálnom počítači - + Browse Prehľadávať - + Enter an unique database name. Zadajte názov databázy. - + This name is already in use. Please enter unique name. Tento názov už existuje. Prosím zadajte iný názov. - + Enter a database file path. Zadajte cestu k databázovému súboru. - + This database is already on the list under name: %1 Táto databáza už je v zozname pod názvom: %1 - + Select a database type. Vyberte typ databázy. - + Auto-generated Automaticky vygenerovaný The name will be auto-generated - Názov bude vygenerovaný automaticky + Názov bude vygenerovaný automaticky - + Type the name Zadajte meno @@ -2048,9 +2175,31 @@ Prezeranie ďalších strán bude možné až po dokončení spočítavania. + Error while dropping %1: %2 Vyskystla sa chyba počas mazania %1: %2 + + + Delete objects + Odstránenie objektov + + + + Are you sure you want to delete following objects: +%1 + + + + + Cannot start transaction. Details: %1 + + + + + Cannot commit transaction. Details: %1 + + DbTree @@ -2065,344 +2214,366 @@ Prezeranie ďalších strán bude možné až po dokončení spočítavania.Filtrovať podľa názvu - + Copy Kopírovať - + Paste Vložiť - + Select all Vybrať všetko - + Create a group Vytvoriť skupinu - + Delete the group Vymazať skupinu - + Rename the group Premenovať skupinu - + Add a database Pridať databázu - + Edit the database Upraviť databázu - + Remove the database Odstrániť databázu - + Connect to the database Pripojiť sa k databáze - + Disconnect from the database Odpojiť sa od databázy - + Import Importovať - + Export the database Exportovať databázu - + Convert database type Konvertovať databázu - + Vacuum Vacuum - + Integrity check Kontrola integrity - + Create a table Vytvoriť tabuľku - + Edit the table Upraviť tabuľku - + Delete the table Vymazať tabuľku - + Export the table Exportovať tabuľku - + Import into the table Importovať do tabuľky - + Populate table Naplniť tabuľku - + Create similar table Vytvoriť rovnakú tabuľku - + Reset autoincrement sequence Resetovať sekvenciu autoinkrementu - + Create an index Vytvoriť index - + Edit the index Upraviť index - + Delete the index Vymazať index - + Create a trigger Vytvoriť spúšťač - + Edit the trigger Upraviť spúšťač - + Delete the trigger Vymazať spúšťač - + Create a view Vytvoriť pohľad - + Edit the view Upraviť pohľad - + Delete the view Vymazať pohľad - + Add a column Pridať stĺpec - + Edit the column Upraviť stĺpec - + Delete the column Vymazať stĺpec - + Delete selected items Vymazať vybrané položky - + Clear filter Zrušiť filter - + Refresh all database schemas Obnoviť všetky databázové schémy - + Refresh selected database schema Obnoviť vybranú databázovú schému - - + + Erase table data Vymazať dáta z tabuľky - - + + Database Databáza - + Grouping Zoskupovanie - - + + Generate query for table + + + + + Create group Vytvoriť skupinu - + Group name Názov skupiny - + Entry with name %1 already exists in group %2. Položka s názvom %1 už existuje v skupine %2. - + Delete group Vymazať skupinu - + Are you sure you want to delete group %1? All objects from this group will be moved to parent group. Ste si istý, že chcete vymazať skupinu %1? Všetky objekty z tejto skupiny budú presunuté do nadradenej skupiny. - + + Are you sure you want to remove database '%1' from the list? + + + + + Are you sure you want to remove following databases from the list: +%1 + + + + + Remove database + + + + + Vacuum (%1) + + + Delete database - Odstrániť databázu + Odstrániť databázu - Are you sure you want to delete database '%1'? - Ste si istý, že chcete odstrániť databázu '%1'? + Ste si istý, že chcete odstrániť databázu '%1'? - - + + Cannot import, because no import plugin is loaded. Nemôžem importovať, lebo nebol načítaný žiaden plugin na import. - - + + Cannot export, because no export plugin is loaded. Nemôžem exportovať, lebo nebol načítaný žiaden plugin na export. - Error while executing VACUUM on the database %1: %2 - Vyskytla sa chyba počas vykonávania príkazu VACUUM na databáze %1: %2 + Vyskytla sa chyba počas vykonávania príkazu VACUUM na databáze %1: %2 - VACUUM execution finished successfully. - VACUUM úspešne skončilo. + VACUUM úspešne skončilo. - + Integrity check (%1) Kontrola integrity (%1) - + Reset autoincrement Resetovať autoinkrement - + Are you sure you want to reset autoincrement value for table '%1'? Ste si istý, že chcete zresetovať hodnotu autoinkrementu pre tabuľku %1 ? - + An error occurred while trying to reset autoincrement value for table '%1': %2 Vyskytla sa chyba pri pokuse o zresetovanie hodnoty autoinkrementu pre tebuľku '%1': %2 - + Autoincrement value for table '%1' has been reset successfly. - + Are you sure you want to delete all data from table '%1'? Ste si istý, že chcete vymazať všetky dáta z tabuľky '%1'? - + An error occurred while trying to delete data from table '%1': %2 Vyskytla sa chyba pri pokuse vymazať dáta z tabuľky '%1': %2 - + All data has been deleted for table '%1'. Všetky dáta z tabuľky '%1' boli vymazané. - + Following objects will be deleted: %1. Nasledujúce objekty budú odstránené: %1. - + Following databases will be removed from list: %1. Nasledujúce databázy budú odstránené zo zoznamu: %1. - + Remainig objects from deleted group will be moved in place where the group used to be. - + %1<br><br>Are you sure you want to continue? %1<br><br>Ste si istý, že chcete pokračovať? - + Delete objects Odstránenie objektov @@ -2437,25 +2608,25 @@ Všetky objekty z tejto skupiny budú presunuté do nadradenej skupiny. DbTreeModel - + Database: %1 dbtree tooltip Databáza: %1 - + Version: dbtree tooltip Verzia: - + File size: dbtree tooltip Veľkosť súboru: - + Encoding: dbtree tooltip Kódovanie: @@ -2463,102 +2634,107 @@ Všetky objekty z tejto skupiny budú presunuté do nadradenej skupiny. Error details: dbtree tooltip - Detaily chyby: + Detaily chyby: - + Error: dbtree tooltip - + Table : %1 dbtree tooltip Tabuľka : %1 - + Columns (%1): dbtree tooltip Stĺpce (%1): - + Indexes (%1): dbtree tooltip Indexy (%1): - + Triggers (%1): dbtree tooltip Spúšťače (%1): - + Copy Kopírovať - + Move - + Include data - + Include indexes - + Include triggers - + Abort Zrušiť - + + Could not add dropped database file '%1' automatically. Manual setup is necessary. + + + + Referenced tables - + Do you want to include following referenced tables as well: %1 - + Name conflict - + Following object already exists in the target database. Please enter new, unique name, or press '%1' to abort the operation: - + SQL statements conversion - + Following error occurred while converting SQL statements to the target SQLite version: - + Would you like to ignore those errors and proceed? @@ -3077,12 +3253,12 @@ Please enter new, unique name, or press '%1' to abort the operation: Register in all databases - + Registrovať vo všetkých databázach Register in following databases: - + Registrovať v nasledujúcich databázach: @@ -3173,7 +3349,7 @@ Please enter new, unique name, or press '%1' to abort the operation: Pick the implementation language. - + Vyberte implementačný jazyk. @@ -3183,7 +3359,7 @@ Please enter new, unique name, or press '%1' to abort the operation: Enter a non-empty implementation code. - + Zadajte implementačný kód. @@ -3260,42 +3436,42 @@ Please enter new, unique name, or press '%1' to abort the operation:Nastavenia dátového zdroja - + Cancel Zrušiť - + If you type table name that doesn't exist, it will be created. Ak zadáte názov neexistujúcej tabuľky, tak bude vytvorená. - + Enter the table name Zadajte názov tabuľky - + Select import plugin. Vyberte importný plugin. - + You must provide a file to import from. Musíte zadať súbor, z ktorého sa budú importovať dáta. - + The file '%1' does not exist. Súbor %1 neexistuje. - + Path you provided is a directory. A regular file is required. Cesta, ktorú ste zadali je adresár. Prosím zadajte celú cestu. - + Pick file to import from Výber súboru, z ktorého sa budú importovať dáta @@ -3309,101 +3485,174 @@ Please enter new, unique name, or press '%1' to abort the operation:Index - + On table: Na tabuľke: - + Index name: Názov indexu: - + Partial index condition - + Unique index Jedinečný index - + Column Stĺpec - + Collation Porovnávanie - + Sort Zoradiť - - DDL - DDL + + Delete selected indexed expression + - + + Moves selected index column up in the order, making it more significant in the index. + + + + + Moves selected index column down in the order, making it less significant in the index. + + + + + Edit selected indexed expression + + + + + Add indexed expression + + + + + DDL + DDL + + + Tried to open index dialog for closed or inexisting database. - + Could not process index %1 correctly. Unable to open an index dialog. - + + Unique index cannot have indexed expressions. Either remove expressions from list below, or uncheck this option. + + + + Pick the table for the index. - + Select at least one column. Vyberte minimálne jeden stĺpec. - + Enter a valid condition. Zadajte platnú podmienku. - + default index dialog - + Sort order table constraints Zoradiť - - + + Error index dialog Chyba - + Cannot create unique index, because values in selected columns are not unique. Would you like to execute SELECT query to see problematic values? Nemôžem vytvoriť jedinečný index, pretože hodnoty vo vybraných stĺpcoch nie sú jedinečné. Chcete spustiť dotaz SELECT na zobrazenie problematických hodnôt? - + An error occurred while executing SQL statements: %1 + + IndexExprColumnDialog + + + Indexed expression + + + + + Expression to index + + + + + This expression is already indexed by the index. + + + + + Column should be indexed directly, not by expression. Either extend this expression to contain something more than just column name, or abort and select this column in index dialog directly. + + + + + Column '%1' does not belong to the table covered by this index. Indexed expressions can refer only to columns from the indexed table. + + + + + It's forbidden to use 'SELECT' statements in indexed expressions. + + + + + Enter an indexed expression. + + + + + Invalid expression. + + + LanguageDialog @@ -3445,273 +3694,273 @@ Please enter new, unique name, or press '%1' to abort the operation:Lišta pohľadov - + Configuration widgets - + Syntax highlighting engines - + Data editors Editory dát - + Running in debug mode. Press %1 or use 'Help / Open debug console' menu entry to open the debug console. - + Running in debug mode. Debug messages are printed to the standard output. Beží v ladiacom móde. Ladiace správy sú vypisované na štandardný výstup. - + You need to restart application to make the language change take effect. Je potrebné reštartovať aplikáciu aby sa zmena jazyka prejavila. - + Open SQL editor Otvoriť SQL editor - + Open DDL history Otvoriť DDL históriu - + Open SQL functions editor Otvoriť editor SQL funkcií - + Open collations editor Otvoriť editor porovnávaní - + Import Import - + Export Export - + Open configuration dialog Konfigurácia - + Tile windows Oddeliť okná - + Tile windows horizontally Oddeliť okná horizontálne - + Tile windows vertically Oddeliť okná vertikálne - + Cascade windows Okná kaskádovito - + Next window Nasledujúce okno - + Previous window Predchádzajúce okno - + Hide status field - + Close selected window Zatvoriť vybrané okno - + Close all windows but selected Zatvoriť všetky okná okrem vybraného - + Close all windows Zatvoriť všetky okná - + Restore recently closed window Obnoviť posledné zatvorené okno - + Rename selected window Premenovať vybrané okno - + Open Debug Console Otvoriť ladiacu konzolu - + Open CSS Console Otvoriť CSS konzolu - + Report a bug Nahlásiť chybu - + Propose a new feature Navrhnúť novú funkciu - + About O programe - + Licenses Licencie - + Open home page Otvoriť domovskú stránku - + Open forum page Otvoriť fórum - + User Manual Používateľský manuál - + SQLite documentation Dokumentácia SQLite - + Report history História hlásení - + Check for updates Skontrolovať akutalizácie - + Database menubar Databázy - + Structure menubar Štruktúry - + View menubar Zobrazenie - + Window list menubar view menu Lišta okien - + Tools menubar Nástroje - + Help Pomoc - + Could not set style: %1 main window Nemôžem nastaviť štýl: %1 - + Cannot export, because no export plugin is loaded. Nemôžem exportovať, lebo nebol načítaný žiaden plugin na export. - + Cannot import, because no import plugin is loaded. Nemôžem importovať, lebo nebol načítaný žiaden plugin na import. - + Rename window Premenovať okno - + Enter new name for the window: Zadajte nový názov pre okno: - + New updates are available. <a href="%1">Click here for details</a>. Nové aktualizácie sú dostupné. <a href="%1">Kliknite sem pre zobrazenie detailov</a>. - + You're running the most recent version. No updates are available. Niesú dostupné žiadne aktualizácie. Používate aktuálnu verziu. - + Database passed in command line parameters (%1) was already on the list under name: %2 Databáza prebratá z príkazového riadka (%1) už je v zozname pod názvom: %2 - + Database passed in command line parameters (%1) has been temporarily added to the list under name: %2 Databáza prebratá z príkazového riadka (%1) bola dočasne pridaná do zoznamu pod názvom: %2 - + Could not add database %1 to list. Nemôžem pridať databázu %1 do zoznamu. @@ -4111,129 +4360,129 @@ Please enter new, unique name, or press '%1' to abort the operation:Názov porovnánavania: %1 - + Data grid view Tabuľkové zobrazenie dát - + Copy cell(s) contents to clipboard Kopírovať obsah buniek do schránky - + Paste cell(s) contents from clipboard Vložiť obsah buniek zo schránky - + Set empty value to selected cell(s) Vymazať hodnoty z vybraných buniek - + Set NULL value to selected cell(s) Nastaviť NULL hodnotu vo vybraných bunkách - + Commit changes to cell(s) contents Potvrdiť zmeny v bunkách - + Rollback changes to cell(s) contents Vrátiť späť zmeny v bunkách - + Delete selected data row Vymazať vybraný riadok - + Insert new data row Vložiť nový riadok - + Open contents of selected cell in a separate editor Otvoriť obsah vybranej bunky v samostatnom editore - + Total pages available: %1 Celkový počet strán: %1 - + Total rows loaded: %1 Celkový počet riadkov: %1 - + Data view (both grid and form) Zobrazenie dát (tabuľka a formulár) - + Refresh data Obnoviť dáta - + Switch to grid view of the data Prepnúť na tabuľkové zobrazenie dát - + Switch to form view of the data Prepnúť na formulárové zobrazenie dát - + Database list Zoznam databáz - + Delete selected item Vymazať vybranú položku - + Clear filter contents Vymazať filter - + Refresh schema Obnoviť schému - + Refresh all schemas Obnoviť všetky schémy - + Add database Pridať databázu - + Select all items Vybrať všetky položky - + Copy selected item(s) Kopírovať vybrané položky - + - + Paste from clipboard Vložiť zo schránky @@ -4345,7 +4594,7 @@ Please enter new, unique name, or press '%1' to abort the operation: Open CSS Console - + Otvoriť CSS konzolu @@ -4354,109 +4603,114 @@ Please enter new, unique name, or press '%1' to abort the operation: - + Cut selected text Vystrihnúť vybraný text - + Copy selected text Kopírovať vybraný text - + Delete selected text Vymazať vybraný text - + Undo - + Redo - + SQL editor input field - + Select whole editor contents Označiť všetko - + Save contents into a file Uložiť SQL do súboru - + Load contents from a file Načítať SQL zo súboru - + Find in text Nájsť v SQL - + Find next Nájsť ďalší - + Find previous Nájsť predchádzajúci - + Replace in text Nahradiť v SQL - + Delete current line Vymazať aktuálny riadok - + Request code assistant Otvoriť SQL pomocníka - + Format contents Formátovať SQL - + Move selected block of text one line down Presunúť blok kódu o riadok nižšie - + Move selected block of text one line up Presunúť blok kódu o riadok vyššie - + Copy selected block of text and paste it a line below Kopírovať blok kódu a vložiť ho na riadok nižšie - + Copy selected block of text and paste it a line above Kopírovať blok kódu a vložiť ho na riadok vyššie + + + Toggle comment + + All SQLite databases @@ -4529,106 +4783,106 @@ Please enter new, unique name, or press '%1' to abort the operation:Prepnúť kurzor do editora - + Table window Okno tabuľky - + Refresh table structure Obnoviť štruktúru tabuľky - + Add new column Pridať nový stĺpec - + Edit selected column Upraviť vybraný stĺpec - + Delete selected column Vymazať vybraný stĺpec - + Export table data Exportovať dáta z tabuľky - + Import data to the table Importovať dáta do tabuľky - + Add new table constraint Pridať nové obmedzenie - + Edit selected table constraint Upraviť vybrané obmedzenie - + Delete selected table constraint Vymazať vybrané obmedzenie - + Refresh table index list Obnoviť zoznam indexov - + Add new index Pridať nový index - + Edit selected index Upraviť vybraný index - + Delete selected index Vymazať vybraný index - + Refresh table trigger list Obnoviť zoznam spúšťačov - + Add new trigger Pridať nový spúšťač - + Edit selected trigger Upraviť vybraný spúšťač - + Delete selected trigger Vymazať vybraný spúšťač - + Go to next tab Prechod na nasledujúcu záložku - + Go to previous tab Prechod na predchádzajúcu záložku @@ -4747,173 +5001,179 @@ nájsť ďalší SqlEditor - + Cut sql editor Vystrihnúť - + Copy sql editor Kopírovať - + Paste sql editor Vložiť - + Delete sql editor Vymazať - + Select all sql editor Vybrať všetko - + Undo sql editor - + Redo sql editor - + Complete sql editor - + Format SQL sql editor Formátovať SQL - + Save SQL to file sql editor Uložiť SQL do súboru - + Select file to save SQL sql editor - + Load SQL from file sql editor Načítať SQL zo súboru - + Delete line sql editor Vymazať riadok - + Move block down sql editor - + Move block up sql editor - + Copy block down sql editor - + Copy up down sql editor - + Find sql editor Nájsť - + Find next sql editor Nájsť ďalší - + Find previous sql editor Nájsť predchádzajúci - + Replace sql editor Nahradiť - + + Toggle comment + sql editor + + + + Saved SQL contents to file: %1 - + Syntax completion can be used only when a valid database is set for the SQL editor. - + Contents of the SQL editor are huge, so errors detecting and existing objects highlighting are temporarily disabled. - + Save to file Uložiť do súboru - + Could not open file '%1' for writing: %2 Nemôžem otvoriť súbor '%1' pre zápis: %2 - + SQL scripts (*.sql);;All files (*) - + Open file Otvoriť súbor - + Could not open file '%1' for reading: %2 Nemôžem otvoriť súbor '%1' na čítanie: %2 - + Reached the end of document. Hit the find again to restart the search. Dosiahnutý koniec súboru. Kliknite na tlačidlo Nájsť pre hľadanie od začiatku súboru. @@ -4921,36 +5181,36 @@ nájsť ďalší SqlQueryItem - + Column: data view tooltip Stĺpec: - + Data type: data view Datový typ: - + Table: data view tooltip Tabuľka: - + Constraints: data view tooltip Obmedzenia: - + This cell is not editable, because: %1 Táto bunka nieje editovateľná, pretože: %1 - + Cannot load the data for a cell that refers to the already closed database. @@ -4958,83 +5218,88 @@ nájsť ďalší SqlQueryItemDelegate - - + + Cannot edit this cell. Details: %2 - + The row is marked for deletion. + + + Foreign key for column %2 has more than %1 possible values. It's too much to display in drop down list. You need to edit value manually. + + SqlQueryModel - - + + Only one query can be executed simultaneously. Nemôže byť spustených viacero dotazov súčasne. - + Uncommited data Nepotvrdené dáta - + There are uncommited data changes. Do you want to proceed anyway? All uncommited changes will be lost. Sú tu nepotvrdené zmeny. Chcete aj napriek tomu pokračovať? Všetky nepotvrdené zmeny budú stratené. - + Cannot commit the data for a cell that refers to the already closed database. Nemôžem potrdiť dáta bunky, ktorá odkazuje na už uzatvorenú databázu. - + Could not begin transaction on the database. Details: %1 Nemôžem začať tranzakciu na databáze. Detaily: %1 - + An error occurred while commiting the transaction: %1 Vyskytla sa chyba počas potvrdzovania tranzakcie: %1 - + An error occurred while rolling back the transaction: %1 Vyskytla sa chyba počas vracania späť tranzakcie: %1 - + Tried to commit a cell which is not editable (yet modified and waiting for commit)! This is a bug. Please report it. Nastal pokus o potvrdenie zmien v bunke, ktorú nieje možné upravovať (napriek tomu bola upravená a čaká na potvrdenie)! Toto je chyba. Prosím nahláste ju. - + An error occurred while commiting the data: %1 Vyskytla sa chyba počas potvrdzovania dát: %1 - - + + Error while executing SQL query on database '%1': %2 Vyskytla sa chyba počas vykonávania SQL dotazu na databáze '%1': %2 - + Error while loading query results: %1 Vyskytla sa chyba počas načítavania výsledkov dotazu: %1 - + Insert multiple rows Vložiť viacero riadkov - + Number of rows to insert: Počet vkládaných riadkov: @@ -5042,92 +5307,117 @@ nájsť ďalší SqlQueryView - + + Go to referenced row in... + + + + Copy Kopírovať - + Copy as... Kopírovať ako... - + Paste Vložiť - + Paste as... Vložiť ako... - + Set NULL values Nastaviť null hodnoty - + Erase values Vymazať hodnoty - + Edit value in editor Upraviť hodnotu v editory - + Commit Potvrdiť - + Rollback Vrátiť späť - + Commit selected cells Potvrdiť vybrané bunky - + Rollback selected cells Vrátiť späť vybrané bunky - + Define columns to sort by Vybrať stĺpce na zoradenie podľa - + Remove custom sorting Odstrániť užívateľské triedenie - + Insert row Vložiť riadok - + Insert multiple rows Vložiť viacero riadkov - + Delete selected row Vymazať viacero riadkov - + + Generate query for selected cells + + + + No items selected to paste clipboard contents to. Neboli vybrané žiadne položky na vloženie obsahu schránky. - + + Go to referenced row in table '%1' + + + + + table '%1' + + + + + Referenced row (%1) + + + + Edit value Upraviť hodnotu @@ -5135,12 +5425,12 @@ nájsť ďalší SqlTableModel - + Error while commiting new row: %1 Vyskytla sa chyba počas potvrdzovania nového riadka: %1 - + Error while deleting row from table %1: %2 Vyskytla sa chyba počas mazania riadka z tabuľky %1: %2 @@ -5332,19 +5622,58 @@ but it's okay to use them anyway. TableStructureModel - + Name table structure columns Názov - + Data type table structure columns Datový typ + + + Primary +Key + table structure columns + + + + + Foreign +Key + table structure columns + + + + + Unique + table structure columns + + + + + Check + table structure columns + + + + + Not +NULL + table structure columns + + + Collate + table structure columns + + + + Default value table structure columns Prednastavená hodnota @@ -5364,6 +5693,7 @@ but it's okay to use them anyway. + Data Dáta @@ -5388,397 +5718,407 @@ but it's okay to use them anyway. DDL - + Export table table window Exportovať tabuľku - + Import data to table table window Importovať dáta do tabuľky - + Populate table table window Naplniť tabuľku - + Refresh structure table window Obnoviť štruktúru - + Commit structure changes table window Potvrdiť zmeny štruktúr - + Rollback structure changes table window Vrátiť späť zmeny štruktúr - + Add column table window Pridať stĺpec - + Edit column table window Upraviť stĺpec - - + + Delete column table window Vymazať stĺpec - + Move column up table window Posunúť stĺpec hore - + Move column down table window Posunúť stĺpec dole - + Create similar table table window Vytvoriť rovnakú tabuľku - + Reset autoincrement value table window Resetovať hodnotu autoinkrementu - + Add table constraint table window Pridať obmedzenie - + Edit table constraint table window Upraviť obmedzenie - + Delete table constraint table window Vymazať obmedzenie - + Move table constraint up table window Posunúť obmedzenie hore - + Move table constraint down table window Posunúť obmedzenie dole - + Add table primary key table window Pridať primárny kľúč - + Add table foreign key table window Pridať cudzí kľúč - + Add table unique constraint table window Pridať jedinečné obmedzenie - + Add table check constraint table window - + Refresh index list table window Obnoviť zoznam indexov - + Create index table window Vytvoriť index - + Edit index table window Upraviť index - + Delete index table window Vymazať index - + Refresh trigger list table window Obnoviť zoznam spúšťačov - + Create trigger table window Vytvoriť spúšťač - + Edit trigger table window Upraviť spúšťač - + Delete trigger table window Vymazať spúšťač - + Are you sure you want to delete column '%1'? table window Ste si istý, že chcete vymazať stĺpec '%1' ? - + Following problems will take place while modifying the table. Would you like to proceed? table window - + Table modification table window - + Could not load data for table %1. Error details: %2 - + Could not process the %1 table correctly. Unable to open a table window. - + Could not restore window %1, because no database or table was stored in session for this window. - + Could not restore window '%1', because no database or table was stored in session for this window. - + Could not restore window '%1', because database %2 could not be resolved. - + Could not restore window '%1'', because the table %2 doesn't exist in the database %3. - - + + New table %1 - + + Commited changes for table '%1' successfly. + + + + + Commited changes for table '%1' (named before '%2') successfly. + + + + Could not commit table structure. Error message: %1 table window - + Reset autoincrement Resetovať autoinkrement - + Are you sure you want to reset autoincrement value for table '%1'? Ste si istý, že chcete zresetovať hodnotu autoinkrementu pre tabuľku %1 ? - + An error occurred while trying to reset autoincrement value for table '%1': %2 Vyskytla sa chyba pri pokuse o zresetovanie hodnoty autoinkrementu pre tebuľku '%1': %2 - + Autoincrement value for table '%1' has been reset successfly. - + Empty name - + A blank name for the table is allowed in SQLite, but it is not recommended. Are you sure you want to create a table with blank name? - + Cannot create a table without at least one column. - + Cannot create table %1, if it has no primary key defined. Either uncheck the %2, or define a primary key. - + Cannot use autoincrement for primary key when %1 clause is used. Either uncheck the %2, or the autoincrement in a primary key. - + Are you sure you want to delete table constraint '%1'? table window Ste si istý, že chcete vymazať obmedzenie '%1'? - + Delete constraint table window Vymazať obmedzenie - + Cannot export, because no export plugin is loaded. Nemôžem exportovať, lebo nebol načítaný žiaden plugin na export. - + Cannot import, because no import plugin is loaded. Nemôžem importovať, lebo nebol načítaný žiaden plugin na import. - + Uncommited changes Nepotvrdené zmeny - + There are uncommited structure modifications. You cannot browse or edit data until you have table structure settled. Do you want to commit the structure, or do you want to go back to the structure tab? Sú tu nepotvrdené zmeny štruktúr. Nemôžte prezerať alebo editovať dáta dokiaľ nebude štruktúra tabuľky jasná. Chcete potvrdiť štruktúru alebo sa chcete vrátiť do záložky štruktúr? - + Go back to structure tab Choď späť na záložku štruktúr - + Commit modifications and browse data. Potvrdiť zmeny a prezerať dáta. - + Name table window indexes Názov - + Unique table window indexes Jedinečný - + Columns table window indexes Stĺpce - + Partial index condition table window indexes - + Name table window triggers Názov - + Event table window triggers Udalosť - + Condition table window triggers Podmienka - + Details table window triggers Detaily - + Table window "%1" has uncommited structure modifications and data. V okne tabuľky %1 sú nepotvrdené zmeny štruktúry a dáta. - + Table window "%1" has uncommited data. V okne tabuľky %1 sú nepotvrdené dáta. - + Table window "%1" has uncommited structure modifications. V okne tabuľky %1 sú nepotvrdené zmeny štruktúry. @@ -5889,7 +6229,7 @@ Chcete potvrdiť štruktúru alebo sa chcete vrátiť do záložky štruktúr? Error trigger dialog - + Chyba @@ -5934,203 +6274,274 @@ Chcete potvrdiť štruktúru alebo sa chcete vrátiť do záložky štruktúr?Názov pohľadu: - + + Output column names + + + + + Data Dáta - + Triggers Spúšťače - + DDL DDL - - + + Could not restore window '%1', because no database or view was stored in session for this window. - + Could not restore window '%1', because database %2 could not be resolved. - + Could not restore window '%1', because database %2 could not be open. - + Could not restore window '%1', because the view %2 doesn't exist in the database %3. - - + + New view %1 Nový pohľad %1 - + Refresh the view view window Obnoviť pohľad - + Commit the view changes view window Potvrdiť zmeny v pohľade - + Rollback the view changes view window Vrátiť späť zmeny v pohľade - + + Explicit column names + + + + + Generate output column names automatically basing on result columns of the view. + + + + + Add column + view window + Pridať stĺpec + + + + Edit column + view window + Upraviť stĺpec + + + + Delete column + view window + Vymazať stĺpec + + + + Move column up + view window + Posunúť stĺpec hore + + + + Move column down + view window + Posunúť stĺpec dole + + + Refresh trigger list view window Obnoviť zoznam spúšťačov - + Create new trigger view window Vytvoriť nový spúšťač - + Edit selected trigger view window Upraviť vybraný spúšťač - + Delete selected trigger view window Vymazať vybraný spúšťač - + View window "%1" has uncommited structure modifications and data. Okno pohľadu "%1" obsahuje nepotrdené zmeny štruktúr a dát. - + View window "%1" has uncommited data. Okno pohľadu "%1" obsahuje nepotrdené dáta. - + View window "%1" has uncommited structure modifications. Okno pohľadu "%1" obsahuje nepotrdené zmeny štruktúr. - + Could not load data for view %1. Error details: %2 Nemôžem načítať dáta z pohľadu %1. Detaily chyby: %2 - + Uncommited changes Nepotvrdené zmeny - + There are uncommited structure modifications. You cannot browse or edit data until you have the view structure settled. Do you want to commit the structure, or do you want to go back to the structure tab? Sú tu nepotvrdené zmeny štruktúr. Nemôžte prezerať alebo editovať dáta dokiaľ nebude štruktúra tabuľky jasná. Chcete potvrdiť štruktúru alebo sa chcete vrátiť do záložky štruktúr? - + Go back to structure tab Choď späť na záložku štruktúr - + Commit modifications and browse data. Potvrdiť zmeny a prezerať dáta. - + + Commited changes for view '%1' successfly. + + + + + Commited changes for view '%1' (named before '%2') successfly. + + + + Could not commit view changes. Error message: %1 view window Nemôžem potvrdiť zmeny v pohľade. Chyba: %1 - + + Override columns + + + + + Currently defined columns will be overriden. Do you want to continue? + + + + + Could not determinate columns returned from the view. The query is problably incomplete or contains errors. + + + + Name view window triggers Názov - + Instead of view window triggers - + Condition view window triggers Podmienka - + Details table window triggers Detaily - + Could not process the %1 view correctly. Unable to open a view window. - + Empty name - + A blank name for the view is allowed in SQLite, but it is not recommended. Are you sure you want to create a view with blank name? - + The SELECT statement could not be parsed. Please correct the query and retry. Details: %1 SELECT nemôže byť analyzovaný. Prosím opravte dotaz a skúste to znovu. Detaily: %1 - + The view could not be modified due to internal SQLiteStudio error. Please report this! - + The view code could not be parsed properly for execution. This is a SQLiteStudio's bug. Please report it. - + Following problems will take place while modifying the view. Would you like to proceed? view window - + View modification view window diff --git a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_zh_CN.qm b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_zh_CN.qm index 2cb7445..47beaf2 100644 Binary files a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_zh_CN.qm and b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_zh_CN.qm differ diff --git a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_zh_CN.ts b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_zh_CN.ts index acefaa8..e6a2c1d 100644 --- a/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_zh_CN.ts +++ b/SQLiteStudio3/guiSQLiteStudio/translations/guiSQLiteStudio_zh_CN.ts @@ -1,6 +1,6 @@ - + AboutDialog @@ -590,95 +590,110 @@ 高级模式 - + Add constraint column dialog 添加约束 - + Edit constraint column dialog 编辑约束 - - + + Delete constraint column dialog 删除约束 - + Move constraint up column dialog 上移约束 - + Move constraint down column dialog 下移约束 - + Add a primary key column dialog 添加主键 - + Add a foreign key column dialog 添加外键 - + Add an unique constraint column dialog 添加唯一约束 - + Add a check constraint column dialog 添加条件约束 - + Add a not null constraint column dialog 添加非空约束 - + Add a collate constraint column dialog 添加排序规则约束 - + Add a default constraint column dialog 添加默认约束 - + Are you sure you want to delete constraint '%1'? column dialog 您确定要删除约束“%1”吗? - + Correct the constraint's configuration. 修正约束配置。 - + This constraint is not officially supported by SQLite 2, but it's okay to use it. SQLite2没有官方支持该约束,但是可以使用。 + + + Scale is not allowed for INTEGER PRIMARY KEY columns. + + + + + Precision cannot be defined without the scale. + + + + + Precision is not allowed for INTEGER PRIMARY KEY columns. + + ColumnDialogConstraintsModel @@ -892,557 +907,616 @@ but it's okay to use it. ConfigDialog - + Configuration 配置 - + Search 搜索 - + General 通用 - + Keyboard shortcuts 快捷键 - + Look & feel 外观 - + Style 风格 - + Fonts 字体 - + Colors 颜色 - + Plugins 插件 - + Code formatters 代码格式化 - + Data browsing 浏览数据 - + Data editors 数据编辑器 - + + Database dialog window + + + + + <p>When adding new database it is marked to be "permanent" (stored in configuration) by default. Checking this option makes every new database to NOT be "permanent" by default.</p> + + + + + Do not mark database to be "permanent" by default + + + + + <p>When this option is enabled, then files dropped from file manager onto database list will be automatically added to the list, bypassing standard database dialog. If for various reasons automatic process fails, then standard dialog will be presented to the user.</p> + + + + + Try to bypass dialog completly when dropping database file onto the list + + + + Data browsing and editing 流量和编辑数据 - + Number of data rows per page: 每页的行数: - - + + <p>When the data is read into grid view columns width is automatically adjusted. This value limits the initial width for the adjustment, but user can still resize the column manually over this limit.</p> <p>在以列表方式显示数据时,列宽度会自动调整。该值控制初始列宽度,之后您可以手动调整列宽度,不受此限制。</p> - + Limit initial data column width to (in pixels): 限制宽度(单位:像素): - - Inserting new row in data grid + + <p>When this is enabled and user holds mouse pointer over a cell in any data view (query results, a table data, a view data) a tooltip will appear with details about the cell - it includes details like column data type, constraints, ROWID and others.</p> - - Before currently selected row - 在已选列之前 + + Show column and row details tooltip in data view + - - - - General.InsertRowPlacement + + Inserting new row in data grid - + + Before currently selected row + 在已选列之前 + + + After currently selected row 在已选列之后 - + At the end of data view 在数据显示区域的末尾 - + + <p>When enabled, Table Windows will show up with the data tab, instead of the structure tab.</p> + + + + + <p>When enabled the "Data" tab will be placed as first tab in every Table Window, instead of being at second place.</p> + + + + + Place data tab as first tab in a Table Window + + + + + <p>When enabled, View Windows will show up with the data tab, instead of the structure tab.</p> + + + + + <p>When enabled the "Data" tab will be placed as first tab in every View Window, instead of being at second place.</p> + + + + + Place data tab as first tab in a View Window + + + + Data types 数据类型 - + Available editors: 可用的编辑器: - + Editors selected for this data type: 已选的该数据类型编辑器: - + Schema editing 架构编辑 - + Number of DDL changes kept in history. 数据库定义(DDL)的更改历史记录数量。 - + DDL history size: 数据库定义(DDL)历史大小: - + Don't show DDL preview dialog when commiting schema changes 当提交schema变动时不显示数据库定义(DDL)预览对话框 - + SQL queries SQL查询 - - + + Number of queries kept in the history. 查询历史记录数量。 - + History size: 历史大小: - + <p>If there is more than one query in the SQL editor window, then (if this option is enabled) only a single query will be executed - the one under the keyboard insertion cursor. Otherwise all queries will be executed. You can always limit queries to be executed by selecting those queries before calling to execute.</p> <p>如果SQL编辑器中有多个语句,如果启用该选项,只执行光标下的语句;反之则执行全部语句。另外您可以选择需要执行的语句来执行</p> - + Execute only the query under the cursor 只执行光标下的语句 - + Updates 更新 - + Automatically check for updates at startup 在启动时自己检查更新 - + Session 会话 - + Restore last session (active MDI windows) after startup 启动后恢复上一次会话。 - + + Status Field + + + + + <p>When user manually closes the Status panel, this option makes sure that if any new message is printed in the Status panel it will be reopened. If it's disabled, then Status panel can only be open manually by the user from the "View" menu.</p> + + + + + Always open Status panel when new message is printed + + + + Filter shortcuts by name or key combination - + Action - + Key combination 按键编定 - - + + Language 语言 - + Changing language requires application restart to take effect. 更改语言后,重启程序生效。 - + Compact layout - + <p>Compact layout reduces all margins and spacing on the UI to minimum, making space for displaying more data. It makes the interface a little bit less aesthetic, but allows to display more data at once.</p> - + Use compact layout - - General.CompactLayout - - - - + + Database list 数据库列表 - + If switched off, then columns will be sorted in the order they are typed in CREATE TABLE statement. 如果关闭,将会以 CREATE TABLE 中的顺序对列进行排序。 - + Sort table columns alphabetically 按字母对列排序 - + Expand tables node when connected to a database 当连接到数据库时,展开数据库节点。 - + <p>Additional labels are those displayed next to the names on the databases list (they are blue, unless configured otherwise). Enabling this option will result in labels for databases, invalid databases and aggregated nodes (column group, index group, trigger group). For more labels see options below.<p> - + Display additional labels on the list - + For regular tables labels will show number of columns, indexes and triggers for each of tables. - + Display labels for regular tables - + Virtual tables will be marked with a 'virtual' label. - + Display labels for virtual tables - + Expand views node when connected to a database - + If this option is switched off, then objects will be sorted in order they appear in sqlite_master table (which is in order they were created) - + Sort objects (tables, indexes, triggers and views) alphabetically - + Display system tables and indexes on the list - + Table windows - - When enabled, Table Windows will show up with the data tab, instead of the structure tab. - - - - + Open Table Windows with the data tab for start - + View windows - - When enabled, View Windows will show up with the data tab, instead of the structure tab. - - - - + Open View Windows with the data tab for start - + Main window dock areas - + Left and right areas occupy corners - + Top and bottom areas occupy corners - + Hide built-in plugins - + Current style: 当前风格: - + Preview 预览 - + Enabled 已启用 - + Disabled 已禁用 - + Active formatter plugin 启用格式化插件 - + SQL editor font SQL编辑器字体 - + Database list font 数据库字体 - + Database list additional label font 数据库额外标签字体 - + Data view font 数据浏览字体 - + Status field font 状态栏字体 - + SQL editor colors SQL编辑器颜色 - + Current line background 当前行的背景色 - + <p>SQL strings are enclosed with single quote characters.</p> <p>单引号内的SQL字符串</p> - + String foreground 字符串颜色 - + <p>Bind parameters are placeholders for values yet to be provided by the user. They have one of the forms:</p><ul><li>:param_name</li><li>$param_name</li><li>@param_name</li><li>?</li></ul> - + Bind parameter foreground - + Highlighted parenthesis background - + <p>BLOB values are binary values represented as hexadecimal numbers, like:</p><ul><li>X'12B4'</li><li>x'46A2F4'</li></ul> - + BLOB value foreground BLOB值的颜色 - + Regular foreground 背景色 - + Line numbers area background 行号的背景色 - + Keyword foreground 关键字的颜色 - + Number foreground 数字颜色 - + Comment foreground 注释颜色 - + <p>Valid objects are name of tables, indexes, triggers, or views that exist in the SQLite database.</p> - + Valid objects foreground - + Data view colors - + <p>Any data changes will be outlined with this color, until they're commited to the database.</p> - + Uncommited data outline color - + <p>In case of error while commiting data changes, the problematic cell will be outlined with this color.</p> - + Commit error outline color - + NULL value foreground NULL值的颜色 - + Deleted row background 已删除行的背景色 - + Database list colors 数据库列表颜色 - + <p>Additional labels are those which tell you SQLite version, number of objects deeper in the tree, etc.</p> - + Additional labels foreground - + Status field colors - + Information message foreground 信息颜色 - + Warning message foreground 警告信息颜色 - + Error message foreground 错误信息颜色 @@ -1494,43 +1568,43 @@ but it's okay to use it. 插件详情 - + Plugins are loaded/unloaded immediately when checked/unchecked, but modified list of plugins to load at startup is not saved until you commit the whole configuration dialog. - + %1 (built-in) plugins manager in configuration dialog %1 (内建) - + Details 详情 - + No plugins in this category. 该分类下没有插件。 - + Add new data type 添加新的数据类型 - + Rename selected data type 重命名选择的数据类型 - + Delete selected data type 删除已选数据类型 - + Help for configuring data type editors @@ -1682,137 +1756,137 @@ but it's okay to use it. DataView - + Filter data data view - + Grid view - + Form view - + Refresh table data data view - + First page data view 首页 - + Previous page data view 上一页 - + Next page data view 下一页 - + Last page data view 末页 - + Apply filter data view - + Commit changes for selected cells data view - + Rollback changes for selected cells data view - + Show grid view of results sql editor - + Show form view of results sql editor - + Filter by text data view - + Filter by the Regular Expression data view - + Filter by SQL expression data view - + Tabs on top data view - + Tabs at bottom data view - + Place new rows above selected row data view - + Place new rows below selected row data view - + Place new rows at the end of the data view data view - + Total number of rows is being counted. Browsing other pages will be possible after the row counting is done. - + Row: %1 行:%1 @@ -1912,7 +1986,7 @@ Browsing other pages will be possible after the row counting is done. Would you like to ignore those errors and proceed? - + 忽略错误并继续? @@ -1967,7 +2041,7 @@ Browsing other pages will be possible after the row counting is done. - + File 文件 @@ -1988,47 +2062,47 @@ Browsing other pages will be possible after the row counting is done. - + Browse for existing database file on local computer 浏览计算上已存在的文件 - + Browse 浏览 - + Enter an unique database name. - + This name is already in use. Please enter unique name. - + Enter a database file path. 输入数据库文件位置。 - + This database is already on the list under name: %1 该数据库已在列表中:%1 - + Select a database type. 选择数据库类型。 - + Auto-generated 自动产生 - + Type the name 输入名字 @@ -2077,9 +2151,31 @@ Browsing other pages will be possible after the row counting is done. + Error while dropping %1: %2 + + + Delete objects + 删除对象 + + + + Are you sure you want to delete following objects: +%1 + + + + + Cannot start transaction. Details: %1 + + + + + Cannot commit transaction. Details: %1 + + DbTree @@ -2094,344 +2190,366 @@ Browsing other pages will be possible after the row counting is done. 过滤名 - + Copy 复制 - + Paste 粘贴 - + Select all 全选 - + Create a group 创建分组 - + Delete the group 删除分组 - + Rename the group 重命名分组 - + Add a database 添加数据库 - + Edit the database 编辑数据库 - + Remove the database 移除数据库 - + Connect to the database 连接到数据库 - + Disconnect from the database 断开数据库连接 - + Import 导入 - + Export the database 导数该数据库 - + Convert database type 转换数据库类型 - + Vacuum 清理 - + Integrity check 检查完整性 - + Create a table 新建表 - + Edit the table 编辑该表 - + Delete the table 删除该表 - + Export the table 导出该表 - + Import into the table 导入到该表 - + Populate table 填充表 - + Create similar table 创建一个相似的表 - + Reset autoincrement sequence 重设 autoincrement - + Create an index 创建索引 - + Edit the index 编辑该索引 - + Delete the index 删除该索引 - + Create a trigger 创建触发器 - + Edit the trigger 编辑该触发器 - + Delete the trigger 删除该触发器 - + Create a view 创建视图 - + Edit the view 编辑该视图 - + Delete the view 删除该视图 - + Add a column 添加字段 - + Edit the column 编辑该字段 - + Delete the column 删除该字段 - + Delete selected items 删除已选项目 - + Clear filter 清除过滤器 - + Refresh all database schemas 刷新全部数据库的结构 - + Refresh selected database schema 刷新已选数据库的结构 - - + + Erase table data 擦除该表的数据 - - + + Database 数据库 - + Grouping 分组 - - + + Generate query for table + + + + + Create group 创建分组 - + Group name 分组名 - + Entry with name %1 already exists in group %2. - + Delete group 删除分组 - + Are you sure you want to delete group %1? All objects from this group will be moved to parent group. 确认删除组 %1 吗? 删除后该组下的全部内容将被移动到其所属的父分组中。 - + + Are you sure you want to remove database '%1' from the list? + + + + + Are you sure you want to remove following databases from the list: +%1 + + + + + Remove database + + + + + Vacuum (%1) + + + Delete database - 删除数据库 + 删除数据库 - Are you sure you want to delete database '%1'? - 您确定要删除数据库“%1”吗? + 您确定要删除数据库“%1”吗? - - + + Cannot import, because no import plugin is loaded. 未能导入,因为没有导入插件被加载。 - - + + Cannot export, because no export plugin is loaded. 未能导出,因为没有导出插件被加载。 - Error while executing VACUUM on the database %1: %2 - 在数据库%1上运行 VACUUM 命令时出错:%2 + 在数据库%1上运行 VACUUM 命令时出错:%2 - VACUUM execution finished successfully. - VACUUM 命令执行完成。 + VACUUM 命令执行完成。 - + Integrity check (%1) 完整性检查(%1) - + Reset autoincrement 重置autoincrement - + Are you sure you want to reset autoincrement value for table '%1'? 您确定要重设“%1”的autoincrement吗? - + An error occurred while trying to reset autoincrement value for table '%1': %2 在重设表“%1”的autoincrement时出现错误:%2 - + Autoincrement value for table '%1' has been reset successfly. 表“%1”的auincrement重设成功。 - + Are you sure you want to delete all data from table '%1'? 您确定要删除表“%1”中的全部数据吗? - + An error occurred while trying to delete data from table '%1': %2 删除表“%1”中的数据时出错:%2 - + All data has been deleted for table '%1'. 表“%1”中的数据全部被删除。 - + Following objects will be deleted: %1. 以下内容将被删除:%1。 - + Following databases will be removed from list: %1. 以下数据库将从列表中移除:%1。 - + Remainig objects from deleted group will be moved in place where the group used to be. - + %1<br><br>Are you sure you want to continue? %1<br><br>继续? - + Delete objects 删除对象 @@ -2466,123 +2584,128 @@ All objects from this group will be moved to parent group. DbTreeModel - + Database: %1 dbtree tooltip 数据库:%1 - + Version: dbtree tooltip 版本: - + File size: dbtree tooltip 文件大小: - + Encoding: dbtree tooltip 编码: - + Error: dbtree tooltip 错误: - + Table : %1 dbtree tooltip 表:%1 - + Columns (%1): dbtree tooltip 字段(%1) - + Indexes (%1): dbtree tooltip 索引(%1) - + Triggers (%1): dbtree tooltip 触发器(%1) - + Copy 复制 - + Move 移动 - + Include data 包含数据 - + Include indexes 包含索引 - + Include triggers 包含触发器 - + Abort 中止 - + + Could not add dropped database file '%1' automatically. Manual setup is necessary. + + + + Referenced tables 参照表 - + Do you want to include following referenced tables as well: %1 - + Name conflict 名字冲突 - + Following object already exists in the target database. Please enter new, unique name, or press '%1' to abort the operation: - + SQL statements conversion - + Following error occurred while converting SQL statements to the target SQLite version: - + Would you like to ignore those errors and proceed? 忽略错误并继续? @@ -3333,101 +3456,174 @@ Please enter new, unique name, or press '%1' to abort the operation:索引 - + On table: - + Index name: 索引名: - + Partial index condition - + Unique index 唯一索引 - + Column 字段 - + Collation - + Sort 排序 - + + Delete selected indexed expression + + + + + Moves selected index column up in the order, making it more significant in the index. + + + + + Moves selected index column down in the order, making it less significant in the index. + + + + + Edit selected indexed expression + + + + + Add indexed expression + + + + DDL DDL - + Tried to open index dialog for closed or inexisting database. - + Could not process index %1 correctly. Unable to open an index dialog. - + + Unique index cannot have indexed expressions. Either remove expressions from list below, or uncheck this option. + + + + Pick the table for the index. - + Select at least one column. 至少选择一列 - + Enter a valid condition. - + default index dialog 默认 - + Sort order table constraints 排序 - - + + Error index dialog 错误 - + Cannot create unique index, because values in selected columns are not unique. Would you like to execute SELECT query to see problematic values? - + An error occurred while executing SQL statements: %1 在执行SQL语句时发生了错误:%1 + + IndexExprColumnDialog + + + Indexed expression + + + + + Expression to index + + + + + This expression is already indexed by the index. + + + + + Column should be indexed directly, not by expression. Either extend this expression to contain something more than just column name, or abort and select this column in index dialog directly. + + + + + Column '%1' does not belong to the table covered by this index. Indexed expressions can refer only to columns from the indexed table. + + + + + It's forbidden to use 'SELECT' statements in indexed expressions. + + + + + Enter an indexed expression. + + + + + Invalid expression. + + + LanguageDialog @@ -3469,273 +3665,273 @@ Please enter new, unique name, or press '%1' to abort the operation:查看工具栏 - + Configuration widgets 配置部件 - + Syntax highlighting engines 语法高亮引擎 - + Data editors 数据编辑器 - + Running in debug mode. Press %1 or use 'Help / Open debug console' menu entry to open the debug console. - + Running in debug mode. Debug messages are printed to the standard output. - + You need to restart application to make the language change take effect. 更改语言后重启程序生效。 - + Open SQL editor 打开SQL编辑器 - + Open DDL history 打开数据库定义(DDL)历史 - + Open SQL functions editor 打开SQL函数编辑器 - + Open collations editor - + Import 导入 - + Export 导出 - + Open configuration dialog 打开配置对话框 - + Tile windows 平铺窗口 - + Tile windows horizontally 水平排列窗口 - + Tile windows vertically 垂直排列窗口 - + Cascade windows 层叠窗口 - + Next window 下一个窗口 - + Previous window 上一个窗口 - + Hide status field 隐藏状态栏 - + Close selected window 关闭当前窗口 - + Close all windows but selected 关闭其它窗口 - + Close all windows 关闭全部窗口 - + Restore recently closed window 恢复最近关闭的窗口 - + Rename selected window 重命名当前窗口 - + Open Debug Console 打开调试终端 - + Open CSS Console 打开CSS控制台 - + Report a bug 提交Bug - + Propose a new feature 提交新功能建议 - + About 关于 - + Licenses 许可 - + Open home page 访问主页 - + Open forum page 访问论坛 - + User Manual 用户手册 - + SQLite documentation SQLite文档 - + Report history 报告历史 - + Check for updates 检查更新 - + Database menubar 数据库 - + Structure menubar 结构 - + View menubar 查看 - + Window list menubar view menu 窗口列表 - + Tools menubar 工具 - + Help 帮助 - + Could not set style: %1 main window 未能设置风格:%1 - + Cannot export, because no export plugin is loaded. 未能导出,因为没有导出插件被加载。 - + Cannot import, because no import plugin is loaded. 未能导入,因为没有导入插件被加载。 - + Rename window 重命名窗口 - + Enter new name for the window: 窗口的新名称: - + New updates are available. <a href="%1">Click here for details</a>. 有新更新 <a href="%1">点此查看更新详情</a>. - + You're running the most recent version. No updates are available. 您使用的是最新版,不需要更新。 - + Database passed in command line parameters (%1) was already on the list under name: %2 - + Database passed in command line parameters (%1) has been temporarily added to the list under name: %2 - + Could not add database %1 to list. 未能将数据%1添加到列表 @@ -4135,127 +4331,127 @@ Please enter new, unique name, or press '%1' to abort the operation: - + Data grid view - + Copy cell(s) contents to clipboard - + Paste cell(s) contents from clipboard - + Set empty value to selected cell(s) - + Set NULL value to selected cell(s) - + Commit changes to cell(s) contents - + Rollback changes to cell(s) contents - + Delete selected data row - + Insert new data row - + Open contents of selected cell in a separate editor - + Total pages available: %1 - + Total rows loaded: %1 - + Data view (both grid and form) - + Refresh data - + Switch to grid view of the data - + Switch to form view of the data - + Database list 数据库列表 - + Delete selected item - + Clear filter contents - + Refresh schema - + Refresh all schemas - + Add database - + Select all items - + Copy selected item(s) - + Paste from clipboard @@ -4369,7 +4565,7 @@ Please enter new, unique name, or press '%1' to abort the operation: Open CSS Console - + 打开CSS控制台 @@ -4481,6 +4677,11 @@ Please enter new, unique name, or press '%1' to abort the operation:Copy selected block of text and paste it a line above + + + Toggle comment + + All SQLite databases @@ -4515,7 +4716,7 @@ Please enter new, unique name, or press '%1' to abort the operation: Execute query - + 执行语句 @@ -4553,106 +4754,106 @@ Please enter new, unique name, or press '%1' to abort the operation: - + Table window - + Refresh table structure - + Add new column - + Edit selected column - + Delete selected column - + Export table data 导出表里的数据 - + Import data to the table - + Add new table constraint - + Edit selected table constraint - + Delete selected table constraint - + Refresh table index list - + Add new index - + Edit selected index - + Delete selected index - + Refresh table trigger list - + Add new trigger - + Edit selected trigger - + Delete selected trigger - + Go to next tab - + Go to previous tab @@ -4896,47 +5097,53 @@ find next 替换 - + + Toggle comment + sql editor + + + + Saved SQL contents to file: %1 - + Syntax completion can be used only when a valid database is set for the SQL editor. - + Contents of the SQL editor are huge, so errors detecting and existing objects highlighting are temporarily disabled. - + Save to file 保存到文件 - + Could not open file '%1' for writing: %2 - + SQL scripts (*.sql);;All files (*) SQL文件 (*.sql);;所有文件 (*) - + Open file 打开文件 - + Could not open file '%1' for reading: %2 - + Reached the end of document. Hit the find again to restart the search. 已搜索到文档底部。点击查找从头程序开始搜索。 @@ -4944,36 +5151,36 @@ find next SqlQueryItem - + Column: data view tooltip 字段: - + Data type: data view 数据类型: - + Table: data view tooltip 表: - + Constraints: data view tooltip 约束: - + This cell is not editable, because: %1 - + Cannot load the data for a cell that refers to the already closed database. @@ -4981,83 +5188,88 @@ find next SqlQueryItemDelegate - - + + Cannot edit this cell. Details: %2 - + The row is marked for deletion. + + + Foreign key for column %2 has more than %1 possible values. It's too much to display in drop down list. You need to edit value manually. + + SqlQueryModel - - + + Only one query can be executed simultaneously. - + Uncommited data - + There are uncommited data changes. Do you want to proceed anyway? All uncommited changes will be lost. - + Cannot commit the data for a cell that refers to the already closed database. - + Could not begin transaction on the database. Details: %1 - + An error occurred while commiting the transaction: %1 - + An error occurred while rolling back the transaction: %1 - + Tried to commit a cell which is not editable (yet modified and waiting for commit)! This is a bug. Please report it. - + An error occurred while commiting the data: %1 - - + + Error while executing SQL query on database '%1': %2 - + Error while loading query results: %1 - + Insert multiple rows 插入多行 - + Number of rows to insert: @@ -5065,92 +5277,117 @@ find next SqlQueryView - + + Go to referenced row in... + + + + Copy 复制 - + Copy as... 复制为... - + Paste 粘贴 - + Paste as... 粘贴为... - + Set NULL values 设置为NULL - + Erase values 擦除 - + Edit value in editor - + Commit 提交 - + Rollback 回滚 - + Commit selected cells - + Rollback selected cells - + Define columns to sort by - + Remove custom sorting - + Insert row 插入行 - + Insert multiple rows 插入多行 - + Delete selected row 删除已选行 - + + Generate query for selected cells + + + + No items selected to paste clipboard contents to. - + + Go to referenced row in table '%1' + + + + + table '%1' + + + + + Referenced row (%1) + + + + Edit value 编辑值 @@ -5158,12 +5395,12 @@ find next SqlTableModel - + Error while commiting new row: %1 写入新行时发生了错误:%1 - + Error while deleting row from table %1: %2 删除行时发生了错误 %1:%2 @@ -5339,7 +5576,7 @@ but it's okay to use them anyway. Sort order table constraints - + 排序 @@ -5355,19 +5592,58 @@ but it's okay to use them anyway. TableStructureModel - + Name table structure columns 名称 - + Data type table structure columns + + + Primary +Key + table structure columns + + + + + Foreign +Key + table structure columns + + + + + Unique + table structure columns + 唯一 + + + + Check + table structure columns + 条件 + + + + Not +NULL + table structure columns + + + Collate + table structure columns + 排序规则 + + + Default value table structure columns @@ -5387,6 +5663,7 @@ but it's okay to use them anyway. + Data 数据 @@ -5408,399 +5685,409 @@ but it's okay to use them anyway. DDL - + DDL - + Export table table window - + Import data to table table window - + Populate table table window 填充表 - + Refresh structure table window - + Commit structure changes table window - + Rollback structure changes table window - + Add column table window - + Edit column table window - - + + Delete column table window - + Move column up table window - + Move column down table window - + Create similar table table window - + 创建一个相似的表 - + Reset autoincrement value table window - + Add table constraint table window - + Edit table constraint table window - + Delete table constraint table window - + Move table constraint up table window - + Move table constraint down table window - + Add table primary key table window - + Add table foreign key table window - + Add table unique constraint table window - + Add table check constraint table window - + Refresh index list table window - + Create index table window - + Edit index table window - + Delete index table window 删除索引 - + Refresh trigger list table window - + Create trigger table window - + Edit trigger table window - + Delete trigger table window 删除触发器 - + Are you sure you want to delete column '%1'? table window - + Following problems will take place while modifying the table. Would you like to proceed? table window - + Table modification table window - + Could not load data for table %1. Error details: %2 - + Could not process the %1 table correctly. Unable to open a table window. - + Could not restore window %1, because no database or table was stored in session for this window. - + Could not restore window '%1', because no database or table was stored in session for this window. - + Could not restore window '%1', because database %2 could not be resolved. - + Could not restore window '%1'', because the table %2 doesn't exist in the database %3. - - + + New table %1 - + + Commited changes for table '%1' successfly. + + + + + Commited changes for table '%1' (named before '%2') successfly. + + + + Could not commit table structure. Error message: %1 table window - + Reset autoincrement 重置autoincrement - + Are you sure you want to reset autoincrement value for table '%1'? - + 您确定要重设“%1”的autoincrement吗? - + An error occurred while trying to reset autoincrement value for table '%1': %2 - + 在重设表“%1”的autoincrement时出现错误:%2 - + Autoincrement value for table '%1' has been reset successfly. - + 表“%1”的auincrement重设成功。 - + Empty name - + A blank name for the table is allowed in SQLite, but it is not recommended. Are you sure you want to create a table with blank name? - + Cannot create a table without at least one column. - + Cannot create table %1, if it has no primary key defined. Either uncheck the %2, or define a primary key. - + Cannot use autoincrement for primary key when %1 clause is used. Either uncheck the %2, or the autoincrement in a primary key. - + Are you sure you want to delete table constraint '%1'? table window - + Delete constraint table window 删除约束 - + Cannot export, because no export plugin is loaded. 未能导出,因为没有导出插件被加载。 - + Cannot import, because no import plugin is loaded. 未能导入,因为没有导入插件被加载。 - + Uncommited changes 未提交的更改 - + There are uncommited structure modifications. You cannot browse or edit data until you have table structure settled. Do you want to commit the structure, or do you want to go back to the structure tab? - + Go back to structure tab - + Commit modifications and browse data. - + Name table window indexes 名称 - + Unique table window indexes 唯一 - + Columns table window indexes 字段 - + Partial index condition table window indexes - + Name table window triggers 名称 - + Event table window triggers - + Condition table window triggers - + Details table window triggers 详情 - + Table window "%1" has uncommited structure modifications and data. - + Table window "%1" has uncommited data. - + Table window "%1" has uncommited structure modifications. @@ -5885,7 +6172,7 @@ Do you want to commit the structure, or do you want to go back to the structure DDL - + DDL @@ -5956,201 +6243,272 @@ Do you want to commit the structure, or do you want to go back to the structure - + + Output column names + + + + + Data 数据 - + Triggers 触发器 - + DDL - + DDL - - + + Could not restore window '%1', because no database or view was stored in session for this window. - + Could not restore window '%1', because database %2 could not be resolved. - + Could not restore window '%1', because database %2 could not be open. - + Could not restore window '%1', because the view %2 doesn't exist in the database %3. - - + + New view %1 - + Refresh the view view window - + Commit the view changes view window - + Rollback the view changes view window - + + Explicit column names + + + + + Generate output column names automatically basing on result columns of the view. + + + + + Add column + view window + + + + + Edit column + view window + + + + + Delete column + view window + + + + + Move column up + view window + + + + + Move column down + view window + + + + Refresh trigger list view window - + Create new trigger view window - + Edit selected trigger view window - + Delete selected trigger view window - + View window "%1" has uncommited structure modifications and data. - + View window "%1" has uncommited data. - + View window "%1" has uncommited structure modifications. - + Could not load data for view %1. Error details: %2 - + Uncommited changes 未提交的更改 - + There are uncommited structure modifications. You cannot browse or edit data until you have the view structure settled. Do you want to commit the structure, or do you want to go back to the structure tab? - + Go back to structure tab - + Commit modifications and browse data. - + + Commited changes for view '%1' successfly. + + + + + Commited changes for view '%1' (named before '%2') successfly. + + + + Could not commit view changes. Error message: %1 view window - + + Override columns + + + + + Currently defined columns will be overriden. Do you want to continue? + + + + + Could not determinate columns returned from the view. The query is problably incomplete or contains errors. + + + + Name view window triggers 名称 - + Instead of view window triggers - + Condition view window triggers - + Details table window triggers 详情 - + Could not process the %1 view correctly. Unable to open a view window. - + Empty name - + A blank name for the view is allowed in SQLite, but it is not recommended. Are you sure you want to create a view with blank name? - + The SELECT statement could not be parsed. Please correct the query and retry. Details: %1 - + The view could not be modified due to internal SQLiteStudio error. Please report this! - + The view code could not be parsed properly for execution. This is a SQLiteStudio's bug. Please report it. - + Following problems will take place while modifying the view. Would you like to proceed? view window - + View modification view window diff --git a/SQLiteStudio3/guiSQLiteStudio/uiconfig.h b/SQLiteStudio3/guiSQLiteStudio/uiconfig.h index 25a8e27..75ea87d 100644 --- a/SQLiteStudio3/guiSQLiteStudio/uiconfig.h +++ b/SQLiteStudio3/guiSQLiteStudio/uiconfig.h @@ -63,35 +63,44 @@ CFG_CATEGORIES(Ui, CFG_ENTRY(QColor, JavaScriptMarker, "#ffff00") ) + CFG_CATEGORY(DbList, + ) + CFG_CATEGORY(General, - CFG_ENTRY(QString, DataViewTabs, QString()) - CFG_ENTRY(QString, SqlEditorTabs, QString()) - CFG_ENTRY(QString, SqlEditorDbListOrder, "LikeDbTree") - CFG_ENTRY(bool, ExpandTables, true) - CFG_ENTRY(bool, ExpandViews, true) - CFG_ENTRY(bool, SortObjects, true) - CFG_ENTRY(bool, SortColumns, false) - CFG_ENTRY(bool, ExecuteCurrentQueryOnly, true) - CFG_ENTRY(bool, ShowSystemObjects, false) - CFG_ENTRY(bool, ShowDbTreeLabels, true) // any labels at all - CFG_ENTRY(bool, ShowRegularTableLabels, false) - CFG_ENTRY(bool, ShowVirtualTableLabels, true) - CFG_ENTRY(int, NumberOfRowsPerPage, 1000) - CFG_ENTRY(QString, Style, &Cfg::getStyleDefaultValue) - CFG_ENTRY(Cfg::Session, Session, Cfg::Session()) - CFG_ENTRY(bool, RestoreSession, true) - CFG_ENTRY(bool, DontShowDdlPreview, false) - CFG_ENTRY(bool, OpenTablesOnData, false) - CFG_ENTRY(bool, OpenViewsOnData, false) - CFG_ENTRY(Cfg::DataEditorsOrder, DataEditorsOrder, Cfg::DataEditorsOrder()) - CFG_ENTRY(QString, FileDialogLastPath, QString()) - CFG_ENTRY(int, MaxInitialColumnWith, 600) - CFG_ENTRY(bool, LanguageAsked, false) - CFG_ENTRY(bool, OpenMaximized, true) - CFG_ENTRY(QString, DockLayout, "vertical") - CFG_ENTRY(QString, CustomCss, QString()) - CFG_ENTRY(bool, CompactLayout, true) - CFG_ENTRY(int, InsertRowPlacement, Cfg::BEFORE_CURRENT) + CFG_ENTRY(QString, DataViewTabs, QString()) + CFG_ENTRY(QString, SqlEditorTabs, QString()) + CFG_ENTRY(QString, SqlEditorDbListOrder, "LikeDbTree") + CFG_ENTRY(bool, ExpandTables, true) + CFG_ENTRY(bool, ExpandViews, true) + CFG_ENTRY(bool, SortObjects, true) + CFG_ENTRY(bool, SortColumns, false) + CFG_ENTRY(bool, ExecuteCurrentQueryOnly, true) + CFG_ENTRY(bool, ShowSystemObjects, false) + CFG_ENTRY(bool, ShowDbTreeLabels, true) // any labels at all + CFG_ENTRY(bool, ShowRegularTableLabels, false) + CFG_ENTRY(bool, ShowVirtualTableLabels, true) + CFG_ENTRY(int, NumberOfRowsPerPage, 1000) + CFG_ENTRY(QString, Style, &Cfg::getStyleDefaultValue) + CFG_ENTRY(Cfg::Session, Session, Cfg::Session()) + CFG_ENTRY(bool, RestoreSession, true) + CFG_ENTRY(bool, DontShowDdlPreview, false) + CFG_ENTRY(bool, OpenTablesOnData, false) + CFG_ENTRY(bool, DataTabAsFirstInTables, false) + CFG_ENTRY(bool, OpenViewsOnData, false) + CFG_ENTRY(bool, DataTabAsFirstInViews, false) + CFG_ENTRY(bool, AutoOpenStatusField, true) + CFG_ENTRY(bool, NewDbNotPermanentByDefault, false) + CFG_ENTRY(bool, BypassDbDialogWhenDropped, false) + CFG_ENTRY(Cfg::DataEditorsOrder, DataEditorsOrder, Cfg::DataEditorsOrder()) + CFG_ENTRY(QString, FileDialogLastPath, QString()) + CFG_ENTRY(int, MaxInitialColumnWith, 600) + CFG_ENTRY(bool, LanguageAsked, false) + CFG_ENTRY(bool, OpenMaximized, true) + CFG_ENTRY(QString, DockLayout, "vertical") + CFG_ENTRY(QString, CustomCss, QString()) + CFG_ENTRY(bool, CompactLayout, true) + CFG_ENTRY(int, InsertRowPlacement, Cfg::BEFORE_CURRENT) + CFG_ENTRY(bool, ShowDataViewTooltips, true) ) ) diff --git a/SQLiteStudio3/guiSQLiteStudio/windows/tablestructuremodel.cpp b/SQLiteStudio3/guiSQLiteStudio/windows/tablestructuremodel.cpp index 80c4567..1c817de 100644 --- a/SQLiteStudio3/guiSQLiteStudio/windows/tablestructuremodel.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/windows/tablestructuremodel.cpp @@ -128,14 +128,16 @@ QVariant TableStructureModel::data(const QModelIndex& index, int role) const QVariant TableStructureModel::headerData(int section, Qt::Orientation orientation, int role) const { - if (role != Qt::DisplayRole) - return QAbstractTableModel::headerData(section, orientation, role); + if (role == Qt::DisplayRole) + { + if (orientation == Qt::Vertical) + return section + 1; - if (orientation == Qt::Vertical) - return section + 1; + // Now it's horizontal orientation with DisplayRole + return columnLabel(section); + } - // Now it's horizontal orientation with DisplayRole - return columnLabel(section); + return QAbstractTableModel::headerData(section, orientation, role); } TableStructureModel::Columns TableStructureModel::getHeaderColumn(int colIdx) const @@ -300,17 +302,17 @@ QString TableStructureModel::columnLabel(int column) const case Columns::TYPE: return tr("Data type", "table structure columns"); case Columns::PK: - return "P"; + return tr("Primary\nKey", "table structure columns"); case Columns::FK: - return "F"; + return tr("Foreign\nKey", "table structure columns"); case Columns::UNIQUE: - return "U"; + return tr("Unique", "table structure columns"); case Columns::CHECK: - return "H"; + return tr("Check", "table structure columns"); case Columns::NOTNULL: - return "N"; + return tr("Not\nNULL", "table structure columns"); case Columns::COLLATE: - return "C"; + return tr("Collate", "table structure columns"); case Columns::DEFAULT: return tr("Default value", "table structure columns"); } diff --git a/SQLiteStudio3/guiSQLiteStudio/windows/tablewindow.cpp b/SQLiteStudio3/guiSQLiteStudio/windows/tablewindow.cpp index cd1ba72..fd344e8 100644 --- a/SQLiteStudio3/guiSQLiteStudio/windows/tablewindow.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/windows/tablewindow.cpp @@ -33,9 +33,11 @@ #include "services/importmanager.h" #include "dbobjectdialogs.h" #include "dialogs/exportdialog.h" +#include "common/centerediconitemdelegate.h" #include "themetuner.h" #include "dialogs/importdialog.h" #include "dialogs/populatedialog.h" +#include "datagrid/sqlqueryitem.h" #include #include #include @@ -46,7 +48,6 @@ #include #include #include -#include // TODO extend QTableView for columns and constraints, so they show full-row-width drop indicator, // instead of single column drop indicator. @@ -142,6 +143,9 @@ void TableWindow::init() { ui->setupUi(this); ui->structureSplitter->setStretchFactor(0, 2); + ui->structureView->horizontalHeader()->setSectionsClickable(false); + ui->structureView->verticalHeader()->setSectionsClickable(false); + constraintColumnsDelegate = new CenteredIconItemDelegate(this); #ifdef Q_OS_MACX QStyle *fusion = QStyleFactory::create("Fusion"); @@ -159,6 +163,7 @@ void TableWindow::init() ui->dataView->init(dataModel); initActions(); + updateTabsOrder(); connect(dataModel, SIGNAL(executionSuccessful()), this, SLOT(executionSuccessful())); connect(dataModel, SIGNAL(executionFailed(QString)), this, SLOT(executionFailed(QString))); @@ -168,6 +173,9 @@ void TableWindow::init() connect(ui->tableNameEdit, SIGNAL(textChanged(QString)), this, SLOT(nameChanged())); connect(ui->indexList, SIGNAL(itemSelectionChanged()), this, SLOT(updateIndexesState())); connect(ui->triggerList, SIGNAL(itemSelectionChanged()), this, SLOT(updateTriggersState())); + connect(CFG_UI.General.DataTabAsFirstInTables, SIGNAL(changed(const QVariant&)), this, SLOT(updateTabsOrder())); + connect(ui->structureView, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(structureViewDoubleClicked(const QModelIndex&))); + connect(ui->tableConstraintsView, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(constraintsViewDoubleClicked(const QModelIndex&))); structureExecutor = new ChainExecutor(this); connect(structureExecutor, SIGNAL(success()), this, SLOT(changesSuccessfullyCommited())); @@ -253,9 +261,9 @@ void TableWindow::createIndexActions() createAction(REFRESH_INDEXES, ICONS.RELOAD, tr("Refresh index list", "table window"), this, SLOT(updateIndexes()), ui->indexToolBar, ui->indexList); ui->indexToolBar->addSeparator(); createAction(ADD_INDEX, ICONS.INDEX_ADD, tr("Create index", "table window"), this, SLOT(addIndex()), ui->indexToolBar, ui->indexList); - createAction(EDIT_INDEX, ICONS.INDEX_EDIT, tr("Edit index", "table window"), this, SLOT(editIndex()), ui->indexToolBar, ui->indexList); + createAction(EDIT_INDEX, ICONS.INDEX_EDIT, tr("Edit index", "table window"), this, SLOT(editCurrentIndex()), ui->indexToolBar, ui->indexList); createAction(DEL_INDEX, ICONS.INDEX_DEL, tr("Delete index", "table window"), this, SLOT(delIndex()), ui->indexToolBar, ui->indexList); - connect(ui->indexList, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(editIndex())); + connect(ui->indexList, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(indexViewDoubleClicked(QModelIndex))); } void TableWindow::createTriggerActions() @@ -265,14 +273,14 @@ void TableWindow::createTriggerActions() createAction(ADD_TRIGGER, ICONS.TRIGGER_ADD, tr("Create trigger", "table window"), this, SLOT(addTrigger()), ui->triggerToolBar, ui->triggerList); createAction(EDIT_TRIGGER, ICONS.TRIGGER_EDIT, tr("Edit trigger", "table window"), this, SLOT(editTrigger()), ui->triggerToolBar, ui->triggerList); createAction(DEL_TRIGGER, ICONS.TRIGGER_DEL, tr("Delete trigger", "table window"), this, SLOT(delTrigger()), ui->triggerToolBar, ui->triggerList); - connect(ui->triggerList, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(editTrigger())); + connect(ui->triggerList, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(triggerViewDoubleClicked(QModelIndex))); } void TableWindow::editColumn(const QModelIndex& idx) { if (!idx.isValid()) { - qWarning() << "Called TableWindow::editColumn() with invalid index."; + addColumn(); return; } @@ -352,6 +360,8 @@ void TableWindow::executeStructureChanges() modifyingThisTable = true; structureExecutor->setDb(db); structureExecutor->setQueries(sqls); + structureExecutor->setDisableForeignKeys(true); + structureExecutor->setDisableObjectDropsDetection(true); widgetCover->show(); structureExecutor->exec(); } @@ -458,23 +468,27 @@ void TableWindow::setupDefShortcuts() void TableWindow::executionSuccessful() { - modifyingThisTable = false; dataLoaded = true; } void TableWindow::executionFailed(const QString& errorText) { - modifyingThisTable = false; notifyError(tr("Could not load data for table %1. Error details: %2").arg(table).arg(errorText)); } void TableWindow::initDbAndTable() { + int totalConstrCols = 6; if (db->getVersion() == 2) { ui->withoutRowIdCheck->setVisible(false); + totalConstrCols -= 2; } + totalConstrCols += 2; // we start at 3rd column + for (int colIdx = 2; colIdx < totalConstrCols; colIdx++) + ui->structureView->setItemDelegateForColumn(colIdx, constraintColumnsDelegate); + if (existingTable) { dataModel->setDb(db); @@ -785,6 +799,8 @@ void TableWindow::commitStructure(bool skipWarning) void TableWindow::changesSuccessfullyCommited() { + modifyingThisTable = false; + QStringList sqls = structureExecutor->getQueries(); CFG->addDdlHistory(sqls.join("\n"), db->getName(), db->getPath()); @@ -804,6 +820,11 @@ void TableWindow::changesSuccessfullyCommited() updateNewTableState(); updateWindowTitle(); + if (oldTable.compare(table, Qt::CaseInsensitive) == 0 || oldTable.isEmpty()) + notifyInfo(tr("Commited changes for table '%1' successfly.").arg(table)); + else + notifyInfo(tr("Commited changes for table '%1' (named before '%2') successfly.").arg(table, oldTable)); + DBTREE->refreshSchema(db); if (tableModifier) @@ -832,6 +853,7 @@ void TableWindow::changesFailedToCommit(int errorCode, const QString& errorText) { qDebug() << "TableWindow::changesFailedToCommit:" << errorCode << errorText; + modifyingThisTable = false; widgetCover->hide(); notifyError(tr("Could not commit table structure. Error message: %1", "table window").arg(errorText)); } @@ -1011,8 +1033,8 @@ TokenList TableWindow::indexColumnTokens(SqliteCreateIndexPtr index) if (index->indexedColumns.size() == 0) return TokenList(); - SqliteIndexedColumn* firstCol = index->indexedColumns.first(); - SqliteIndexedColumn* lastCol = index->indexedColumns.last(); + SqliteOrderBy* firstCol = index->indexedColumns.first(); + SqliteOrderBy* lastCol = index->indexedColumns.last(); if (firstCol->tokens.size() == 0) return TokenList(); @@ -1048,9 +1070,9 @@ QString TableWindow::getCurrentTrigger() const void TableWindow::applyInitialTab() { if (existingTable && !table.isNull() && CFG_UI.General.OpenTablesOnData.get()) - ui->tabWidget->setCurrentIndex(1); + ui->tabWidget->setCurrentIndex(getDataTabIdx()); else - ui->tabWidget->setCurrentIndex(0); + ui->tabWidget->setCurrentIndex(getStructureTabIdx()); } void TableWindow::resizeStructureViewColumns() @@ -1060,6 +1082,16 @@ void TableWindow::resizeStructureViewColumns() ui->structureView->resizeColumnToContents(c); } +int TableWindow::getDataTabIdx() const +{ + return ui->tabWidget->indexOf(ui->dataTab); +} + +int TableWindow::getStructureTabIdx() const +{ + return ui->tabWidget->indexOf(ui->structureTab); +} + void TableWindow::updateDdlTab() { createTable->rebuildTokens(); @@ -1103,7 +1135,10 @@ void TableWindow::delConstraint() void TableWindow::editConstraint(const QModelIndex& idx) { if (!idx.isValid()) + { + addConstraint(); return; + } SqliteCreateTable::Constraint* constr = structureConstraintsModel->getConstraint(idx.row()); ConstraintDialog dialog(ConstraintDialog::EDIT, constr, createTable.data(), db, this); @@ -1217,39 +1252,37 @@ void TableWindow::createSimilarTable() void TableWindow::tabChanged(int newTab) { - switch (newTab) + if (tabsMoving) + return; + + if (newTab == getDataTabIdx()) { - case 1: + if (isModified()) { - if (isModified()) - { - int res = QMessageBox::question(this, tr("Uncommited changes"), - tr("There are uncommited structure modifications. You cannot browse or edit data until you have " - "table structure settled.\n" - "Do you want to commit the structure, or do you want to go back to the structure tab?"), - tr("Go back to structure tab"), tr("Commit modifications and browse data.")); - - ui->tabWidget->setCurrentIndex(0); - if (res == 1) - commitStructure(true); - - break; - } + int res = QMessageBox::question(this, tr("Uncommited changes"), + tr("There are uncommited structure modifications. You cannot browse or edit data until you have " + "table structure settled.\n" + "Do you want to commit the structure, or do you want to go back to the structure tab?"), + tr("Go back to structure tab"), tr("Commit modifications and browse data.")); - if (!dataLoaded) - ui->dataView->refreshData(); + ui->tabWidget->setCurrentIndex(0); + if (res == 1) + commitStructure(true); - break; + return; } + + if (!dataLoaded) + ui->dataView->refreshData(); } } -void TableWindow::on_structureView_doubleClicked(const QModelIndex &index) +void TableWindow::structureViewDoubleClicked(const QModelIndex &index) { editColumn(index); } -void TableWindow::on_tableConstraintsView_doubleClicked(const QModelIndex &index) +void TableWindow::constraintsViewDoubleClicked(const QModelIndex &index) { editConstraint(index); } @@ -1280,7 +1313,7 @@ void TableWindow::addIndex() updateIndexes(); } -void TableWindow::editIndex() +void TableWindow::editCurrentIndex() { QString index = getCurrentIndex(); if (index.isNull()) @@ -1291,6 +1324,22 @@ void TableWindow::editIndex() updateIndexes(); } +void TableWindow::indexViewDoubleClicked(const QModelIndex& idx) +{ + if (!idx.isValid()) + { + addIndex(); + return; + } + + QString index = ui->indexList->item(idx.row(), 0)->text(); + + DbObjectDialogs dialogs(db, this); + dialogs.editIndex(index); + updateIndexes(); +} + + void TableWindow::delIndex() { QString index = getCurrentIndex(); @@ -1313,7 +1362,25 @@ void TableWindow::editTrigger() { QString trigger = getCurrentTrigger(); if (trigger.isNull()) + { + addTrigger(); + return; + } + + DbObjectDialogs dialogs(db, this); + dialogs.editTrigger(trigger); + updateTriggers(); +} + +void TableWindow::triggerViewDoubleClicked(const QModelIndex& idx) +{ + if (!idx.isValid()) + { + addTrigger(); return; + } + + QString trigger = ui->triggerList->item(idx.row(), 0)->text(); DbObjectDialogs dialogs(db, this); dialogs.editTrigger(trigger); @@ -1488,6 +1555,18 @@ void TableWindow::delColumn(const QString& columnName) delColumn(colIdx); } +void TableWindow::updateTabsOrder() +{ + tabsMoving = true; + ui->tabWidget->removeTab(getDataTabIdx()); + int idx = 1; + if (CFG_UI.General.DataTabAsFirstInTables.get()) + idx = 0; + + ui->tabWidget->insertTab(idx, ui->dataTab, tr("Data")); + tabsMoving = false; +} + bool TableWindow::restoreSessionNextTime() { return existingTable && db && !DBLIST->isTemporary(db); diff --git a/SQLiteStudio3/guiSQLiteStudio/windows/tablewindow.h b/SQLiteStudio3/guiSQLiteStudio/windows/tablewindow.h index 69f210b..d8738f1 100644 --- a/SQLiteStudio3/guiSQLiteStudio/windows/tablewindow.h +++ b/SQLiteStudio3/guiSQLiteStudio/windows/tablewindow.h @@ -21,6 +21,7 @@ class TableConstraintsModel; class QProgressBar; class WidgetCover; class SqliteSyntaxHighlighter; +class CenteredIconItemDelegate; class ConstraintTabModel; namespace Ui { @@ -159,6 +160,8 @@ class GUI_API_EXPORT TableWindow : public MdiChild QString getCurrentTrigger() const; void applyInitialTab(); void resizeStructureViewColumns(); + int getDataTabIdx() const; + int getStructureTabIdx() const; int newTableWindowNum = 1; @@ -178,6 +181,8 @@ class GUI_API_EXPORT TableWindow : public MdiChild ChainExecutor* structureExecutor = nullptr; TableModifier* tableModifier = nullptr; bool modifyingThisTable = false; + CenteredIconItemDelegate* constraintColumnsDelegate = nullptr; + bool tabsMoving = false; private slots: void executionSuccessful(); @@ -215,12 +220,14 @@ class GUI_API_EXPORT TableWindow : public MdiChild void updateTableConstraintsToolbarState(); void updateDdlTab(); void updateNewTableState(); - void on_structureView_doubleClicked(const QModelIndex &index); - void on_tableConstraintsView_doubleClicked(const QModelIndex &index); + void structureViewDoubleClicked(const QModelIndex &index); + void constraintsViewDoubleClicked(const QModelIndex &index); void nameChanged(); void withOutRowIdChanged(); void addIndex(); - void editIndex(); + void editCurrentIndex(); + void indexViewDoubleClicked(const QModelIndex& idx); + void triggerViewDoubleClicked(const QModelIndex& idx); void delIndex(); void addTrigger(); void editTrigger(); @@ -229,6 +236,7 @@ class GUI_API_EXPORT TableWindow : public MdiChild void updateTriggersState(); void nextTab(); void prevTab(); + void updateTabsOrder(); public slots: void updateIndexes(); diff --git a/SQLiteStudio3/guiSQLiteStudio/windows/tablewindow.ui b/SQLiteStudio3/guiSQLiteStudio/windows/tablewindow.ui index 0dd7fe6..14e278a 100644 --- a/SQLiteStudio3/guiSQLiteStudio/windows/tablewindow.ui +++ b/SQLiteStudio3/guiSQLiteStudio/windows/tablewindow.ui @@ -105,7 +105,7 @@ false - + true @@ -152,7 +152,7 @@ - + true @@ -225,7 +225,7 @@ - + QAbstractItemView::NoEditTriggers @@ -254,7 +254,7 @@ - + QAbstractItemView::NoEditTriggers @@ -307,6 +307,16 @@
dataview.h
1 + + ExtTableView + QTableView +
common/exttableview.h
+
+ + ExtTableWidget + QTableWidget +
common/exttablewidget.h
+
diff --git a/SQLiteStudio3/guiSQLiteStudio/windows/viewwindow.cpp b/SQLiteStudio3/guiSQLiteStudio/windows/viewwindow.cpp index cb3a11e..07c927c 100644 --- a/SQLiteStudio3/guiSQLiteStudio/windows/viewwindow.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/windows/viewwindow.cpp @@ -21,10 +21,12 @@ #include "services/config.h" #include "services/codeformatter.h" #include "themetuner.h" +#include "datagrid/sqlviewmodel.h" #include #include #include #include +#include CFG_KEYS_DEFINE(ViewWindow) @@ -44,6 +46,7 @@ ViewWindow::ViewWindow(Db* db, QWidget* parent) : newView(); init(); applyInitialTab(); + updateDbRelatedUiElements(); } ViewWindow::ViewWindow(const ViewWindow& win) : @@ -56,6 +59,7 @@ ViewWindow::ViewWindow(const ViewWindow& win) : init(); initView(); applyInitialTab(); + updateDbRelatedUiElements(); } ViewWindow::ViewWindow(QWidget* parent, Db* db, const QString& database, const QString& view) : @@ -68,6 +72,7 @@ ViewWindow::ViewWindow(QWidget* parent, Db* db, const QString& database, const Q init(); initView(); applyInitialTab(); + updateDbRelatedUiElements(); } ViewWindow::~ViewWindow() @@ -134,6 +139,7 @@ bool ViewWindow::restoreSession(const QVariant& sessionValue) initView(); applyInitialTab(); + updateDbRelatedUiElements(); return true; } @@ -209,10 +215,10 @@ void ViewWindow::init() ui->queryTab, ui->dataTab, ui->triggersTab, - ui->ddl + ui->ddlTab }); - dataModel = new SqlQueryModel(this); + dataModel = new SqlViewModel(this); ui->dataView->init(dataModel); ui->queryEdit->setVirtualSqlExpression("CREATE VIEW name AS %1"); @@ -225,6 +231,12 @@ void ViewWindow::init() connect(ui->queryEdit, SIGNAL(textChanged()), this, SLOT(updateQueryToolbarStatus())); connect(ui->queryEdit, SIGNAL(errorsChecked(bool)), this, SLOT(updateQueryToolbarStatus())); connect(ui->triggersList, SIGNAL(itemSelectionChanged()), this, SLOT(updateTriggersState())); + connect(ui->triggersList, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(triggerViewDoubleClicked(QModelIndex))); + connect(ui->outputColumnsTable, SIGNAL(currentRowChanged(int)), this, SLOT(updateColumnButtons())); + connect(ui->outputColumnsTable->model(), SIGNAL(rowsMoved(const QModelIndex&, int, int, const QModelIndex&, int)), this, SLOT(updateColumnButtons())); + connect(ui->outputColumnsTable->model(), SIGNAL(rowsMoved(const QModelIndex&, int, int, const QModelIndex&, int)), this, SLOT(updateQueryToolbarStatus())); + connect(ui->outputColumnsTable, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(updateQueryToolbarStatus())); + connect(CFG_UI.General.DataTabAsFirstInViews, SIGNAL(changed(const QVariant&)), this, SLOT(updateTabsOrder())); structureExecutor = new ChainExecutor(this); connect(structureExecutor, SIGNAL(success()), this, SLOT(changesSuccessfullyCommited())); @@ -234,9 +246,17 @@ void ViewWindow::init() initActions(); + ui->splitter->setStretchFactor(0, 1); + ui->splitter->setStretchFactor(1, 3); + + updateOutputColumnsVisibility(); + + updateTabsOrder(); + refreshTriggers(); updateQueryToolbarStatus(); updateTriggersState(); + updateColumnButtons(); } void ViewWindow::newView() @@ -258,10 +278,18 @@ void ViewWindow::initView() { dataModel->setDb(db); dataModel->setQuery(originalCreateView->select->detokenize()); + dataModel->setView(view); } ui->queryEdit->setDb(db); ui->queryEdit->setPlainText(createView->select->detokenize()); + + if (createView->columns.size() > 0) + { + columnsFromViewToList(); + outputColumnsCheck->setChecked(true); + } + updateDdlTab(); ui->ddlEdit->setSqliteVersion(db->getVersion()); @@ -286,6 +314,19 @@ void ViewWindow::createQueryTabActions() createAction(ROLLBACK_QUERY, ICONS.ROLLBACK, tr("Rollback the view changes", "view window"), this, SLOT(rollbackView()), ui->queryToolbar); ui->queryToolbar->addSeparator(); ui->queryToolbar->addAction(ui->queryEdit->getAction(SqlEditor::FORMAT_SQL)); + + outputColumnsCheck = new QAction(ICONS.COLUMNS, tr("Explicit column names"), this); + outputColumnsCheck->setCheckable(true); + connect(outputColumnsCheck, SIGNAL(toggled(bool)), this, SLOT(updateOutputColumnsVisibility())); + + outputColumnsSeparator = ui->queryToolbar->addSeparator(); + ui->queryToolbar->addAction(outputColumnsCheck); + createAction(GENERATE_OUTPUT_COLUMNS, ICONS.GENERATE_COLUMNS, tr("Generate output column names automatically basing on result columns of the view."), this, SLOT(generateOutputColumns()), ui->queryToolbar); + createAction(ADD_COLUMN, ICONS.TABLE_COLUMN_ADD, tr("Add column", "view window"), this, SLOT(addColumn()), ui->queryToolbar); + createAction(EDIT_COLUMN, ICONS.TABLE_COLUMN_EDIT, tr("Edit column", "view window"), this, SLOT(editColumn()), ui->queryToolbar); + createAction(DEL_COLUMN, ICONS.TABLE_COLUMN_DELETE, tr("Delete column", "view window"), this, SLOT(delColumn()), ui->queryToolbar); + createAction(MOVE_COLUMN_UP, ICONS.MOVE_UP, tr("Move column up", "view window"), this, SLOT(moveColumnUp()), ui->queryToolbar); + createAction(MOVE_COLUMN_DOWN, ICONS.MOVE_DOWN, tr("Move column down", "view window"), this, SLOT(moveColumnDown()), ui->queryToolbar); } void ViewWindow::createTriggersTabActions() @@ -394,6 +435,7 @@ void ViewWindow::rollbackView() ui->nameEdit->setText(createView->view); ui->queryEdit->setPlainText(createView->select->detokenize()); + columnsFromViewToList(); updateQueryToolbarStatus(); updateDdlTab(); } @@ -411,15 +453,70 @@ QString ViewWindow::getCurrentTrigger() const void ViewWindow::applyInitialTab() { if (existingView && !view.isNull() && CFG_UI.General.OpenViewsOnData.get()) - ui->tabWidget->setCurrentIndex(1); + ui->tabWidget->setCurrentIndex(getDataTabIdx()); else - ui->tabWidget->setCurrentIndex(0); + ui->tabWidget->setCurrentIndex(getQueryTabIdx()); } QString ViewWindow::getCurrentDdl() const { - static_qstring(ddlTpl, "CREATE VIEW %1 AS %2"); - return ddlTpl.arg(wrapObjIfNeeded(ui->nameEdit->text(), db->getDialect())).arg(ui->queryEdit->toPlainText()); + static_qstring(ddlTpl, "CREATE VIEW %1%2 AS %3"); + QString columnsStr = ""; + if (outputColumnsCheck->isChecked() && ui->outputColumnsTable->count() > 0) + columnsStr = "(" + collectColumnNames().join(", ") + ")"; + + return ddlTpl.arg( + wrapObjIfNeeded(ui->nameEdit->text(), db->getDialect()), + columnsStr, + ui->queryEdit->toPlainText() + ); +} + +QStringList ViewWindow::indexedColumnsToNamesOnly(const QList& columns) const +{ + QStringList names; + for (SqliteIndexedColumn* col : columns) + names << col->name; + + return names; +} + +QStringList ViewWindow::collectColumnNames() const +{ + Dialect dialect = db ? db->getDialect() : Dialect::Sqlite3; + QStringList cols; + for (int row = 0; row < ui->outputColumnsTable->count(); row++) + cols << wrapObjIfNeeded(ui->outputColumnsTable->item(row)->text(), dialect); + + return cols; +} + +void ViewWindow::columnsFromViewToList() +{ + ui->outputColumnsTable->clear(); + ui->outputColumnsTable->addItems(indexedColumnsToNamesOnly(createView->columns)); + + QListWidgetItem* item = nullptr; + for (int row = 0; row < ui->outputColumnsTable->count(); row++) + { + item = ui->outputColumnsTable->item(row); + item->setFlags(item->flags() | Qt::ItemIsEditable); + } +} + +int ViewWindow::getDataTabIdx() const +{ + return ui->tabWidget->indexOf(ui->dataTab); +} + +int ViewWindow::getQueryTabIdx() const +{ + return ui->tabWidget->indexOf(ui->queryTab); +} + +int ViewWindow::getDdlTabIdx() const +{ + return ui->tabWidget->indexOf(ui->ddlTab); } void ViewWindow::addTrigger() @@ -465,10 +562,11 @@ void ViewWindow::executionFailed(const QString& errorMessage) void ViewWindow::tabChanged(int tabIdx) { - switch (tabIdx) + if (tabsMoving) + return; + + if (tabIdx == getDataTabIdx()) { - case 1: - { if (isModified()) { int res = QMessageBox::question(this, tr("Uncommited changes"), @@ -481,19 +579,19 @@ void ViewWindow::tabChanged(int tabIdx) if (res == 1) commitView(true); - break; + return; } if (!dataLoaded) ui->dataView->refreshData(); - break; - } - case 3: - { - updateDdlTab(); - break; - } + return; + } + + if (tabIdx == getDdlTabIdx()) + { + updateDdlTab(); + return; } } @@ -518,12 +616,18 @@ void ViewWindow::changesSuccessfullyCommited() //QString oldView = view; // uncomment when implementing notify manager call database = createView->database; + QString oldView = view; view = createView->view; existingView = true; initView(); updateQueryToolbarStatus(); updateWindowTitle(); + if (oldView.compare(view, Qt::CaseInsensitive) == 0) + notifyInfo(tr("Commited changes for view '%1' successfly.").arg(view)); + else + notifyInfo(tr("Commited changes for view '%1' (named before '%2') successfly.").arg(view, oldView)); + DBTREE->refreshSchema(db); } @@ -599,6 +703,154 @@ void ViewWindow::checkIfViewDeleted(const QString& database, const QString& obje } } +void ViewWindow::updateOutputColumnsVisibility() +{ + bool enabled = outputColumnsCheck->isChecked(); + + ui->outputColumnsContainer->setVisible(enabled); + actionMap[Action::GENERATE_OUTPUT_COLUMNS]->setVisible(enabled); + actionMap[Action::ADD_COLUMN]->setVisible(enabled); + actionMap[Action::EDIT_COLUMN]->setVisible(enabled); + actionMap[Action::DEL_COLUMN]->setVisible(enabled); + actionMap[Action::MOVE_COLUMN_UP]->setVisible(enabled); + actionMap[Action::MOVE_COLUMN_DOWN]->setVisible(enabled); + + updateQueryToolbarStatus(); +} + +void ViewWindow::addColumn() +{ + QListWidgetItem* item = new QListWidgetItem(); + item->setFlags(item->flags() | Qt::ItemIsEditable); + ui->outputColumnsTable->addItem(item); + ui->outputColumnsTable->editItem(item); + ui->outputColumnsTable->setCurrentItem(item); + updateColumnButtons(); +} + +void ViewWindow::editColumn() +{ + QListWidgetItem* item = ui->outputColumnsTable->currentItem(); + ui->outputColumnsTable->editItem(item); + updateColumnButtons(); +} + +void ViewWindow::delColumn() +{ + QListWidgetItem* item = ui->outputColumnsTable->takeItem(ui->outputColumnsTable->currentRow()); + delete item; + updateColumnButtons(); +} + +void ViewWindow::moveColumnUp() +{ + int row = ui->outputColumnsTable->currentRow(); + if (row <= 0) + return; + + QListWidgetItem* item = ui->outputColumnsTable->takeItem(row); + ui->outputColumnsTable->insertItem(--row, item); + ui->outputColumnsTable->setCurrentItem(item); +} + +void ViewWindow::moveColumnDown() +{ + int row = ui->outputColumnsTable->currentRow(); + if (row + 1 >= ui->outputColumnsTable->count()) + return; + + QListWidgetItem* item = ui->outputColumnsTable->takeItem(row); + ui->outputColumnsTable->insertItem(++row, item); + ui->outputColumnsTable->setCurrentItem(item); +} + +void ViewWindow::updateColumnButtons() +{ + QListWidgetItem* item = ui->outputColumnsTable->currentItem(); + int row = ui->outputColumnsTable->currentRow(); + + actionMap[MOVE_COLUMN_UP]->setEnabled(row > 0); + actionMap[MOVE_COLUMN_DOWN]->setEnabled(row + 1 < ui->outputColumnsTable->count()); + actionMap[EDIT_COLUMN]->setEnabled(item != nullptr); + actionMap[DEL_COLUMN]->setEnabled(item != nullptr); +} + +void ViewWindow::generateOutputColumns() +{ + if (ui->outputColumnsTable->count() > 0) + { + QMessageBox::StandardButton res = QMessageBox::question(this, tr("Override columns"), tr("Currently defined columns will be overriden. Do you want to continue?")); + if (res != QMessageBox::Yes) + return; + } + + // Validate and generate fresh createView instance + bool validated = validate(true); + if (!validated) + return; + + // Make copy of CREATE statement and remove columns + SqliteCreateView* stmt = dynamic_cast(createView->clone()); + for (SqliteIndexedColumn* col : stmt->columns) + delete col; + + stmt->columns.clear(); + + // Indentify columns + SchemaResolver resolver(db); + QStringList columns = resolver.getColumnsUsingPragma(stmt); + delete stmt; + if (columns.isEmpty()) + { + notifyWarn(tr("Could not determinate columns returned from the view. The query is problably incomplete or contains errors.")); + return; + } + + ui->outputColumnsTable->clear(); + ui->outputColumnsTable->addItems(columns); + + QListWidgetItem* item = nullptr; + for (int row = 0; row < columns.size(); row++) + { + item = ui->outputColumnsTable->item(row); + item->setFlags(item->flags() | Qt::ItemIsEditable); + } +} + +void ViewWindow::updateDbRelatedUiElements() +{ + bool enabled = db->getDialect() == Dialect::Sqlite3; + outputColumnsCheck->setVisible(enabled); + outputColumnsSeparator->setVisible(enabled); +} + +void ViewWindow::updateTabsOrder() +{ + tabsMoving = true; + ui->tabWidget->removeTab(getDataTabIdx()); + int idx = 1; + if (CFG_UI.General.DataTabAsFirstInViews.get()) + idx = 0; + + ui->tabWidget->insertTab(idx, ui->dataTab, tr("Data")); + tabsMoving = false; +} + +void ViewWindow::triggerViewDoubleClicked(const QModelIndex& idx) +{ + if (!idx.isValid()) + { + addTrigger(); + return; + } + + QString trigger = ui->triggersList->item(idx.row(), 0)->text(); + + DbObjectDialogs dialogs(db, this); + dialogs.editTrigger(trigger); + refreshTriggers(); +} + void ViewWindow::refreshTriggers() { if (!db || !db->isValid()) @@ -680,9 +932,21 @@ void ViewWindow::updateDdlTab() bool ViewWindow::isModified() const { - return (originalCreateView && originalCreateView->view != ui->nameEdit->text()) || - ui->queryEdit->toPlainText() != originalQuery || - !existingView; + // Quick checks first + bool modified = !existingView || (originalCreateView && originalCreateView->view != ui->nameEdit->text()) || + ui->queryEdit->toPlainText() != originalQuery; + + if (modified) + return modified; + + // And now a bit slower check + QStringList origCols = createView ? indexedColumnsToNamesOnly(createView->columns) : QStringList(); + QStringList currentCols; + if (outputColumnsCheck->isChecked()) + currentCols = collectColumnNames(); + + bool colsModified = origCols != currentCols; + return colsModified; } bool ViewWindow::validate(bool skipWarnings) @@ -697,12 +961,9 @@ bool ViewWindow::validate(bool skipWarnings) } // Rebuilding createView statement and validating it on the fly. - QString ddl = "CREATE VIEW %1 AS %2"; - QString viewName = wrapObjIfNeeded(ui->nameEdit->text(), db->getDialect()); - QString select = ui->queryEdit->toPlainText(); - + QString ddl = getCurrentDdl(); Parser parser(db->getDialect()); - if (!parser.parse(ddl.arg(viewName).arg(select)) || parser.getQueries().size() < 1) + if (!parser.parse(ddl) || parser.getQueries().size() < 1) { notifyError(tr("The SELECT statement could not be parsed. Please correct the query and retry.\nDetails: %1").arg(parser.getErrorString())); return false; diff --git a/SQLiteStudio3/guiSQLiteStudio/windows/viewwindow.h b/SQLiteStudio3/guiSQLiteStudio/windows/viewwindow.h index 62e1218..65c3260 100644 --- a/SQLiteStudio3/guiSQLiteStudio/windows/viewwindow.h +++ b/SQLiteStudio3/guiSQLiteStudio/windows/viewwindow.h @@ -13,12 +13,12 @@ namespace Ui { } class SqliteSyntaxHighlighter; -class SqlQueryModel; class WidgetCover; class QPushButton; class QProgressBar; class ChainExecutor; class ViewModifier; +class SqlViewModel; CFG_KEY_LIST(ViewWindow, QObject::tr("A view window"), CFG_KEY_ENTRY(REFRESH_TRIGGERS, Qt::Key_F5, QObject::tr("Refresh view trigger list")) @@ -41,6 +41,12 @@ class GUI_API_EXPORT ViewWindow : public MdiChild REFRESH_QUERY, COMMIT_QUERY, ROLLBACK_QUERY, + ADD_COLUMN, + EDIT_COLUMN, + DEL_COLUMN, + MOVE_COLUMN_UP, + MOVE_COLUMN_DOWN, + GENERATE_OUTPUT_COLUMNS, // Triggers tab REFRESH_TRIGGERS, ADD_TRIGGER, @@ -103,6 +109,12 @@ class GUI_API_EXPORT ViewWindow : public MdiChild QString getCurrentTrigger() const; void applyInitialTab(); QString getCurrentDdl() const; + QStringList indexedColumnsToNamesOnly(const QList& columns) const; + QStringList collectColumnNames() const; + void columnsFromViewToList(); + int getDataTabIdx() const; + int getQueryTabIdx() const; + int getDdlTabIdx() const; Db* db = nullptr; QString database; @@ -113,13 +125,16 @@ class GUI_API_EXPORT ViewWindow : public MdiChild bool modified = false; SqliteCreateViewPtr originalCreateView; SqliteCreateViewPtr createView; - SqlQueryModel* dataModel = nullptr; + SqlViewModel* dataModel = nullptr; QString originalQuery; WidgetCover* widgetCover = nullptr; ChainExecutor* structureExecutor = nullptr; ViewModifier* viewModifier = nullptr; Ui::ViewWindow *ui = nullptr; bool modifyingThisView = false; + QAction* outputColumnsCheck = nullptr; + QAction* outputColumnsSeparator = nullptr; + bool tabsMoving = false; private slots: void refreshView(); @@ -139,6 +154,17 @@ class GUI_API_EXPORT ViewWindow : public MdiChild void prevTab(); void dbClosedFinalCleanup(); void checkIfViewDeleted(const QString& database, const QString& object, DbObjectType type); + void updateOutputColumnsVisibility(); + void addColumn(); + void editColumn(); + void delColumn(); + void moveColumnUp(); + void moveColumnDown(); + void updateColumnButtons(); + void generateOutputColumns(); + void updateDbRelatedUiElements(); + void updateTabsOrder(); + void triggerViewDoubleClicked(const QModelIndex& idx); public slots: void refreshTriggers(); diff --git a/SQLiteStudio3/guiSQLiteStudio/windows/viewwindow.ui b/SQLiteStudio3/guiSQLiteStudio/windows/viewwindow.ui index 0fdccc3..9112280 100644 --- a/SQLiteStudio3/guiSQLiteStudio/windows/viewwindow.ui +++ b/SQLiteStudio3/guiSQLiteStudio/windows/viewwindow.ui @@ -29,7 +29,7 @@ - 0 + 2 @@ -68,7 +68,86 @@ - + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Vertical + + + + + 4 + + + 4 + + + 4 + + + 4 + + + 4 + + + + + Output column names + + + + + + true + + + QAbstractItemView::InternalMove + + + Qt::MoveAction + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + true + + + + + + + + + + + + +
@@ -91,7 +170,7 @@
- + QAbstractItemView::NoEditTriggers @@ -114,7 +193,7 @@
- + DDL @@ -149,6 +228,11 @@ QPlainTextEdit
sqleditor.h
+ + ExtTableWidget + QTableWidget +
common/exttablewidget.h
+
diff --git a/SQLiteStudio3/lang.tcl b/SQLiteStudio3/lang.tcl index 00fd151..4746a8d 100755 --- a/SQLiteStudio3/lang.tcl +++ b/SQLiteStudio3/lang.tcl @@ -2,6 +2,7 @@ proc usage {} { puts "$::argv0 (add|remove) " + puts "$::argv0 add_plugin " puts "$::argv0 (update|release|status)" } @@ -111,6 +112,36 @@ switch -- $op { puts "$k - ${perc}% ($tr / $all)" } } + "add_plugin" { + if {$argc != 2} { + usage + exit 1 + } + + set plug [lindex $argv 1] + set plugPro ../Plugins/$plug/$plug.pro + if {![file exists $plugPro]} { + puts "$plugPro does not exist." + exit 1 + } + + set fd [open ../Plugins/CsvImport/CsvImport.pro r] + set data [read $fd] + close $fd + + set langs [list] + set trData "\nTRANSLATIONS += " + foreach {all lang} [regexp -inline -all -- {CsvImport_(\w+)\.ts} $data] { + append trData "\\\n\t\t${plug}_$lang.ts" + lappend langs $lang + } + append trData "\n" + + set fd [open $plugPro a+] + puts $fd $trData + close $fd + puts "Added translation languages for plugin $plug:\n[join $langs \n]" + } "add" - "remove" { if {$argc != 2} { usage diff --git a/SQLiteStudio3/sqlitestudio/main.cpp b/SQLiteStudio3/sqlitestudio/main.cpp index 0ac506f..94ee80e 100644 --- a/SQLiteStudio3/sqlitestudio/main.cpp +++ b/SQLiteStudio3/sqlitestudio/main.cpp @@ -36,7 +36,7 @@ #include #include -bool listPlugins = false; +static bool listPlugins = false; QString uiHandleCmdLineArgs() { @@ -51,6 +51,7 @@ QString uiHandleCmdLineArgs() QCommandLineOption lemonDebugOption("debug-lemon", QObject::tr("Enables Lemon parser debug messages for SQL code assistant.")); QCommandLineOption sqlDebugOption("debug-sql", QObject::tr("Enables debugging of every single SQL query being sent to any database.")); QCommandLineOption sqlDebugDbNameOption("debug-sql-db", QObject::tr("Limits SQL query messages to only the given ."), QObject::tr("database")); + QCommandLineOption executorDebugOption("debug-query-executor", QObject::tr("Enables debugging of SQLiteStudio's query executor.")); QCommandLineOption listPluginsOption("list-plugins", QObject::tr("Lists plugins installed in the SQLiteStudio and quits.")); parser.addOption(debugOption); parser.addOption(debugStdOutOption); @@ -58,6 +59,7 @@ QString uiHandleCmdLineArgs() parser.addOption(lemonDebugOption); parser.addOption(sqlDebugOption); parser.addOption(sqlDebugDbNameOption); + parser.addOption(executorDebugOption); parser.addOption(listPluginsOption); parser.addPositionalArgument(QObject::tr("file"), QObject::tr("Database file to open")); @@ -68,6 +70,7 @@ QString uiHandleCmdLineArgs() setUiDebug(enableDebug, !parser.isSet(debugStdOutOption), parser.value(debugFileOption)); CompletionHelper::enableLemonDebug = parser.isSet(lemonDebugOption); setSqlLoggingEnabled(parser.isSet(sqlDebugOption)); + setExecutorLoggingEnabled(parser.isSet(executorDebugOption)); if (parser.isSet(sqlDebugDbNameOption)) setSqlLoggingFilter(parser.value(sqlDebugDbNameOption)); diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_de.qm b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_de.qm index 9dad8df..6007538 100644 Binary files a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_de.qm and b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_de.qm differ diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_de.ts b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_de.ts index ce4a973..ff1c85b 100644 --- a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_de.ts +++ b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_de.ts @@ -1,6 +1,6 @@ - + QObject @@ -11,17 +11,17 @@ Enables debug messages in console (accessible with F12). - Aktiviert Debug-Meldungen in der Konsole (erreichbar über F12) + Aktiviert Debug-Meldungen in der Konsole (erreichbar über F12). Redirects debug messages into standard output (forces debug mode). - Leitet Debug-Meldungen in den Standardausgabekanal um (erzwingt den Debugmodus) + Leitet Debug-Meldungen in den Standardausgabekanal um (erzwingt den Debugmodus). Redirects debug messages into given file (forces debug mode). - Leitet Debug-Meldungen in die angegebene Datei um (erzwingt den Debugmodus) + Leitet Debug-Meldungen in die angegebene Datei um (erzwingt den Debugmodus). @@ -51,23 +51,28 @@ + Enables debugging of SQLiteStudio's query executor. + + + + Lists plugins installed in the SQLiteStudio and quits. Was wird hier beendet? Listet die in SQLiteStudio installierten Plugins auf und beendet. - + file Datei - + Database file to open Zu öffnende Datenbankdatei - - + + Error Fehler diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_es.ts b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_es.ts index 443941d..0130240 100644 --- a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_es.ts +++ b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_es.ts @@ -1,6 +1,6 @@ - + QObject @@ -50,22 +50,27 @@ + Enables debugging of SQLiteStudio's query executor. + + + + Lists plugins installed in the SQLiteStudio and quits. - + file - + Database file to open - - + + Error diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_fr.ts b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_fr.ts index f801dd7..78be06b 100644 --- a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_fr.ts +++ b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_fr.ts @@ -32,7 +32,7 @@ Enables Lemon parser debug messages for SQL code assistant. - Message de déboguage avec l'analyseur Lemon pour un assistant code SQL. + Message de déboguage avec l’analyseur Lemon pour un assistant code SQL. diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_it.qm b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_it.qm new file mode 100644 index 0000000..9dad8df Binary files /dev/null and b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_it.qm differ diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_it.ts b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_it.ts index f0caedd..9cd5c61 100644 --- a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_it.ts +++ b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_it.ts @@ -1,6 +1,6 @@ - + QObject @@ -50,22 +50,27 @@ + Enables debugging of SQLiteStudio's query executor. + + + + Lists plugins installed in the SQLiteStudio and quits. - + file - + Database file to open - - + + Error diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_pl.ts b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_pl.ts index 967434a..700bb5e 100644 --- a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_pl.ts +++ b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_pl.ts @@ -1,6 +1,6 @@ - + QObject @@ -55,5 +55,9 @@ log file plik logów + + Enables debugging of SQLiteStudio's query executor. + Włącza debugowanie wykonawcy zapytań w SQLiteStudio. + diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_pt_BR.ts b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_pt_BR.ts index 2a54175..b637de7 100644 --- a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_pt_BR.ts +++ b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_pt_BR.ts @@ -1,6 +1,6 @@ - + QObject @@ -50,22 +50,27 @@ + Enables debugging of SQLiteStudio's query executor. + + + + Lists plugins installed in the SQLiteStudio and quits. - + file - + Database file to open - - + + Error diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_ru.ts b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_ru.ts index 3ca5a22..9808fe7 100644 --- a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_ru.ts +++ b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_ru.ts @@ -1,6 +1,6 @@ - + QObject @@ -50,22 +50,27 @@ + Enables debugging of SQLiteStudio's query executor. + + + + Lists plugins installed in the SQLiteStudio and quits. Выводит список установленных в SQLiteStudio модулей и осуществляет выход. - + file файл - + Database file to open Файл базы данных для открытия - - + + Error Ошибка diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_sk.ts b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_sk.ts index a7b3257..496f44d 100644 --- a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_sk.ts +++ b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_sk.ts @@ -1,6 +1,6 @@ - + QObject @@ -50,22 +50,27 @@ + Enables debugging of SQLiteStudio's query executor. + + + + Lists plugins installed in the SQLiteStudio and quits. - + file Súbor - + Database file to open - - + + Error Chyba diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_zh_CN.qm b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_zh_CN.qm index be651ee..83692c1 100644 Binary files a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_zh_CN.qm and b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_zh_CN.qm differ diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_zh_CN.ts b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_zh_CN.ts index ec8bd90..d5b76d7 100644 --- a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_zh_CN.ts +++ b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_zh_CN.ts @@ -1,6 +1,6 @@ - + QObject @@ -50,22 +50,27 @@ + Enables debugging of SQLiteStudio's query executor. + + + + Lists plugins installed in the SQLiteStudio and quits. 列出已安装的插件并退出。 - + file 文件 - + Database file to open 要打开的数据库文件 - - + + Error 错误 diff --git a/SQLiteStudio3/sqlitestudiocli/cli_config.cpp b/SQLiteStudio3/sqlitestudiocli/cli_config.cpp index 93c2b53..f77805e 100644 --- a/SQLiteStudio3/sqlitestudiocli/cli_config.cpp +++ b/SQLiteStudio3/sqlitestudiocli/cli_config.cpp @@ -1,4 +1,5 @@ #include "cli_config.h" +#include CFG_DEFINE(Cli) diff --git a/SQLiteStudio3/sqlitestudiocli/climsghandler.cpp b/SQLiteStudio3/sqlitestudiocli/climsghandler.cpp index d36f9d0..f9dbc76 100644 --- a/SQLiteStudio3/sqlitestudiocli/climsghandler.cpp +++ b/SQLiteStudio3/sqlitestudiocli/climsghandler.cpp @@ -14,6 +14,9 @@ void cliMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString txt; switch (type) { + case QtInfoMsg: + txt = QString("Info: %1").arg(msg); + break; case QtDebugMsg: txt = QString("Debug: %1").arg(msg); break; diff --git a/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_de.ts b/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_de.ts index f544581..1eb52bd 100644 --- a/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_de.ts +++ b/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_de.ts @@ -1,6 +1,6 @@ - + CLI diff --git a/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_es.ts b/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_es.ts index 7d3b5c5..3ed0731 100644 --- a/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_es.ts +++ b/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_es.ts @@ -1,6 +1,6 @@ - + CLI diff --git a/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_fr.ts b/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_fr.ts index cdcfb5b..5a505a0 100644 --- a/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_fr.ts +++ b/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_fr.ts @@ -11,12 +11,12 @@ No current working database is set. - Aucune base de données en cours n'est activée. + Aucune base de données en cours n’est activée. Type %1 for help - Touche %1 pour l'aide + Touche %1 pour l’aide @@ -26,7 +26,7 @@ Could not add database %1 to list. - Impossible d'ajouter la base de données %1 à la liste. + Impossible d’ajouter la base de données %1 à la liste. @@ -47,7 +47,7 @@ Could not add database %1 to list. - Impossible d'ajouter le base de données %1 à la liste. + Impossible d’ajouter le base de données %1 à la liste. @@ -62,7 +62,7 @@ Adds given database pointed by <path> with given <name> to list the databases list. The <name> is just a symbolic name that you can later refer to. Just pick any unique name. For list of databases already on the list use %1 command. - Ajoutez la base de données pointée par <path>nommée <name>à la liste des baszs de données. Le nom<name>est seulement un nom symbilique que vous pourrez y référer. Choississez un nom unique. Pour une base de données figuant dans la liste utilisez la commande %1. + Ajoutez la base de données pointée par <path>nommée <name>à la liste des baszs de données. Le nom<name>est seulement un nom symbilique que vous pourrez y référer. Choississez un nom unique. Pour une base de données figuant dans la liste utilisez la commande %1. @@ -97,7 +97,7 @@ Very similar command to 'cd' known from Unix systems and Windows. It requires a <path> argument to be passed, therefore calling %1 will always cause a change of the directory. To learn what's the current working directory use %2 command and to list contents of the current working directory use %3 command. - La commande 'cd' est connu du système UNIX et Windows. Elle nécessite le paramètre <chemin> passé avant l'appel %1 qui occasionnera une modification du répertoire. Pour connaitre qu'elle est le répertoire courant utiliser la commande %2 et pour lister le contenu de celui-ci utilisez la commande %3. + La commande « cd » est connu du système UNIX et Windows. Elle nécessite le paramètre <chemin> passé avant l’appel %1 qui occasionnera une modification du répertoire. Pour connaitre qu’elle est le répertoire courant utiliser la commande %2 et pour lister le contenu de celui-ci utilisez la commande %3. @@ -111,7 +111,7 @@ Cannot call %1 when no database is set to be current. Specify current database with %2 command or pass database name to %3. - Impossible d'appeler %1 lorsqu'aucune base de données n'est active. Spécifiez la base de données active avec la commande %2 ou par le nom de la base de données par %3. + Impossible d’appeler %1 lorsqu’aucune base de données n’est active. Spécifiez la base de données active avec la commande %2 ou par le nom de la base de données par %3. @@ -127,12 +127,12 @@ closes given (or current) database - Fermeture d'une de données sélectionnées (ou actuelle) + Fermeture d’une de données sélectionnées (ou actuelle) Closes database connection. If the database was already closed, nothing happens. If <name> is provided, it should be name of the database to close (as printed by %1 command). The the <name> is not provided, then current working database is closed (see help for %2 for details). - Fermeture de base de données connectée. . Si la base est déjà fermée, aucune action. Si <name> est fourni, c'est celle ainsi qui sera close (as printed by %1 command). Si <name> n'est pas fourni, la base actuelle est close (voir l'aide %2 pour plus de détails). + Fermeture de base de données connectée. . Si la base est déjà fermée, aucune action. Si <name> est fourni, c’est celle ainsi qui sera close (as printed by %1 command). Si <name> n’est pas fourni, la base actuelle est close (voir l’aide %2 pour plus de détails). @@ -146,7 +146,7 @@ No current working database defined. - Aucune base de données actuelle n'est définie. + Aucune base de données actuelle n’est définie. @@ -195,7 +195,7 @@ Prints list of databases registered in the SQLiteStudio. Each database on the list can be in open or closed state and %1 tells you that. The current working database (aka default database) is also marked on the list with '*' at the start of its name. See help for %2 command to learn about the default database. - Imprimez la liste des bases de données enregistrées sous SQLiteStudio. Chaque base se données de la liste peut être ouverte ou close et %1 vous indique lesquellest.La base de données actuelle est aussi marquée dans la liste par '*' en début de nom. Voir l'aide la commande %2 pour en savoir plus sur la base de données actuelle. + Imprimez la liste des bases de données enregistrées sous SQLiteStudio. Chaque base se données de la liste peut être ouverte ou close et %1 vous indique lesquellest.La base de données actuelle est aussi marquée dans la liste par « * » en début de nom. Voir l’aide la commande %2 pour en savoir plus sur la base de données actuelle. @@ -205,14 +205,14 @@ No working database is set. Call %1 command to set working database. Call %2 to see list of all databases. - Aucune base de données de travail n'est activée. + Aucune base de données de travail n’est activée. Appelez la commande %1 pour activer la base de données active. Appelez %2 pour voir la liste de toutes les bases de données. Database is not open. - La base de données n'est pas ouverte. + La base de données n’est pas ouverte. @@ -277,7 +277,7 @@ Appelez %2 pour voir la liste de toutes les bases de données. This is very similar to 'dir' command known from Windows and 'ls' command from Unix systems. You can pass <pattern> with wildcard characters to filter output. - Ceci est très semblable à la commande 'dir' de Windows et à la commande de 'ls' de systèmes Unix. + Ceci est très semblable à la commande « dir » de Windows et à la commande de « ls » de systèmes Unix. You pouvez utiliser les caractères de remplacement <pattern> npour filtrer la sortie. @@ -292,12 +292,12 @@ You pouvez utiliser les caractères de remplacement <pattern> npour filtre quits the application - Quitter l'application + Quitter l’application Quits the application. Settings are stored in configuration file and will be restored on next startup. - Quittez l'apllication. Le paramètrage est stocké dans la configuration et sera restauré au prochain lancement. + Quittez l’apllication. Le paramètrage est stocké dans la configuration et sera restauré au prochain lancement. @@ -305,7 +305,7 @@ You pouvez utiliser les caractères de remplacement <pattern> npour filtre shows this help message - Affichagez l'aide du message + Affichagez l’aide du message @@ -318,9 +318,9 @@ You can always execute any command with exactly single '--help' option Utilisez %1 pour connaitre certaines commandes supportées par la ligne de commande (CLI) de SQLiteStudio. Pour voir les commandes supportées, saississez %2 sana arguments. -En utilisant le nom de <command>, vous ajouter le caractère spécial'(%3'). +En utilisant le nom de <command>, vous ajouter le caractère spécial(« %3 »). -Vous pouvez exécuter n'importe quelle commande avec l'option ' --help' pour voir l'aide pour cette commande. C'est une alternative à : %1 <commande>. +Vous pouvez exécuter n’importe quelle commande avec l’option « --help » pour voir l’aide pour cette commande. C’est une alternative à : %1 <commande>. @@ -336,7 +336,7 @@ Vous pouvez exécuter n'importe quelle commande avec l'option ' - Type '%1' for list of available commands. - Saisissez '%1' pour la liste des commandes valides. + Saisissez « %1 » pour la liste des commandes valides. @@ -354,12 +354,12 @@ Vous pouvez exécuter n'importe quelle commande avec l'option ' - Current history limit is set to: %1 - L'historique actuel est limité à: %1 + L’historique actuel est limité à: %1 prints history or erases it - Imprimez l'historique ou supprimez le + Imprimez l’historique ou supprimez le @@ -368,7 +368,7 @@ Vous pouvez exécuter n'importe quelle commande avec l'option ' - When the -c or --clear option is passed, then the history gets erased. When the -l or --limit option is passed, it sets the new history entries limit. It requires an additional argument saying how many entries do you want the history to be limited to. Use -ql or --querylimit option to see the current limit value. - Lorqu'aucun argument n'est passé,cette commande imprime l'histoirique. Chaque entrée est séparée par une ligne vide, permettant une lecture aisée. + Lorqu’aucun argument n’est passé,cette commande imprime l’histoirique. Chaque entrée est séparée par une ligne vide, permettant une lecture aisée. When the -c or --clear option is passed, then the history gets erased. When the -l or --limit option is passed, it sets the new history entries limit. It requires an additional argument saying how many entries do you want the history to be limited to. @@ -400,17 +400,17 @@ Use -ql or --querylimit option to see the current limit value. Current results printing mode: %1 - Résultats actuels du mode d' impression: %1 + Résultats actuels du mode d’ impression: %1 Invalid results printing mode: %1 - Résultats invalides du mode d' impression: %1 + Résultats invalides du mode d’ impression: %1 New results printing mode: %1 - Résultats actuels du mode d' impression: %1 + Résultats actuels du mode d’ impression: %1 @@ -454,17 +454,17 @@ The ROW mode is recommended if you need to see whole values and you don't e Current NULL representation string: %1 - Représentation actuelle d'une chaine NULL: %1 + Représentation actuelle d’une chaine NULL: %1 tells or changes the NULL representation string - Modifiez la représentation d'une chaine NULL + Modifiez la représentation d’une chaine NULL If no argument was passed, it tells what's the current NULL value representation (that is - what is printed in place of NULL values in query results). If the argument is given, then it's used as a new string to be used for NULL representation. - Si on n'a passé aucun argument, c'est la représentation de valeur NULL actuelle qui est utilisée (ce qui est imprimé à la place de valeurs NULL dans des résultats de requête). Si on donne un argument, il sera utilisé comme une nouvelle chaine représentant NULL. + Si on n’a passé aucun argument, c’est la représentation de valeur NULL actuelle qui est utilisée (ce qui est imprimé à la place de valeurs NULL dans des résultats de requête). Si on donne un argument, il sera utilisé comme une nouvelle chaine représentant NULL. @@ -472,17 +472,17 @@ The ROW mode is recommended if you need to see whole values and you don't e Cannot call %1 when no database is set to be current. Specify current database with %2 command or pass database name to %3. - Impossible d'appeler %1 lorsque aucune base de données n'est sélectionnée. Spécifiez la base de données actuelle avec la commande %2 ou nommez la base de données %3. + Impossible d’appeler %1 lorsque aucune base de données n’est sélectionnée. Spécifiez la base de données actuelle avec la commande %2 ou nommez la base de données %3. Could not add database %1 to list. - Impossible d'ajouter la base de données %1 à la liste. + Impossible d’ajouter la base de données %1 à la liste. File %1 doesn't exist in %2. Cannot open inexisting database with %3 command. To create a new database, use %4 command. - Le fichier %1 n'existe pas dans %2. Impossible d'ouvrir une base de données avec la commande %3. Pour créer une nouvelle base de données utilisez la commande %4. + Le fichier %1 n’existe pas dans %2. Impossible d’ouvrir une base de données avec la commande %3. Pour créer une nouvelle base de données utilisez la commande %4. @@ -497,7 +497,7 @@ The ROW mode is recommended if you need to see whole values and you don't e Opens connection to the database. If no additional argument was passed, then the connection is open to the current default database (see help for %1 for details). However if an argument was passed, it can be either <name> of the registered database to open, or it can be <path> to the database file to open. In the second case, the <path> gets registered on the list with a generated name, but only for the period of current application session. After restarting application such database is not restored on the list. - Ouvre la connexion de la base de données. Si aucun argument n'est passé, alors la connexion est ouverte comme base de données actuelle (voir l'aide %1 pour plus de détails). Cependant si on a passé un argument il peut être le <name> d'une base de données enregistrée, ou cela peut être le <chemin> du fichier de base de données. Dans le deuxième cas, le <chemin> est enregistré dans la liste avec un nom généré mais seulement pendant la période de la session actuelle. Après la reprise de la l'application une telle base de données n'est pas rétablie dans la liste. + Ouvre la connexion de la base de données. Si aucun argument n’est passé, alors la connexion est ouverte comme base de données actuelle (voir l’aide %1 pour plus de détails). Cependant si on a passé un argument il peut être le <name> d’une base de données enregistrée, ou cela peut être le <chemin> du fichier de base de données. Dans le deuxième cas, le <chemin> est enregistré dans la liste avec un nom généré mais seulement pendant la période de la session actuelle. Après la reprise de la l’application une telle base de données n’est pas rétablie dans la liste. @@ -522,7 +522,7 @@ The ROW mode is recommended if you need to see whole values and you don't e This is the same as 'pwd' command on Unix systems and 'cd' command without arguments on Windows. It prints current working directory. You can change the current working directory with %1 command and you can also list contents of the current working directory with %2 command. - C'est la même commande d'un système Unix 'pwd' ou 'cd' sans arguments de Windows. Ceci imprimele répertoire de travail courant. Vous pouvez changer le répertoire avec le commande %1 et avoir la liste des répertoire de travail avec la commande %2. + C’est la même commande d’un système Unix « pwd » ou « cd » sans arguments de Windows. Ceci imprimele répertoire de travail courant. Vous pouvez changer le répertoire avec le commande %1 et avoir la liste des répertoire de travail avec la commande %2. @@ -550,7 +550,7 @@ The ROW mode is recommended if you need to see whole values and you don't e Removes <name> database from the list of registered databases. If the database was not on the list (see %1 command), then error message is printed and nothing more happens. - Enlève la base de données <nom> de la liste des bases enregistrées.si la base de données n'est pas dans la liste (voir la commande %1), alors message d'erreur est imprimé sans aucunes autres lignes. + Enlève la base de données <nom> de la liste des bases enregistrées.si la base de données n’est pas dans la liste (voir la commande %1), alors message d’erreur est imprimé sans aucunes autres lignes. @@ -566,14 +566,14 @@ The ROW mode is recommended if you need to see whole values and you don't e No working database is set. Call %1 command to set working database. Call %2 to see list of all databases. - Aucune base de données de travail n'est activée. + Aucune base de données de travail n’est activée. Appelez la commande %1 pour activer la base de données active. Appelez %2 pour voir la liste de toutes les bases de données. Database is not open. - La base de données n'est pas ouverte. + La base de données n’est pas ouverte. @@ -583,7 +583,7 @@ Appelez %2 pour voir la liste de toutes les bases de données. This command is executed every time you enter SQL query in command prompt. It executes the query on the current working database (see help for %1 for details). There's no sense in executing this command explicitly. Instead just type the SQL query in the command prompt, without any command prefixed. - Cette commande est exécutée chaque fois vous saississez une requête SQL au prompt de commande. Il exécute la requête sur la base de données actuelle (voir l'aide %1 pour des détails). Il n'y a aucun sens dans l'exécution de cette commande explicitement. Instead just type the SQL query in the command prompt, without any command prefixed. + Cette commande est exécutée chaque fois vous saississez une requête SQL au prompt de commande. Il exécute la requête sur la base de données actuelle (voir l’aide %1 pour des détails). Il n’y a aucun sens dans l’exécution de cette commande explicitement. Instead just type the SQL query in the command prompt, without any command prefixed. @@ -605,7 +605,7 @@ Appelez %2 pour voir la liste de toutes les bases de données. Query execution error: %1 - Erreur d'exécution de la requête: %1 + Erreur d’exécution de la requête: %1 @@ -618,7 +618,7 @@ Appelez %2 pour voir la liste de toutes les bases de données. Cannot call %1 when no database is set to be current. Specify current database with %2 command or pass database name to %3. - Impossible d'appeler %1 quand aucune base de données n'est active. Spécifiez la base de données active avec la commade %2 ou nommez la base de données avec %3. + Impossible d’appeler %1 quand aucune base de données n’est active. Spécifiez la base de données active avec la commade %2 ou nommez la base de données avec %3. @@ -645,8 +645,8 @@ Appelez %2 pour voir la liste de toutes les bases de données. Prints list of tables in given <database> or in the current working database. Note, that the <database> should be the name of the registered database (see %1). The output list includes all tables from any other databases attached to the queried database. When the -s option is given, then system tables are also listed. - Imprime la liste des tables d'une <database> donnée ou la base de données actuelle. Notez que la <database> devrait être le nom enregistré de la base de données (voir %1). L'affichage de la liste inclus toutes les tables d'autres bases de données attachées à celle-ci. -Lorsque l'option '-s' est ajouté, les tables système sont aussi listées. + Imprime la liste des tables d’une <database> donnée ou la base de données actuelle. Notez que la <database> devrait être le nom enregistré de la base de données (voir %1). L’affichage de la liste inclus toutes les tables d’autres bases de données attachées à celle-ci. +Lorsque l’option « -s » est ajouté, les tables système sont aussi listées. @@ -660,7 +660,7 @@ Lorsque l'option '-s' est ajouté, les tables système sont aussi No current working database is selected. Use %1 to define one and then run %2. - Aucune base de données actuelle n'est sélectionnée. Utilisez %1 pour en définir uneet lancez avec %2. + Aucune base de données actuelle n’est sélectionnée. Utilisez %1 pour en définir uneet lancez avec %2. @@ -699,10 +699,10 @@ Lorsque l'option '-s' est ajouté, les tables système sont aussi When -c option is given, then also columns will be listed under each table. When -s option is given, then also system objects will be printed (sqlite_* tables, autoincrement indexes, etc). The database argument is optional and if provided, then only given database will be printed. This is not a registered database name, but instead it's an internal SQLite database name, like 'main', 'temp', or any attached database name. To print tree for other registered database, call %1 first to switch the working database, and then use %2 command. - Imprime tous les objets (tables, index, déclencheurs et vues) qui sont dans la base de données comme un arbre. L'arbre est très semblable à celui que vous pouvez voir dans lGUI client de SQLiteStudio. -Quand on ajoute l'option-c, alors aussi les colonnes seront inscrites sous chaque table. -Quand on ajoute l'option-s, alors aussi les objets de système seront imprimés (sqlite_* tables, des index d'autoincrément, etc). -L'argument de base de données est facultatif et si fourni, alors seulement la base de données donnée sera imprimée. Ceci n'est pas un nom de base de données enregistré, mais au lieu de cela c'est un nom de base de données SQLite interne, comme 'principal', 'ltemporaire', ou n'importe quel nom de base de données attaché. Pour imprimer l'arbre pour d'autre base de données enregistrée, appelez %1 d'abord pour changer la base de données actuelleet utiliser la commande %2. + Imprime tous les objets (tables, index, déclencheurs et vues) qui sont dans la base de données comme un arbre. L’arbre est très semblable à celui que vous pouvez voir dans lGUI client de SQLiteStudio. +Quand on ajoute l’option-c, alors aussi les colonnes seront inscrites sous chaque table. +Quand on ajoute l’option-s, alors aussi les objets de système seront imprimés (sqlite_* tables, des index d’autoincrément, etc). +L’argument de base de données est facultatif et si fourni, alors seulement la base de données donnée sera imprimée. Ceci n’est pas un nom de base de données enregistré, mais au lieu de cela c’est un nom de base de données SQLite interne, comme « principal », « temporaire », ou n’importe quel nom de base de données attaché. Pour imprimer l’arbre pour d’autre base de données enregistrée, appelez %1 d’abord pour changer la base de données actuelleet utiliser la commande %2. @@ -741,17 +741,17 @@ The default database can be selected in various ways: - by passing registered database name to the application startup parameters, - by restoring previously selected default database from saved configuration, - or when default database was not selected by any of the above, then first database from the registered databases list becomes the default one. - Changet la base de données actuelle <nom>. Si le <nom > de la base de données n'est pas enregistrée dans l'application, le message d'erreur est imprimé et aucun changement n'est fait. + Changet la base de données actuelle <nom>. Si le <nom > de la base de données n’est pas enregistrée dans l’application, le message d’erreur est imprimé et aucun changement n’est fait. Quel est la base de données actuelle? -Quand vous saississez une requête SQL à exécuter, celle-ci est exécutée sur la base de données par défaut, que l'on connaît aussi comme la base de données actuelle. La plupart de commandes concernant la base de données utilise la base de données de défaut d'utilisation, si on n'a fourni aucune base de données dans leurs arguments. La base de données actuelle est toujours identifiée par la ligne de commande. La base de données par défaut est toujours définie (à moins qu'il n'y ait aucune base de données dans la liste). +Quand vous saississez une requête SQL à exécuter, celle-ci est exécutée sur la base de données par défaut, que l’on connaît aussi comme la base de données actuelle. La plupart de commandes concernant la base de données utilise la base de données de défaut d’utilisation, si on n’a fourni aucune base de données dans leurs arguments. La base de données actuelle est toujours identifiée par la ligne de commande. La base de données par défaut est toujours définie (à moins qu’il n’y ait aucune base de données dans la liste). La base de données par défaut peut être choisie de diverses manières: - Utilisation de la commande%1, -- En passant nom de fichier de base de données aux paramètres de démarrage d'application, -- En passantle nom la base de données enregistrée aux paramètres de démarrage d'application, +- En passant nom de fichier de base de données aux paramètres de démarrage d’application, +- En passantle nom la base de données enregistrée aux paramètres de démarrage d’application, - En restaurant la base de données par défaut précédemment choisie dans la configuration sauvée, -- Ou quand la base de données par défaut n'a été choisie par aucun du susdit, l'alors première base de données de la liste de bases de données enregistrée devient le par défaut. +- Ou quand la base de données par défaut n’a été choisie par aucun du susdit, l’alors première base de données de la liste de bases de données enregistrée devient le par défaut. @@ -765,18 +765,18 @@ La base de données par défaut peut être choisie de diverses manières: Insufficient number of arguments. - Nombre d'arguments insuffisant. + Nombre d’arguments insuffisant. Too many arguments. - Trop d'arguements. + Trop d’arguements. Invalid argument value: %1. Expected one of: %2 - Valeur invalide de l'arguement %1. Exepté l'un d'eux: %2 + Valeur invalide de l’arguement %1. Exepté l’un d’eux: %2 @@ -788,7 +788,7 @@ Expected one of: %2 Option %1 requires an argument. CLI command syntax - L'option %1 nécessite un argument. + L’option %1 nécessite un argument. @@ -804,12 +804,12 @@ Expected one of: %2 Enables debug messages on standard error output. - Messages de débogage valides sur sortie d'erreur standard. + Messages de débogage valides sur sortie d’erreur standard. Enables Lemon parser debug messages for SQL code assistant. - Permet le débogage avec l'analyseur syntaxique de Lemo pour l'assistant SQL. + Permet le débogage avec l’analyseur syntaxique de Lemo pour l’assistant SQL. diff --git a/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_it.qm b/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_it.qm new file mode 100644 index 0000000..9dad8df Binary files /dev/null and b/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_it.qm differ diff --git a/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_it.ts b/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_it.ts index 959e194..5ef2bff 100644 --- a/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_it.ts +++ b/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_it.ts @@ -1,6 +1,6 @@ - + CLI diff --git a/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_pl.ts b/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_pl.ts index 9a0f67b..e1dfd31 100644 --- a/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_pl.ts +++ b/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_pl.ts @@ -1,6 +1,6 @@ - + CLI @@ -173,45 +173,45 @@ No working database is set. Call %1 command to set working database. Call %2 to see list of all databases. - Nie wybrano domyślnej bazy danych. + Nie wybrano domyślnej bazy danych. Użyj polecenia %1, aby ustawić domyślną bazę danych. Użyj polecenie %2, aby wypisać listę wszystkich baz. Database is not open. - Baz danych nie jest otwarta. + Baza danych nie jest otwarta. Cannot find table named: %1 - + Nie można znaleźć tabeli o nazwie: %1 Table: %1 - + Tabla: %1 Column name - + Nazwa kolumny Data type - + Typ danych Constraints - + Ograniczenia Virtual table: %1 - + Wirtualna tabela: %1 Construction arguments: - + Argumenty konstruujące: No construction arguments were passed for this virtual table. - + Nie podano argumentów konstruujących dla tej tabeli wirtualnej. diff --git a/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_pt_BR.ts b/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_pt_BR.ts index 0d46151..f874e9b 100644 --- a/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_pt_BR.ts +++ b/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_pt_BR.ts @@ -1,6 +1,6 @@ - + CLI diff --git a/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_ru.qm b/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_ru.qm index 2f2ac76..9943370 100644 Binary files a/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_ru.qm and b/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_ru.qm differ diff --git a/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_sk.ts b/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_sk.ts index e799908..8f71f1d 100644 --- a/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_sk.ts +++ b/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_sk.ts @@ -1,6 +1,6 @@ - + CLI diff --git a/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_zh_CN.qm b/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_zh_CN.qm index be651ee..1de3b17 100644 Binary files a/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_zh_CN.qm and b/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_zh_CN.qm differ diff --git a/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_zh_CN.ts b/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_zh_CN.ts index 71b2ea2..072f362 100644 --- a/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_zh_CN.ts +++ b/SQLiteStudio3/sqlitestudiocli/translations/sqlitestudiocli_zh_CN.ts @@ -1,6 +1,6 @@ - + CLI -- cgit v1.2.3