diff options
| author | 2015-04-04 14:41:10 -0400 | |
|---|---|---|
| committer | 2015-04-04 14:41:10 -0400 | |
| commit | b5f93b05578293d1d233b4920a28a5c2fd826f94 (patch) | |
| tree | 82332679f647e9c76e331206786d07a58dcfa9b8 /SQLiteStudio3/coreSQLiteStudio | |
| parent | af8a7a3e3dccf9c9ad257e3952173d180c8a7421 (diff) | |
| parent | a5b034d4a9c44f9bc1e83b01de82530f8fc63013 (diff) | |
Merge tag 'upstream/3.0.4'
Upstream version 3.0.4
# gpg: Signature made Sat 04 Apr 2015 02:41:09 PM EDT using RSA key ID EBE9BD91
# gpg: Good signature from "Unit 193 <unit193@gmail.com>"
# gpg: aka "Unit 193 <unit193@ninthfloor.org>"
# gpg: aka "Unit 193 <unit193@ubuntu.com>"
# gpg: aka "Unit 193 <unit193@ninthfloor.com>"
Diffstat (limited to 'SQLiteStudio3/coreSQLiteStudio')
79 files changed, 1241 insertions, 685 deletions
diff --git a/SQLiteStudio3/coreSQLiteStudio/ChangeLog.txt b/SQLiteStudio3/coreSQLiteStudio/ChangeLog.txt index fe7a977..f795356 100644 --- a/SQLiteStudio3/coreSQLiteStudio/ChangeLog.txt +++ b/SQLiteStudio3/coreSQLiteStudio/ChangeLog.txt @@ -1,3 +1,38 @@ +[3.0.4] + * [ADDED]: Import dialog has now "Ignore errors" option, to skip rows that causes problems (constraint violation, wrong column count, etc). + * [CHANGE]: Enhanced Copy&Paste capabilities of data grid, so copying and pasting internally in SQLiteStudio will not be limited by TSV format (NULL values will be distinguished, tab characters will be allowed in values), only pasting from outside will be affected by TSV limitations. + * [CHANGE]: "Invalid database" icon changed, so it's no longer confusing with "Connected" database. + * [CHANGE]: "Databases" panel cannot be closed/hidden anymore. + * [CHANGE]: Database dialog reorganized to look a bit nicer, db type moved to top, URL browse button for file is now separated to 2 buttons. + * [BUGFIX]: #2795 XmlExport plugin: Fixed crash that happend in most exports. + * [BUGFIX]: XmlExport plugin: Fixed column number attribute incrementing for data rows. + * [BUGFIX]: #2793 SqlEnterpriseFormatter plugin: Fixed formatting queries starting with EXPLAIN and EXPLAIN QUERY PLAN. + * [BUGFIX]: #2786 Fixed double plugin names in config dialog for built-in plugins. + * [BUGFIX]: Fixed dead-lock when fixing path for a database that pointed to inexisting file. + * [BUGFIX]: Fixed data editing for SQL queries joining the same table several times. + * [BUGFIX]: Fixed "Ctrl+W"/"Cmd+W" shortcut to work every time, not only every second time. + * [BUGFIX]: Fixed order of window focusing when closing with "Ctrl+W"/"Cmd+W" shortcut. + * [BUGFIX]: #2797 Database type is no longer disabled when adding existing database file. + * [BUGFIX]: SqlExport appends Foreign Key (re)enabling pragma at the end. + * [BUGFIX]: "Maximized" MDI window state is no longer lost after closing last MDI window. + * [BUGFIX]: #2812 TableModifier is now much smarter about when to recreate triggers and how to do it. + * [BUGFIX]: TriggerDialog no longer loses "When" field when editing existing trigger. + * [BUGFIX]: Columns of Indexes and Triggers tabs in Table Window don't shring after refresh anymore. + * [BUGFIX]: NumPad Enter key also accepts the Code Assistant choice. + * [BUGFIX]: Fixed drawing items in SQL code assistant, so they no longer are "black on dark blue" when using classic Windows theme. + * [BUGFIX]: #2790 Fixed hexadecimal literals evaluation in SQL queries. + * [BUGFIX]: #2804 Fixed querying SQLite 2 database. + * [BUGFIX]: Fixed executing query like: SELECT * FROM (SELECT * FROM table); - it used to crash. + * [BUGFIX]: #2798 Fixed crash when restoring DbList group for inexisting database. + * [BUGFIX]: #2808 Sorting indicators in data grid fixed to point the right direction and got a little bit larger. + * [BUGFIX]: #2807 Fixed SQL export plugin when exporting whole database without formatting SQL, so the missing semicolons are appended to each DDL. + * [BUGFIX]: #2806 Fixed table sorting in Export Dialog. + * [BUGFIX]: #2809 Fixed crash when trying to paste data into data grid with no rows in it. + * [BUGFIX]: Fixed rolling back of row marked to deletion, if it was previously already marked as edited. + * [BUGFIX]: #2814 Fixed executing custom SQL function with same bind parameter used multiple times. + * [BUGFIX]: #2815 Fixed refreshing data pages after adding/deleting rows in grid view. + * [BUGFIX]: #2820 Fixed parsing 'IN table.column' expression (used to incorrectly assume a 'NOT' keyword to be present, even it wasn't). + [3.0.3] * [ADDED]: Added visual validation indicators to DbDialog, so user is informed why the "Ok" button is disabled at the moment. * [ADDED]: Russian translation. @@ -22,6 +57,7 @@ * [BUGFIX]: Optimized loading huge data sets into data grid. It's faster and the progress bar acts more smoothly. * [BUGFIX]: Shortcut for closing current window is now displayed in the context menu for taskbar. * [BUGFIX]: "Skip first line" option in CSV import renamed to "First line represents CSV columns". Maybe this time it won't confused anyone. + * [BUGFIX]: #2790 Fixed hexadecimal literals evaluation in SQL queries. [3.0.2] * [ADDED]: Full support for the interface translations. diff --git a/SQLiteStudio3/coreSQLiteStudio/TODO.txt b/SQLiteStudio3/coreSQLiteStudio/TODO.txt index 055898c..de84b10 100644 --- a/SQLiteStudio3/coreSQLiteStudio/TODO.txt +++ b/SQLiteStudio3/coreSQLiteStudio/TODO.txt @@ -1,4 +1,5 @@ * Next versions: +- object names (columns, tables, etc) in dialogs should be validated against suffix/prefix whitespaces and if they appear, user should be asked for confirmation - small useful features: generating template queries from context menu for table/view, from data view. - commiting DataView should be async - syntax checkers as services - per language diff --git a/SQLiteStudio3/coreSQLiteStudio/common/global.h b/SQLiteStudio3/coreSQLiteStudio/common/global.h index bc228ca..b1f4b01 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/global.h +++ b/SQLiteStudio3/coreSQLiteStudio/common/global.h @@ -32,6 +32,13 @@ var = nullptr; \ } +#define qobject_safe_delete(var) \ + if (var) \ + { \ + var->deleteLater(); \ + var = nullptr; \ + } + #define static_char static constexpr const char #define static_qstring(N,V) const static QString N = QStringLiteral(V) diff --git a/SQLiteStudio3/coreSQLiteStudio/common/signalwait.cpp b/SQLiteStudio3/coreSQLiteStudio/common/signalwait.cpp new file mode 100644 index 0000000..90f9075 --- /dev/null +++ b/SQLiteStudio3/coreSQLiteStudio/common/signalwait.cpp @@ -0,0 +1,29 @@ +#include "signalwait.h" +#include <QCoreApplication> +#include <QTime> + +SignalWait::SignalWait(QObject* object, const char* signal) : + QObject() +{ + connect(object, signal, this, SLOT(handleSignal())); +} + +bool SignalWait::wait(int msTimeout) +{ + QTime timer(0, 0, 0, msTimeout); + timer.start(); + while (!called && timer.elapsed() < msTimeout) + qApp->processEvents(QEventLoop::ExcludeUserInputEvents); + + return called; +} + +void SignalWait::reset() +{ + called = false; +} + +void SignalWait::handleSignal() +{ + called = true; +} diff --git a/SQLiteStudio3/coreSQLiteStudio/common/signalwait.h b/SQLiteStudio3/coreSQLiteStudio/common/signalwait.h new file mode 100644 index 0000000..7b7b903 --- /dev/null +++ b/SQLiteStudio3/coreSQLiteStudio/common/signalwait.h @@ -0,0 +1,23 @@ +#ifndef SIGNALWAIT_H +#define SIGNALWAIT_H + +#include <QObject> + +class SignalWait : public QObject +{ + Q_OBJECT + + public: + SignalWait(QObject *object, const char *signal); + + bool wait(int msTimeout); + void reset(); + + private: + bool called = false; + + private slots: + void handleSignal(); +}; + +#endif // SIGNALWAIT_H diff --git a/SQLiteStudio3/coreSQLiteStudio/common/table.cpp b/SQLiteStudio3/coreSQLiteStudio/common/table.cpp index c590995..a9b0f16 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/table.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/common/table.cpp @@ -50,3 +50,43 @@ int qHash(Table table) {
return qHash(table.getDatabase() + "." + table.getTable());
}
+
+AliasedTable::AliasedTable()
+{
+}
+
+AliasedTable::AliasedTable(const QString& database, const QString& table, const QString& alias) :
+ Table(database, table)
+{
+ setTableAlias(alias);
+}
+
+AliasedTable::AliasedTable(const AliasedTable& other) :
+ Table(other.database, other.table)
+{
+ tableAlias = other.tableAlias;
+}
+
+AliasedTable::~AliasedTable()
+{
+}
+
+int AliasedTable::operator ==(const AliasedTable& other) const
+{
+ return other.database == this->database && other.table == this->table && other.tableAlias == this->tableAlias;
+}
+
+QString AliasedTable::getTableAlias() const
+{
+ return tableAlias;
+}
+
+void AliasedTable::setTableAlias(const QString& value)
+{
+ tableAlias = value;
+}
+
+int qHash(AliasedTable table)
+{
+ return qHash(table.getDatabase() + "." + table.getTable() + " " + table.getTableAlias());
+}
diff --git a/SQLiteStudio3/coreSQLiteStudio/common/table.h b/SQLiteStudio3/coreSQLiteStudio/common/table.h index d17a729..5cc4570 100644 --- a/SQLiteStudio3/coreSQLiteStudio/common/table.h +++ b/SQLiteStudio3/coreSQLiteStudio/common/table.h @@ -23,10 +23,27 @@ class API_EXPORT Table protected:
QString database;
QString table;
+};
+
+class API_EXPORT AliasedTable : public Table
+{
+ public:
+ AliasedTable();
+ AliasedTable(const QString& database, const QString& table, const QString& alias);
+ AliasedTable(const AliasedTable& other);
+ virtual ~AliasedTable();
+ int operator ==(const AliasedTable& other) const;
+
+ QString getTableAlias() const;
+ void setTableAlias(const QString& value);
+
+ protected:
+ QString tableAlias;
};
int API_EXPORT qHash(Table table);
+int API_EXPORT qHash(AliasedTable table);
#endif // TABLE_H
diff --git a/SQLiteStudio3/coreSQLiteStudio/coreSQLiteStudio.pro b/SQLiteStudio3/coreSQLiteStudio/coreSQLiteStudio.pro index 84cd818..0a7eb60 100644 --- a/SQLiteStudio3/coreSQLiteStudio/coreSQLiteStudio.pro +++ b/SQLiteStudio3/coreSQLiteStudio/coreSQLiteStudio.pro @@ -19,6 +19,7 @@ TEMPLATE = lib win32 { LIBS += -lpsapi $$PWD/../../../lib/libquazip.a + LIBS += -limagehlp THE_FILE = $$PWD/qt.conf THE_DEST = $${DESTDIR} @@ -215,7 +216,8 @@ SOURCES += sqlitestudio.cpp \ rsa/KeyPair.cpp \ rsa/PrimeGenerator.cpp \ rsa/RSA.cpp \ - translations.cpp + translations.cpp \ + common/signalwait.cpp HEADERS += sqlitestudio.h\ coreSQLiteStudio_global.h \ @@ -402,7 +404,8 @@ HEADERS += sqlitestudio.h\ rsa/KeyPair.h \ rsa/PrimeGenerator.h \ rsa/RSA.h \ - translations.h + translations.h \ + common/signalwait.h unix: { target.path = $$LIBDIR diff --git a/SQLiteStudio3/coreSQLiteStudio/coresqlitestudio.qrc b/SQLiteStudio3/coreSQLiteStudio/coresqlitestudio.qrc index 3ad28a9..7b814ec 100644 --- a/SQLiteStudio3/coreSQLiteStudio/coresqlitestudio.qrc +++ b/SQLiteStudio3/coreSQLiteStudio/coresqlitestudio.qrc @@ -22,5 +22,7 @@ <file>translations/coreSQLiteStudio_pl.qm</file> <file>translations/coreSQLiteStudio_ru.qm</file> <file>translations/coreSQLiteStudio_fr.qm</file> + <file>translations/coreSQLiteStudio_sk.qm</file> + <file>translations/coreSQLiteStudio_zh_CN.qm</file> </qresource> </RCC> diff --git a/SQLiteStudio3/coreSQLiteStudio/db/abstractdb.cpp b/SQLiteStudio3/coreSQLiteStudio/db/abstractdb.cpp index 4b3165b..68c6ad7 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/abstractdb.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/db/abstractdb.cpp @@ -177,22 +177,22 @@ ReadWriteLocker::Mode AbstractDb::getLockingMode(const QString &query, Flags fla return ReadWriteLocker::getMode(query, getDialect(), flags.testFlag(Flag::NO_LOCK)); } -QString AbstractDb::getName() +QString AbstractDb::getName() const { return name; } -QString AbstractDb::getPath() +QString AbstractDb::getPath() const { return path; } -quint8 AbstractDb::getVersion() +quint8 AbstractDb::getVersion() const { return version; } -Dialect AbstractDb::getDialect() +Dialect AbstractDb::getDialect() const { if (version == 2) return Dialect::Sqlite2; diff --git a/SQLiteStudio3/coreSQLiteStudio/db/abstractdb.h b/SQLiteStudio3/coreSQLiteStudio/db/abstractdb.h index 89edf03..3f2b4c0 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/abstractdb.h +++ b/SQLiteStudio3/coreSQLiteStudio/db/abstractdb.h @@ -45,10 +45,10 @@ class API_EXPORT AbstractDb : public Db virtual ~AbstractDb(); bool isOpen(); - QString getName(); - QString getPath(); - quint8 getVersion(); - Dialect getDialect(); + QString getName() const; + QString getPath() const; + quint8 getVersion() const; + Dialect getDialect() const; QString getEncoding(); QHash<QString,QVariant>& getConnectionOptions(); void setName(const QString& value); diff --git a/SQLiteStudio3/coreSQLiteStudio/db/abstractdb3.h b/SQLiteStudio3/coreSQLiteStudio/db/abstractdb3.h index 7a84ec2..9cb58aa 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/abstractdb3.h +++ b/SQLiteStudio3/coreSQLiteStudio/db/abstractdb3.h @@ -868,7 +868,8 @@ bool AbstractDb3<T>::Query::execInternal(const QList<QVariant>& args) if (res != T::OK) return false; - for (int paramIdx = 1; paramIdx <= queryWithParams.second; paramIdx++) + + for (int paramIdx = 1, argCount = args.size(); paramIdx <= queryWithParams.second && paramIdx <= argCount; paramIdx++) { res = bindParam(paramIdx, args[paramIdx-1]); if (res != T::OK) @@ -906,16 +907,25 @@ bool AbstractDb3<T>::Query::execInternal(const QHash<QString, QVariant>& args) if (res != T::OK) return false; - int paramIdx = 1; - foreach (const QString& paramName, queryWithParams.second) + int paramIdx = -1; + for (const QString& paramName : queryWithParams.second) { if (!args.contains(paramName)) { + qWarning() << "Could not bind parameter" << paramName << "because it was not found in passed arguments."; + setError(SqlErrorCode::OTHER_EXECUTION_ERROR, "Error while preparing statement: could not bind parameter " + paramName); + return false; + } + + paramIdx = T::bind_parameter_index(stmt, paramName.toUtf8().constData()); + if (paramIdx <= 0) + { + qWarning() << "Could not bind parameter" << paramName << "because it was not found in prepared statement."; setError(SqlErrorCode::OTHER_EXECUTION_ERROR, "Error while preparing statement: could not bind parameter " + paramName); return false; } - res = bindParam(paramIdx++, args[paramName]); + res = bindParam(paramIdx, args[paramName]); if (res != T::OK) { db->extractLastError(); diff --git a/SQLiteStudio3/coreSQLiteStudio/db/db.cpp b/SQLiteStudio3/coreSQLiteStudio/db/db.cpp index c89349c..7676f30 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/db.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/db/db.cpp @@ -1,5 +1,6 @@ #include "db.h" #include <QMetaEnum> +#include <QDebug> Db::Db() { @@ -55,3 +56,10 @@ void Sqlite2ColumnDataTypeHelper::clearBinaryTypes() { binaryColumns.clear(); } + + +QDebug operator<<(QDebug dbg, const Db* db) +{ + dbg.nospace() << "<DB:" << db->getName() << ">"; + return dbg.space(); +} diff --git a/SQLiteStudio3/coreSQLiteStudio/db/db.h b/SQLiteStudio3/coreSQLiteStudio/db/db.h index e11a844..efadd41 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/db.h +++ b/SQLiteStudio3/coreSQLiteStudio/db/db.h @@ -195,13 +195,13 @@ class API_EXPORT Db : public QObject, public Interruptable * @brief Gets database symbolic name. * @return Database symbolic name (as it was defined in call to DbManager#addDb() or DbManager#updateDb()). */ - virtual QString getName() = 0; + virtual QString getName() const = 0; /** * @brief Gets database file path. * @return Database file path (as it was defined in call to DbManager#addDb() or DbManager#updateDb()). */ - virtual QString getPath() = 0; + virtual QString getPath() const = 0; /** * @brief Gets SQLite version major number for this database. @@ -209,7 +209,7 @@ class API_EXPORT Db : public QObject, public Interruptable * * You don't have to open the database. This information is always available. */ - virtual quint8 getVersion() = 0; + virtual quint8 getVersion() const = 0; /** * @brief Gets database dialect. @@ -217,7 +217,7 @@ class API_EXPORT Db : public QObject, public Interruptable * * You don't have to open the database. This information is always available. */ - virtual Dialect getDialect() = 0; + virtual Dialect getDialect() const = 0; /** * @brief Gets database encoding. @@ -816,6 +816,8 @@ class API_EXPORT Db : public QObject, public Interruptable QDataStream &operator<<(QDataStream &out, const Db* myObj); QDataStream &operator>>(QDataStream &in, Db*& myObj); +QDebug operator<<(QDebug dbg, const Db* db); + Q_DECLARE_METATYPE(Db*) Q_DECLARE_OPERATORS_FOR_FLAGS(Db::Flags) diff --git a/SQLiteStudio3/coreSQLiteStudio/db/dbpluginoption.h b/SQLiteStudio3/coreSQLiteStudio/db/dbpluginoption.h index 7b594ef..e2ed66f 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/dbpluginoption.h +++ b/SQLiteStudio3/coreSQLiteStudio/db/dbpluginoption.h @@ -27,6 +27,11 @@ struct DbPluginOption { /** + * @brief Handler for custom path browser implemented by the plugin. + */ + typedef std::function<QString(const QString&)> CustomBrowseHandler; + + /** * @brief Option data type * * Determinates what kind of input widget will be added to DbDialog. @@ -39,7 +44,8 @@ struct DbPluginOption DOUBLE = 3, /**< QDoubleSpinBox will be added */ FILE = 4, /**< QLineEdit will be added */ PASSWORD = 5, /**< QLineEdit with value masking will be added */ - CHOICE = 6 /**< QComboBox will be added */ + CHOICE = 6, /**< QComboBox will be added */ + CUSTOM_PATH_BROWSE = 7 /**< File path browse button will be handled by the plugin. No additional editor will be added. */ }; /** @@ -92,6 +98,11 @@ struct DbPluginOption * @brief Expected data type for the option. */ Type type; + + /** + * @brief Handler for custom path browser implemented by the plugin. + */ + CustomBrowseHandler customBrowseHandler = nullptr; }; #endif // DBPLUGINOPTION_H diff --git a/SQLiteStudio3/coreSQLiteStudio/db/invaliddb.cpp b/SQLiteStudio3/coreSQLiteStudio/db/invaliddb.cpp index e4810a1..bdf3ef6 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/invaliddb.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/db/invaliddb.cpp @@ -12,22 +12,22 @@ bool InvalidDb::isOpen() return false; } -QString InvalidDb::getName() +QString InvalidDb::getName() const { return name; } -QString InvalidDb::getPath() +QString InvalidDb::getPath() const { return path; } -quint8 InvalidDb::getVersion() +quint8 InvalidDb::getVersion() const { return 0; } -Dialect InvalidDb::getDialect() +Dialect InvalidDb::getDialect() const { return Dialect::Sqlite3; } diff --git a/SQLiteStudio3/coreSQLiteStudio/db/invaliddb.h b/SQLiteStudio3/coreSQLiteStudio/db/invaliddb.h index 759aa4c..a9d58e0 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/invaliddb.h +++ b/SQLiteStudio3/coreSQLiteStudio/db/invaliddb.h @@ -9,10 +9,10 @@ class API_EXPORT InvalidDb : public Db InvalidDb(const QString& name, const QString& path, const QHash<QString, QVariant>& connOptions); bool isOpen(); - QString getName(); - QString getPath(); - quint8 getVersion(); - Dialect getDialect(); + QString getName() const; + QString getPath() const; + quint8 getVersion() const; + Dialect getDialect() const; QString getEncoding(); QHash<QString, QVariant>& getConnectionOptions(); void setName(const QString& value); diff --git a/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorcolumns.cpp b/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorcolumns.cpp index 6acfb6f..287a8ce 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorcolumns.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorcolumns.cpp @@ -40,14 +40,13 @@ bool QueryExecutorColumns::exec() core->resultColumns.clear(); // Count total rowId columns - int rowIdColCount = 0; for (const QueryExecutor::ResultRowIdColumnPtr& rowIdCol : context->rowIdColumns) - rowIdColCount += rowIdCol->queryExecutorAliasToColumn.size(); + rowIdColNames += rowIdCol->queryExecutorAliasToColumn.keys(); // Defining result columns QueryExecutor::ResultColumnPtr resultColumn; SqliteSelect::Core::ResultColumn* resultColumnForSelect = nullptr; - bool isRowIdColumn = false; + bool rowIdColumn = false; int i = 0; for (const SelectResolver::Column& col : columns) { @@ -55,15 +54,18 @@ bool QueryExecutorColumns::exec() resultColumn = getResultColumn(col); // Adding new result column to the query - isRowIdColumn = (i < rowIdColCount); - resultColumnForSelect = getResultColumnForSelect(resultColumn, col, isRowIdColumn); + rowIdColumn = isRowIdColumn(col.alias); + if (rowIdColumn && col.alias.contains(":")) + continue; // duplicate ROWID column provided by SelectResolver. See isRowIdColumn() for details. + + resultColumnForSelect = getResultColumnForSelect(resultColumn, col); if (!resultColumnForSelect) return false; resultColumnForSelect->setParent(core); core->resultColumns << resultColumnForSelect; - if (!isRowIdColumn) + if (!rowIdColumn) context->resultColumns << resultColumn; // store it in context for later usage by any step i++; @@ -89,7 +91,6 @@ QueryExecutor::ResultColumnPtr QueryExecutorColumns::getResultColumn(const Selec resultColumn->column = resolvedColumn.column; resultColumn->alias = resolvedColumn.alias; resultColumn->expression = true; - resultColumn->queryExecutorAlias = getNextColName(); } else { @@ -111,20 +112,20 @@ QueryExecutor::ResultColumnPtr QueryExecutorColumns::getResultColumn(const Selec resultColumn->tableAlias = resolvedColumn.tableAlias; resultColumn->alias = resolvedColumn.alias; resultColumn->displayName = resolvedColumn.displayName; + } - if (isRowIdColumnAlias(resultColumn->alias)) - { - resultColumn->queryExecutorAlias = resultColumn->alias; - } - else - { - resultColumn->queryExecutorAlias = getNextColName(); - } + if (isRowIdColumnAlias(resultColumn->alias)) + { + resultColumn->queryExecutorAlias = resultColumn->alias; + } + else + { + resultColumn->queryExecutorAlias = getNextColName(); } return resultColumn; } -SqliteSelect::Core::ResultColumn* QueryExecutorColumns::getResultColumnForSelect(const QueryExecutor::ResultColumnPtr& resultColumn, const SelectResolver::Column& col, bool rowIdColumn) +SqliteSelect::Core::ResultColumn* QueryExecutorColumns::getResultColumnForSelect(const QueryExecutor::ResultColumnPtr& resultColumn, const SelectResolver::Column& col) { SqliteSelect::Core::ResultColumn* selectResultColumn = new SqliteSelect::Core::ResultColumn(); @@ -164,28 +165,6 @@ SqliteSelect::Core::ResultColumn* QueryExecutorColumns::getResultColumnForSelect selectResultColumn->expr->table = resultColumn->table; } - -// // SQLite2 requires special treatment here. It won't allow selecting db.table.col from a subquery - it needs escaped ID that reflects db.table.col. -// if (dialect == Dialect::Sqlite2) -// { -// selectResultColumn->expr->rebuildTokens(); -// colString = wrapObjIfNeeded(selectResultColumn->expr->detokenize(), dialect); -// delete selectResultColumn->expr; -// selectResultColumn->expr = nullptr; - -// expr = parser.parseExpr(colString); -// if (!expr) -// { -// qWarning() << "Could not parse result column expr in SQLite2's second parsing phase:" << colString; -// if (parser.getErrors().size() > 0) -// qWarning() << "The error was:" << parser.getErrors().first()->getFrom() << ":" << parser.getErrors().first()->getMessage(); - -// return nullptr; -// } - -// expr->setParent(selectResultColumn); -// selectResultColumn->expr = expr; -// } } if (!col.alias.isNull()) @@ -193,7 +172,7 @@ SqliteSelect::Core::ResultColumn* QueryExecutorColumns::getResultColumnForSelect selectResultColumn->asKw = true; selectResultColumn->alias = col.alias; } - else if (rowIdColumn || resultColumn->expression) + else { selectResultColumn->asKw = true; selectResultColumn->alias = resultColumn->queryExecutorAlias; @@ -252,12 +231,10 @@ void QueryExecutorColumns::wrapWithAliasedColumns(SqliteSelect* select) // If alias was given, we use it. If it was anything but expression, we also use its display name, // because it's explicit column (no matter if from table, or table alias). baseColName = QString(); - if (!resCol->alias.isNull()) + if (!resCol->queryExecutorAlias.isNull()) baseColName = resCol->alias; - else if (dialect == Dialect::Sqlite3 && !resCol->expression) + else if (!resCol->expression) baseColName = resCol->column; - else if (dialect == Dialect::Sqlite2 && !resCol->expression) - baseColName = getAliasedColumnNameForSqlite2(resCol); if (!baseColName.isNull()) { @@ -279,20 +256,17 @@ void QueryExecutorColumns::wrapWithAliasedColumns(SqliteSelect* select) select->tokens = wrapSelect(select->tokens, outerColumns); } -QString QueryExecutorColumns::getAliasedColumnNameForSqlite2(const QueryExecutor::ResultColumnPtr& resCol) +bool QueryExecutorColumns::isRowIdColumn(const QString& columnAlias) { - QStringList colNameParts; - if (!resCol->table.isNull()) - { - if (!resCol->database.isNull()) - { - if (context->dbNameToAttach.containsLeft(resCol->database, Qt::CaseInsensitive)) - colNameParts << context->dbNameToAttach.valueByLeft(resCol->database, Qt::CaseInsensitive); - else - colNameParts << wrapObjIfNeeded(resCol->database, dialect); - } - colNameParts << wrapObjIfNeeded(resCol->table, dialect); - } - colNameParts << wrapObjIfNeeded(resCol->column, dialect); - return colNameParts.join("."); + // In case of "SELECT * FROM (SELECT * FROM test);" the SelectResolver will return ROWID columns twice for each table listed, + // because ROWID columns are recurrently handled by QueryExecutorAddRowIds step. We need to identify such columns and make them unique + // in the final query. + // Currently all columns have QueryExecutor aliased names, so we can assume they have unified alias name in form ResCol_N. + // If SelectResolver returns any column like ResCol_N:X, then it means that the column is result of the query like above. + // Note, that this assumption is correct for RowId columns. There can be columns aliased by user and those aliases won't be unified. + QString aliasOnly = columnAlias; + if (aliasOnly.contains(":")) + aliasOnly = aliasOnly.left(aliasOnly.indexOf(":")); + + return rowIdColNames.contains(aliasOnly); } diff --git a/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorcolumns.h b/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorcolumns.h index fd85651..e23b9f6 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorcolumns.h +++ b/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorcolumns.h @@ -50,7 +50,7 @@ class QueryExecutorColumns : public QueryExecutorStep * @param rowIdColumn Indicates if this is a call for ROWID column added by QueryExecutorRowId step. * @return Result column object ready for rebuilding tokens and detokenizing. */ - SqliteSelect::Core::ResultColumn* getResultColumnForSelect(const QueryExecutor::ResultColumnPtr& resultColumn, const SelectResolver::Column& col, bool rowIdColumn); + SqliteSelect::Core::ResultColumn* getResultColumnForSelect(const QueryExecutor::ResultColumnPtr& resultColumn, const SelectResolver::Column& col); /** * @brief Translates attach name into database name. @@ -67,8 +67,8 @@ class QueryExecutorColumns : public QueryExecutorStep bool isRowIdColumnAlias(const QString& alias); void wrapWithAliasedColumns(SqliteSelect* select); - - QString getAliasedColumnNameForSqlite2(const QueryExecutor::ResultColumnPtr& resCol); + bool isRowIdColumn(const QString& columnAlias); + QStringList rowIdColNames; }; #endif // QUERYEXECUTORCOLUMNS_H diff --git a/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorexecute.cpp b/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorexecute.cpp index f42f647..df2ed68 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorexecute.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/db/queryexecutorsteps/queryexecutorexecute.cpp @@ -8,6 +8,7 @@ #include <QDateTime> #include <QDebug> #include <schemaresolver.h> +#include <common/table.h> bool QueryExecutorExecute::exec() { @@ -120,17 +121,17 @@ void QueryExecutorExecute::setupSqlite2ColumnDataTypes(SqlQueryPtr results) if (!sqlite2Helper) return; - QPair<QString,QString> key; + Table key; SqliteCreateTablePtr createTable; SchemaResolver resolver(db); - QHash<QPair<QString,QString>,SqliteCreateTablePtr> tables; + QHash<Table,SqliteCreateTablePtr> tables; for (QueryExecutor::SourceTablePtr tab : context->sourceTables) { if (tab->table.isNull()) continue; - key = QPair<QString,QString>(tab->database, tab->table); + key = Table(tab->database, tab->table); createTable = resolver.getParsedObject(tab->database, tab->table, SchemaResolver::TABLE).dynamicCast<SqliteCreateTable>(); tables[key] = createTable; } @@ -142,7 +143,7 @@ void QueryExecutorExecute::setupSqlite2ColumnDataTypes(SqlQueryPtr results) for (QueryExecutor::ResultColumnPtr resCol : context->resultColumns) { idx++; - key = QPair<QString,QString>(resCol->database, resCol->table); + key = Table(resCol->database, resCol->table); if (!tables.contains(key)) continue; diff --git a/SQLiteStudio3/coreSQLiteStudio/db/stdsqlite3driver.h b/SQLiteStudio3/coreSQLiteStudio/db/stdsqlite3driver.h index eff3621..2f26aaf 100644 --- a/SQLiteStudio3/coreSQLiteStudio/db/stdsqlite3driver.h +++ b/SQLiteStudio3/coreSQLiteStudio/db/stdsqlite3driver.h @@ -41,6 +41,7 @@ static int bind_int(stmt* a1, int a2, int a3) {return Prefix##sqlite3_bind_int(a1, a2, a3);} \ static int bind_int64(stmt* a1, int a2, int64 a3) {return Prefix##sqlite3_bind_int64(a1, a2, a3);} \ static int bind_null(stmt* a1, int a2) {return Prefix##sqlite3_bind_null(a1, a2);} \ + static int bind_parameter_index(stmt* a1, const char* a2) {return Prefix##sqlite3_bind_parameter_index(a1, a2);} \ static int bind_text16(stmt* a1, int a2, const void* a3, int a4, void(*a5)(void*)) {return Prefix##sqlite3_bind_text16(a1, a2, a3, a4, a5);} \ static void result_blob(context* a1, const void* a2, int a3, void(*a4)(void*)) {Prefix##sqlite3_result_blob(a1, a2, a3, a4);} \ static void result_double(context* a1, double a2) {Prefix##sqlite3_result_double(a1, a2);} \ diff --git a/SQLiteStudio3/coreSQLiteStudio/exportworker.cpp b/SQLiteStudio3/coreSQLiteStudio/exportworker.cpp index b14bbf1..ffecd4d 100644 --- a/SQLiteStudio3/coreSQLiteStudio/exportworker.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/exportworker.cpp @@ -23,6 +23,7 @@ ExportWorker::~ExportWorker() void ExportWorker::run() { + qDebug() << "ExportWorker thread started. Export mode: " << static_cast<int>(exportMode); bool res = false; switch (exportMode) { @@ -109,39 +110,64 @@ bool ExportWorker::exportQueryResults() QHash<ExportManager::ExportProviderFlag,QVariant> providerData = getProviderDataForQueryResults(); if (results->isInterrupted()) + { + logExportFail("exportQueryResults() -> interrupted(1)"); return false; + } if (results->isError()) { + logExportFail("exportQueryResults() -> error"); notifyError(tr("Error while exporting query results: %1").arg(results->getErrorText())); return false; } if (!plugin->initBeforeExport(db, output, *config)) + { + logExportFail("initBeforeExport()"); return false; + } if (!plugin->beforeExportQueryResults(query, resultColumns, providerData)) + { + logExportFail("beforeExportQueryResults()"); return false; + } if (isInterrupted()) + { + logExportFail("exportQueryResults() -> interrupted(2)"); return false; + } SqlResultsRowPtr row; while (results->hasNext()) { row = results->next(); if (!plugin->exportQueryResultsRow(row)) + { + logExportFail("exportQueryResultsRow()"); return false; + } if (isInterrupted()) + { + logExportFail("exportQueryResults() -> interrupted(3)"); return false; + } } if (!plugin->afterExportQueryResults()) + { + logExportFail("afterExportQueryResults()"); return false; + } if (!plugin->afterExport()) + { + logExportFail("afterExport()"); return false; + } return true; } @@ -192,18 +218,28 @@ bool ExportWorker::exportDatabase() QList<ExportManager::ExportObjectPtr> dbObjects = collectDbObjects(&err); if (!err.isNull()) { + logExportFail("exportDatabase() -> dbObjects"); notifyError(err); return false; } if (!plugin->initBeforeExport(db, output, *config)) + { + logExportFail("initBeforeExport()"); return false; + } if (!plugin->beforeExportDatabase(db->getName())) + { + logExportFail("beforeExportDatabase()"); return false; + } if (isInterrupted()) + { + logExportFail("exportDatabase() -> interrupted(1)"); return false; + } QList<ExportManager::ExportObject::Type> order = { ExportManager::ExportObject::TABLE, ExportManager::ExportObject::INDEX, ExportManager::ExportObject::TRIGGER, ExportManager::ExportObject::VIEW @@ -215,46 +251,88 @@ bool ExportWorker::exportDatabase() }); if (!plugin->beforeExportTables()) + { + logExportFail("beforeExportTables()"); return false; + } if (!exportDatabaseObjects(dbObjects, ExportManager::ExportObject::TABLE)) + { + logExportFail("exportDatabaseObjects()"); return false; + } if (!plugin->afterExportTables()) + { + logExportFail("afterExportTables()"); return false; + } if (!plugin->beforeExportIndexes()) + { + logExportFail("beforeExportIndexes()"); return false; + } if (!exportDatabaseObjects(dbObjects, ExportManager::ExportObject::INDEX)) + { + logExportFail("exportDatabaseObjects()"); return false; + } if (!plugin->afterExportIndexes()) + { + logExportFail("afterExportIndexes()"); return false; + } if (!plugin->beforeExportTriggers()) + { + logExportFail("beforeExportTriggers()"); return false; + } if (!exportDatabaseObjects(dbObjects, ExportManager::ExportObject::TRIGGER)) + { + logExportFail("exportDatabaseObjects()"); return false; + } if (!plugin->afterExportTriggers()) + { + logExportFail("afterExportTriggers()"); return false; + } if (!plugin->beforeExportViews()) + { + logExportFail("beforeExportViews()"); return false; + } if (!exportDatabaseObjects(dbObjects, ExportManager::ExportObject::VIEW)) + { + logExportFail("exportDatabaseObjects()"); return false; + } if (!plugin->afterExportViews()) + { + logExportFail("afterExportViews()"); return false; + } if (!plugin->afterExportDatabase()) + { + logExportFail("afterExportDatabase()"); return false; + } if (!plugin->afterExport()) + { + logExportFail("afterExport()"); return false; + } return true; } @@ -297,10 +375,16 @@ bool ExportWorker::exportDatabaseObjects(const QList<ExportManager::ExportObject } if (!res) + { + logExportFail("database objects export " + obj->name); return false; + } if (isInterrupted()) + { + logExportFail("database objects export (interrupted)"); return false; + } } return true; } @@ -313,6 +397,7 @@ bool ExportWorker::exportTable() queryTableDataToExport(db, table, results, providerData, &errorMessage); if (!errorMessage.isNull()) { + logExportFail("fetching table data"); notifyError(errorMessage); return false; } @@ -329,45 +414,72 @@ bool ExportWorker::exportTable() SqliteQueryPtr createTable = parser->getQueries().first(); if (!plugin->initBeforeExport(db, output, *config)) + { + logExportFail("initBeforeExport()"); return false; + } if (!exportTableInternal(database, table, ddl, createTable, results, providerData)) + { + logExportFail("exportTableInternal()"); return false; + } if (config->exportTableIndexes) { if (!plugin->beforeExportIndexes()) + { + logExportFail("beforeExportIndexes()"); return false; + } QList<SqliteCreateIndexPtr> parsedIndexesForTable = resolver.getParsedIndexesForTable(database, table); for (const SqliteCreateIndexPtr& idx : parsedIndexesForTable) { if (!plugin->exportIndex(database, idx->index, idx->detokenize(), idx)) + { + logExportFail("exportIndex()"); return false; + } } if (!plugin->afterExportIndexes()) + { + logExportFail("afterExportIndexes()"); return false; + } } if (config->exportTableTriggers) { if (!plugin->beforeExportTriggers()) + { + logExportFail("beforeExportTriggers()"); return false; + } QList<SqliteCreateTriggerPtr> parsedTriggersForTable = resolver.getParsedTriggersForTable(database, table); for (const SqliteCreateTriggerPtr& trig : parsedTriggersForTable) { if (!plugin->exportTrigger(database, trig->trigger, trig->detokenize(), trig)) + { + logExportFail("exportTrigger()"); return false; + } } if (!plugin->afterExportTriggers()) + { + logExportFail("afterExportTriggers()"); return false; + } } if (!plugin->afterExport()) + { + logExportFail("afterExport()"); return false; + } return true; } @@ -388,16 +500,25 @@ bool ExportWorker::exportTableInternal(const QString& database, const QString& t colNames = createTable->getColumnNames(); if (!plugin->exportTable(database, table, colNames, ddl, createTable, providerData)) + { + logExportFail("exportTable()"); return false; + } } else { if (!plugin->exportVirtualTable(database, table, colNames, ddl, createVirtualTable, providerData)) + { + logExportFail("exportVirtualTable()"); return false; + } } if (isInterrupted()) + { + logExportFail("internal table export interruption"); return false; + } SqlResultsRowPtr row; if (results) @@ -406,15 +527,24 @@ bool ExportWorker::exportTableInternal(const QString& database, const QString& t { row = results->next(); if (!plugin->exportTableRow(row)) + { + logExportFail("exportTableRow()"); return false; + } if (isInterrupted()) + { + logExportFail("internal table export interruption (2)"); return false; + } } } if (!plugin->afterExportTable()) + { + logExportFail("afterExportTable()"); return false; + } return true; } @@ -478,7 +608,7 @@ void ExportWorker::queryTableDataToExport(Db* db, const QString& table, SqlQuery { QString wrappedTable = wrapObjIfNeeded(table, db->getDialect()); dataPtr = db->exec(sql.arg(wrappedTable)); - if (dataPtr->isError()) + if (dataPtr->isError() && !errorMessage->isNull()) *errorMessage = tr("Error while reading data to export from table %1: %2").arg(table, dataPtr->getErrorText()); if (plugin->getProviderFlags().testFlag(ExportManager::ROW_COUNT)) @@ -486,8 +616,8 @@ void ExportWorker::queryTableDataToExport(Db* db, const QString& table, SqlQuery SqlQueryPtr countQuery = db->exec(countSql.arg(wrappedTable)); if (countQuery->isError()) { - if (errorMessage->isNull()) - *errorMessage = tr("Error while counting data to export from table %1: %2").arg(table, dataPtr->getErrorText()); + if (!errorMessage->isNull()) + *errorMessage = tr("Error while counting data to export from table %1: %2").arg(table, countQuery->getErrorText()); } else providerData[ExportManager::ROW_COUNT] = countQuery->getSingleCell().toInt(); @@ -502,8 +632,8 @@ void ExportWorker::queryTableDataToExport(Db* db, const QString& table, SqlQuery SqlQueryPtr colLengthQuery = db->exec(colLengthSql.arg(wrappedCols.join(", "), wrappedTable)); if (colLengthQuery->isError()) { - if (errorMessage->isNull()) - *errorMessage = tr("Error while counting data column width to export from table %1: %2").arg(table, dataPtr->getErrorText()); + if (!errorMessage->isNull()) + *errorMessage = tr("Error while counting data column width to export from table %1: %2").arg(table, colLengthQuery->getErrorText()); } else { @@ -523,3 +653,8 @@ bool ExportWorker::isInterrupted() return interrupted; } +void ExportWorker::logExportFail(const QString &stageName) +{ + qWarning() << "Export has faild at" << stageName << "stage."; +} + diff --git a/SQLiteStudio3/coreSQLiteStudio/exportworker.h b/SQLiteStudio3/coreSQLiteStudio/exportworker.h index 27620a4..5e8bef3 100644 --- a/SQLiteStudio3/coreSQLiteStudio/exportworker.h +++ b/SQLiteStudio3/coreSQLiteStudio/exportworker.h @@ -35,6 +35,7 @@ class API_EXPORT ExportWorker : public QObject, public QRunnable void queryTableDataToExport(Db* db, const QString& table, SqlQueryPtr& dataPtr, QHash<ExportManager::ExportProviderFlag, QVariant>& providerData, QString* errorMessage) const; bool isInterrupted(); + void logExportFail(const QString& stageName); ExportPlugin* plugin = nullptr; ExportManager::StandardExportConfig* config = nullptr; diff --git a/SQLiteStudio3/coreSQLiteStudio/importworker.cpp b/SQLiteStudio3/coreSQLiteStudio/importworker.cpp index af4a66d..2cdeeb0 100644 --- a/SQLiteStudio3/coreSQLiteStudio/importworker.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/importworker.cpp @@ -149,8 +149,19 @@ bool ImportWorker::importData() query->setArgs(row.mid(0, colCount)); if (!query->execute()) { - error(tr("Error while importing data: %1").arg(query->getErrorText())); - return false; + if (config->ignoreErrors) + { + qDebug() << "Could not import data row number" << (rowCnt+1) << ". The row was ignored. Problem details:" + << query->getErrorText(); + + notifyWarn(tr("Could not import data row number %1. The row was ignored. Problem details: %2") + .arg(QString::number(rowCnt + 1), query->getErrorText())); + } + else + { + error(tr("Error while importing data: %1").arg(query->getErrorText())); + return false; + } } if ((rowCnt % 100) == 0 && isInterrupted()) diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.cpp index 6c840e7..49763a5 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitealtertable.cpp @@ -102,7 +102,7 @@ void SqliteAlterTable::initName(const QString &name1, const QString &name2) TokenList SqliteAlterTable::rebuildTokensFromContents() { StatementTokenBuilder builder; - + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); builder.withKeyword("ALTER").withSpace().withKeyword("TABLE").withSpace(); if (!database.isNull()) diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteanalyze.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteanalyze.cpp index d4e5778..30396c1 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteanalyze.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteanalyze.cpp @@ -69,7 +69,7 @@ QList<SqliteStatement::FullObject> SqliteAnalyze::getFullObjectsInStatement() TokenList SqliteAnalyze::rebuildTokensFromContents() { StatementTokenBuilder builder; - + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); builder.withKeyword("ANALYZE").withSpace(); if (!database.isNull()) diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteattach.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteattach.cpp index 7d0b8a5..359396b 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteattach.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteattach.cpp @@ -47,7 +47,7 @@ SqliteStatement* SqliteAttach::clone() TokenList SqliteAttach::rebuildTokensFromContents() { StatementTokenBuilder builder; - + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); builder.withKeyword("ATTACH").withSpace(); if (databaseKw) diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitebegintrans.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitebegintrans.cpp index dcd9740..00ec9ac 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitebegintrans.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitebegintrans.cpp @@ -52,7 +52,7 @@ QString SqliteBeginTrans::typeToString(SqliteBeginTrans::Type type) TokenList SqliteBeginTrans::rebuildTokensFromContents() { StatementTokenBuilder builder; - + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); builder.withKeyword("BEGIN"); if (type != Type::null) diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecommittrans.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecommittrans.cpp index 97be8a9..2b1b707 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecommittrans.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecommittrans.cpp @@ -29,7 +29,7 @@ SqliteStatement* SqliteCommitTrans::clone() TokenList SqliteCommitTrans::rebuildTokensFromContents() { StatementTokenBuilder builder; - + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); if (endKw) builder.withKeyword("END"); else diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecopy.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecopy.cpp index 009f836..0d9ed9f 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecopy.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecopy.cpp @@ -73,7 +73,7 @@ QList<SqliteStatement::FullObject> SqliteCopy::getFullObjectsInStatement() TokenList SqliteCopy::rebuildTokensFromContents() { StatementTokenBuilder builder; - + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); builder.withKeyword("COPY").withSpace(); if (onConflict != SqliteConflictAlgo::null) builder.withKeyword("OR").withSpace().withKeyword(sqliteConflictAlgo(onConflict)).withSpace(); diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.cpp index 36f7aa9..16cec8f 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateindex.cpp @@ -149,6 +149,7 @@ QList<SqliteStatement::FullObject> SqliteCreateIndex::getFullObjectsInStatement( TokenList SqliteCreateIndex::rebuildTokensFromContents() { StatementTokenBuilder builder; + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); builder.withKeyword("CREATE").withSpace(); if (uniqueKw) builder.withKeyword("UNIQUE").withSpace(); diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.cpp index e31e512..454c0e3 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetable.cpp @@ -208,7 +208,7 @@ QList<SqliteStatement::FullObject> SqliteCreateTable::getFullObjectsInStatement( TokenList SqliteCreateTable::rebuildTokensFromContents() { StatementTokenBuilder builder; - + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); builder.withKeyword("CREATE"); if (tempKw) builder.withSpace().withKeyword("TEMP"); @@ -706,7 +706,6 @@ TokenList SqliteCreateTable::Column::rebuildTokensFromContents() TokenList SqliteCreateTable::Column::Constraint::rebuildTokensFromContents() { StatementTokenBuilder builder; - if (!name.isNull()) builder.withKeyword("CONSTRAINT").withSpace().withOther(name, dialect).withSpace(); diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.cpp index 3b7b0ea..8f67aea 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatetrigger.cpp @@ -322,7 +322,7 @@ SqliteCreateTrigger::Event::Type SqliteCreateTrigger::Event::stringToType(const TokenList SqliteCreateTrigger::rebuildTokensFromContents() { StatementTokenBuilder builder; - + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); builder.withKeyword("CREATE").withSpace(); if (tempKw) builder.withKeyword("TEMP").withSpace(); diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.cpp index 6b11c3c..d1a8961 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreateview.cpp @@ -98,7 +98,7 @@ QList<SqliteStatement::FullObject> SqliteCreateView::getFullObjectsInStatement() TokenList SqliteCreateView::rebuildTokensFromContents() { StatementTokenBuilder builder; - + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); builder.withKeyword("CREATE").withSpace(); if (tempKw) builder.withKeyword("TEMP").withSpace(); diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatevirtualtable.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatevirtualtable.cpp index bc38dc9..1d98c8d 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatevirtualtable.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitecreatevirtualtable.cpp @@ -91,7 +91,7 @@ void SqliteCreateVirtualTable::initName(const QString &name1, const QString &nam TokenList SqliteCreateVirtualTable::rebuildTokensFromContents() { StatementTokenBuilder builder; - + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); builder.withKeyword("CREATE").withSpace().withKeyword("VIRTUAL").withSpace().withKeyword("TABLE"); if (ifNotExistsKw) builder.withKeyword("IF").withSpace().withKeyword("NOT").withSpace().withKeyword("EXISTS").withSpace(); diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.cpp index 60e5878..6026de3 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedelete.cpp @@ -113,7 +113,7 @@ void SqliteDelete::init(const QString &name1, const QString &name2, SqliteExpr * TokenList SqliteDelete::rebuildTokensFromContents() { StatementTokenBuilder builder; - + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); if (with) builder.withStatement(with); diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedetach.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedetach.cpp index 1f874d3..e5b59e3 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedetach.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedetach.cpp @@ -36,7 +36,7 @@ SqliteStatement*SqliteDetach::clone() TokenList SqliteDetach::rebuildTokensFromContents() { StatementTokenBuilder builder; - + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); builder.withKeyword("DETACH").withSpace(); if (databaseKw) diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropindex.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropindex.cpp index df924fe..2e39312 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropindex.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropindex.cpp @@ -63,7 +63,7 @@ QList<SqliteStatement::FullObject> SqliteDropIndex::getFullObjectsInStatement() TokenList SqliteDropIndex::rebuildTokensFromContents() { StatementTokenBuilder builder; - + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); builder.withKeyword("DROP").withSpace().withKeyword("INDEX").withSpace(); if (ifExistsKw) diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptable.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptable.cpp index 9c4aa37..c4fc02d 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptable.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptable.cpp @@ -71,7 +71,7 @@ QList<SqliteStatement::FullObject> SqliteDropTable::getFullObjectsInStatement() TokenList SqliteDropTable::rebuildTokensFromContents() { StatementTokenBuilder builder; - + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); builder.withKeyword("DROP").withSpace().withKeyword("TABLE").withSpace(); if (ifExistsKw) diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptrigger.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptrigger.cpp index 471d558..8921af3 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptrigger.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedroptrigger.cpp @@ -64,7 +64,7 @@ QList<SqliteStatement::FullObject> SqliteDropTrigger::getFullObjectsInStatement( TokenList SqliteDropTrigger::rebuildTokensFromContents() { StatementTokenBuilder builder; - + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); builder.withKeyword("DROP").withSpace().withKeyword("TRIGGER").withSpace(); if (ifExistsKw) diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropview.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropview.cpp index 06d70db..b992e98 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropview.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitedropview.cpp @@ -70,7 +70,7 @@ QList<SqliteStatement::FullObject> SqliteDropView::getFullObjectsInStatement() TokenList SqliteDropView::rebuildTokensFromContents() { StatementTokenBuilder builder; - + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); builder.withKeyword("DROP").withSpace().withKeyword("VIEW").withSpace(); if (ifExistsKw) diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.cpp index 6c26e8d..cb85377 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteinsert.cpp @@ -167,7 +167,7 @@ void SqliteInsert::initMode(bool replace, SqliteConflictAlgo onConflict) TokenList SqliteInsert::rebuildTokensFromContents() { StatementTokenBuilder builder; - + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); if (with) builder.withStatement(with); diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitepragma.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitepragma.cpp index 0e4f056..4660e4f 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitepragma.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitepragma.cpp @@ -90,7 +90,7 @@ void SqlitePragma::initName(const QString &name1, const QString &name2) TokenList SqlitePragma::rebuildTokensFromContents() { StatementTokenBuilder builder; - + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); builder.withKeyword("PRAGMA").withSpace(); if (!database.isNull()) diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitequery.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitequery.cpp index 19c3c40..02eff1d 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitequery.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitequery.cpp @@ -1,4 +1,5 @@ #include "sqlitequery.h" +#include "parser/statementtokenbuilder.h" SqliteQuery::SqliteQuery() { @@ -49,3 +50,15 @@ bool SqliteQuery::isReadOnly() } return readOnly; } + +TokenList SqliteQuery::rebuildTokensFromContents() +{ + StatementTokenBuilder builder; + if (explain) + { + builder.withKeyword("EXPLAIN").withSpace(); + if (queryPlan) + builder.withKeyword("QUERY").withSpace().withKeyword("PLAN").withSpace(); + } + return builder.build(); +} diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitequery.h b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitequery.h index 1667dc9..787ccb9 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitequery.h +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitequery.h @@ -20,6 +20,9 @@ class API_EXPORT SqliteQuery : public SqliteStatement bool explain = false; bool queryPlan = false; + + protected: + TokenList rebuildTokensFromContents(); }; /** diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitereindex.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitereindex.cpp index 7584a37..6f863f9 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitereindex.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitereindex.cpp @@ -71,7 +71,7 @@ QList<SqliteStatement::FullObject> SqliteReindex::getFullObjectsInStatement() TokenList SqliteReindex::rebuildTokensFromContents() { StatementTokenBuilder builder; - + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); builder.withKeyword("REINDEX"); if (!database.isNull()) builder.withOther(database, dialect).withOperator("."); diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterelease.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterelease.cpp index 8510524..f71d61c 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterelease.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterelease.cpp @@ -28,7 +28,7 @@ SqliteStatement*SqliteRelease::clone() TokenList SqliteRelease::rebuildTokensFromContents() { StatementTokenBuilder builder; - + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); builder.withKeyword("RELEASE").withSpace(); if (savepointKw) builder.withKeyword("SAVEPOINT").withSpace(); diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterollback.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterollback.cpp index a13fd4c..01284b4 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterollback.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliterollback.cpp @@ -38,7 +38,7 @@ SqliteStatement*SqliteRollback::clone() TokenList SqliteRollback::rebuildTokensFromContents() { StatementTokenBuilder builder; - + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); builder.withKeyword("ROLLBACK").withSpace(); if (transactionKw) builder.withKeyword("TRANSACTION").withSpace(); diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitesavepoint.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitesavepoint.cpp index 9003086..1ac50cd 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitesavepoint.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitesavepoint.cpp @@ -27,6 +27,7 @@ SqliteStatement*SqliteSavepoint::clone() TokenList SqliteSavepoint::rebuildTokensFromContents() { StatementTokenBuilder builder; + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); builder.withKeyword("SAVEPOINT").withSpace().withOther(name, dialect).withOperator(";"); return builder.build(); } diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.cpp index 5452795..f1b1929 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteselect.cpp @@ -759,6 +759,7 @@ TokenList SqliteSelect::Core::rebuildTokensFromContents() TokenList SqliteSelect::rebuildTokensFromContents() { StatementTokenBuilder builder; + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); if (with) builder.withStatement(with); diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.cpp index 88ac28b..df892fb 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqliteupdate.cpp @@ -168,7 +168,7 @@ QList<SqliteStatement::FullObject> SqliteUpdate::getFullObjectsInStatement() TokenList SqliteUpdate::rebuildTokensFromContents() { StatementTokenBuilder builder; - + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); if (with) builder.withStatement(with); diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitevacuum.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitevacuum.cpp index ab7d00e..96ff7a4 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitevacuum.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/ast/sqlitevacuum.cpp @@ -51,6 +51,7 @@ QList<SqliteStatement::FullObject> SqliteVacuum::getFullObjectsInStatement() TokenList SqliteVacuum::rebuildTokensFromContents() { StatementTokenBuilder builder; + builder.withTokens(SqliteQuery::rebuildTokensFromContents()); builder.withKeyword("VACUUM").withOperator(";"); return builder.build(); } diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/parsercontext.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/parsercontext.cpp index e9444e5..7f8ad7a 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/parsercontext.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/parsercontext.cpp @@ -164,6 +164,36 @@ const QList<ParserError *> &ParserContext::getErrors() return errors; } +QVariant *ParserContext::handleNumberToken(const QString &tokenValue) +{ + recentNumberIsCandidateForMaxNegative = false; + if (tokenValue.startsWith("0x", Qt::CaseInsensitive)) + { + bool ok; + qint64 i64 = tokenValue.toLongLong(&ok, 16); + if (!ok) + { + quint64 ui64 = tokenValue.toULongLong(&ok, 16); + i64 = static_cast<qint64>(ui64); + } + return new QVariant(i64); + } + else if (tokenValue == "9223372036854775808") // max negative longlong value, but without a sign + { + recentNumberIsCandidateForMaxNegative = true; + return new QVariant(static_cast<qint64>(0L)); + } + else + { + return new QVariant(QVariant(tokenValue).toLongLong()); + } +} + +bool ParserContext::isCandidateForMaxNegativeNumber() const +{ + return recentNumberIsCandidateForMaxNegative; +} + void ParserContext::cleanUp() { foreach (ParserError* err, errors) diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/parsercontext.h b/SQLiteStudio3/coreSQLiteStudio/parser/parsercontext.h index d52c021..64ce3a3 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/parsercontext.h +++ b/SQLiteStudio3/coreSQLiteStudio/parser/parsercontext.h @@ -187,6 +187,9 @@ class ParserContext */ const QList<ParserError*>& getErrors(); + QVariant* handleNumberToken(const QString& tokenValue); + bool isCandidateForMaxNegativeNumber() const; + /** * @brief Flag indicating if the Lemon parser should setup token collections. * @@ -284,6 +287,18 @@ class ParserContext * Defined by errorBeforeNextToken() and minorErrorBeforeNextToken(). */ QString nextTokenError; + + /** + * @brief Indicates that the number value is 1 over the max longlong value. + * + * Then the positive number is over max longlong by 1, then this is a candidate + * for max negative longlong value, but this is to be identified in the next parser reduce level. + * + * Because of that this flag is set to false by default each time the number is parsed and is set afterwards + * to true each timethe value is 1 over max longlong. This way if the 'term' rule includes 'minus' token, + * then it will be properly converted to max negative longlong. + */ + bool recentNumberIsCandidateForMaxNegative = false; }; #endif // PARSERCONTEXT_H diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/sqlite2_parse.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/sqlite2_parse.cpp index 5b65904..ffc1fab 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/sqlite2_parse.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/sqlite2_parse.cpp @@ -3832,7 +3832,7 @@ static void yy_reduce( case 250: /* exprx ::= expr not_opt IN nm dbnm */ { yygotominor.yy192 = new SqliteExpr(); - yygotominor.yy192->initIn(yymsp[-4].minor.yy192, yymsp[-3].minor.yy291, *(yymsp[-1].minor.yy319), *(yymsp[0].minor.yy319)); + yygotominor.yy192->initIn(yymsp[-4].minor.yy192, *(yymsp[-3].minor.yy291), *(yymsp[-1].minor.yy319), *(yymsp[0].minor.yy319)); delete yymsp[-3].minor.yy291; delete yymsp[-1].minor.yy319; objectForTokens = yygotominor.yy192; diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/sqlite2_parse.y b/SQLiteStudio3/coreSQLiteStudio/parser/sqlite2_parse.y index d6ee4f7..472725e 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/sqlite2_parse.y +++ b/SQLiteStudio3/coreSQLiteStudio/parser/sqlite2_parse.y @@ -1513,7 +1513,7 @@ exprx(X) ::= expr(E) not_opt(N) IN LP exprx(X) ::= expr(E) not_opt(N) IN nm(N1) dbnm(N2). [IN] { X = new SqliteExpr(); - X->initIn(E, N, *(N1), *(N2)); + X->initIn(E, *(N), *(N1), *(N2)); delete N; delete N1; objectForTokens = X; diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/sqlite3_parse.cpp b/SQLiteStudio3/coreSQLiteStudio/parser/sqlite3_parse.cpp index 646c533..fa8a9d1 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/sqlite3_parse.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/parser/sqlite3_parse.cpp @@ -51,6 +51,7 @@ #include "parser/ast/sqlitewith.h" #include <QObject> #include <QDebug> +#include <limits.h> #define assert(X) Q_ASSERT(X) #define UNUSED_PARAMETER(X) (void)(X) @@ -242,7 +243,7 @@ static const YYMINORTYPE yyzerominor = { 0 }; ** shifting non-terminals after a reduce. ** yy_default[] Default action for each state. */ -#define YY_ACTTAB_COUNT (2282) +#define YY_ACTTAB_COUNT (2263) 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, @@ -413,66 +414,64 @@ static const YYACTIONTYPE yy_action[] = { /* 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, 286, 337, 714, - /* 1700 */ 713, 686, 190, 714, 713, 621, 287, 72, 430, 428, - /* 1710 */ 715, 428, 436, 685, 209, 558, 686, 188, 41, 715, - /* 1720 */ 567, 287, 430, 642, 430, 676, 9, 642, 716, 96, - /* 1730 */ 686, 196, 686, 195, 715, 38, 39, 641, 716, 283, - /* 1740 */ 431, 327, 40, 716, 207, 428, 203, 319, 150, 428, - /* 1750 */ 4, 425, 715, 318, 641, 642, 325, 422, 430, 716, - /* 1760 */ 687, 429, 430, 719, 716, 690, 686, 197, 709, 641, - /* 1770 */ 686, 201, 642, 689, 688, 687, 428, 224, 411, 716, - /* 1780 */ 261, 716, 86, 641, 221, 641, 708, 651, 258, 430, - /* 1790 */ 428, 695, 220, 715, 428, 685, 420, 686, 232, 227, - /* 1800 */ 41, 715, 651, 430, 715, 433, 642, 430, 676, 9, - /* 1810 */ 642, 686, 290, 428, 707, 686, 191, 38, 39, 641, - /* 1820 */ 149, 147, 431, 641, 40, 257, 430, 82, 432, 256, - /* 1830 */ 714, 713, 4, 425, 686, 194, 679, 642, 715, 422, - /* 1840 */ 714, 713, 714, 429, 716, 714, 713, 690, 716, 715, - /* 1850 */ 641, 367, 428, 15, 642, 689, 688, 687, 428, 684, - /* 1860 */ 411, 714, 713, 700, 641, 430, 714, 713, 641, 145, - /* 1870 */ 17, 430, 476, 686, 193, 234, 521, 685, 294, 686, - /* 1880 */ 185, 714, 713, 714, 713, 293, 400, 641, 642, 428, - /* 1890 */ 676, 9, 642, 541, 428, 502, 292, 28, 529, 38, - /* 1900 */ 39, 474, 430, 291, 248, 408, 40, 430, 481, 428, - /* 1910 */ 686, 189, 55, 683, 4, 686, 314, 715, 715, 642, - /* 1920 */ 428, 422, 430, 463, 687, 429, 641, 428, 716, 690, - /* 1930 */ 686, 313, 641, 430, 402, 216, 642, 689, 688, 687, - /* 1940 */ 430, 686, 312, 428, 536, 428, 714, 713, 686, 184, - /* 1950 */ 714, 713, 43, 640, 419, 66, 430, 229, 430, 214, - /* 1960 */ 415, 228, 34, 641, 686, 171, 686, 170, 641, 637, - /* 1970 */ 642, 635, 676, 9, 642, 428, 141, 626, 428, 622, - /* 1980 */ 246, 139, 715, 641, 477, 428, 108, 389, 430, 428, - /* 1990 */ 715, 430, 715, 715, 641, 386, 686, 183, 430, 686, - /* 2000 */ 169, 641, 430, 380, 577, 471, 686, 186, 617, 244, - /* 2010 */ 686, 168, 428, 473, 133, 428, 242, 641, 330, 641, - /* 2020 */ 470, 715, 715, 583, 578, 430, 277, 715, 430, 715, - /* 2030 */ 714, 713, 428, 686, 167, 428, 686, 93, 574, 716, - /* 2040 */ 535, 573, 443, 572, 716, 430, 547, 128, 430, 641, - /* 2050 */ 310, 428, 641, 686, 166, 428, 686, 164, 428, 641, - /* 2060 */ 716, 236, 716, 641, 430, 322, 546, 716, 430, 428, - /* 2070 */ 393, 430, 686, 174, 715, 554, 686, 173, 309, 686, - /* 2080 */ 175, 716, 430, 715, 716, 275, 641, 716, 545, 641, - /* 2090 */ 686, 178, 428, 80, 428, 568, 716, 428, 715, 428, - /* 2100 */ 544, 716, 127, 106, 716, 430, 641, 430, 715, 641, - /* 2110 */ 430, 549, 430, 686, 94, 686, 177, 428, 686, 176, - /* 2120 */ 686, 180, 269, 428, 715, 641, 212, 392, 126, 641, - /* 2130 */ 430, 354, 641, 262, 24, 715, 430, 526, 686, 179, - /* 2140 */ 430, 714, 713, 641, 686, 165, 714, 713, 686, 70, - /* 2150 */ 124, 363, 78, 527, 123, 105, 121, 155, 523, 513, - /* 2160 */ 84, 104, 714, 713, 714, 713, 641, 348, 641, 714, - /* 2170 */ 713, 641, 263, 641, 518, 360, 492, 489, 120, 493, - /* 2180 */ 441, 480, 103, 714, 713, 715, 714, 713, 715, 714, - /* 2190 */ 713, 641, 648, 118, 345, 347, 76, 641, 714, 713, - /* 2200 */ 442, 641, 343, 714, 713, 427, 714, 713, 715, 284, - /* 2210 */ 264, 253, 117, 715, 250, 241, 75, 116, 715, 115, - /* 2220 */ 237, 74, 715, 715, 715, 73, 238, 715, 715, 114, - /* 2230 */ 323, 113, 23, 715, 451, 652, 20, 449, 101, 715, - /* 2240 */ 100, 445, 112, 61, 439, 162, 295, 669, 655, 623, - /* 2250 */ 412, 665, 520, 628, 618, 278, 569, 260, 198, 361, - /* 2260 */ 305, 374, 681, 522, 664, 6, 654, 556, 211, 45, - /* 2270 */ 364, 487, 566, 560, 296, 559, 409, 81, 71, 587, - /* 2280 */ 586, 550, + /* 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, }; static const YYCODETYPE yy_lookahead[] = { /* 0 */ 4, 81, 82, 83, 84, 85, 86, 87, 4, 58, @@ -644,107 +643,105 @@ static const YYCODETYPE yy_lookahead[] = { /* 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, 177, 37, 106, - /* 1700 */ 107, 198, 199, 106, 107, 141, 177, 95, 190, 177, - /* 1710 */ 190, 177, 36, 59, 252, 118, 198, 199, 64, 190, - /* 1720 */ 127, 177, 190, 152, 190, 154, 155, 156, 4, 189, + /* 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, 4, 238, 177, 273, 275, 90, 177, - /* 1750 */ 96, 15, 190, 275, 251, 101, 212, 103, 190, 4, - /* 1760 */ 106, 107, 190, 176, 4, 111, 198, 199, 176, 251, - /* 1770 */ 198, 199, 118, 119, 120, 121, 177, 204, 42, 4, - /* 1780 */ 177, 4, 204, 251, 181, 251, 176, 258, 177, 190, - /* 1790 */ 177, 177, 181, 190, 177, 59, 276, 198, 199, 237, - /* 1800 */ 64, 190, 258, 190, 190, 176, 152, 190, 154, 155, - /* 1810 */ 156, 198, 199, 177, 49, 198, 199, 81, 82, 251, - /* 1820 */ 178, 178, 4, 251, 88, 177, 190, 180, 183, 181, - /* 1830 */ 106, 107, 96, 15, 198, 199, 177, 101, 190, 103, - /* 1840 */ 106, 107, 106, 107, 4, 106, 107, 111, 4, 190, - /* 1850 */ 251, 60, 177, 104, 118, 119, 120, 121, 177, 221, - /* 1860 */ 42, 106, 107, 184, 251, 190, 106, 107, 251, 56, - /* 1870 */ 151, 190, 133, 198, 199, 138, 152, 59, 227, 198, - /* 1880 */ 199, 106, 107, 106, 107, 228, 148, 251, 152, 177, - /* 1890 */ 154, 155, 156, 118, 177, 118, 229, 149, 164, 81, - /* 1900 */ 82, 146, 190, 230, 177, 177, 88, 190, 181, 177, - /* 1910 */ 198, 199, 150, 231, 96, 198, 199, 190, 190, 101, - /* 1920 */ 177, 103, 190, 163, 106, 107, 251, 177, 4, 111, - /* 1930 */ 198, 199, 251, 190, 147, 87, 118, 119, 120, 121, - /* 1940 */ 190, 198, 199, 177, 100, 177, 106, 107, 198, 199, - /* 1950 */ 106, 107, 252, 64, 203, 96, 190, 259, 190, 87, - /* 1960 */ 203, 255, 158, 251, 198, 199, 198, 199, 251, 177, - /* 1970 */ 152, 241, 154, 155, 156, 177, 99, 177, 177, 177, - /* 1980 */ 177, 241, 190, 251, 181, 177, 99, 223, 190, 177, - /* 1990 */ 190, 190, 190, 190, 251, 139, 198, 199, 190, 198, - /* 2000 */ 199, 251, 190, 123, 208, 165, 198, 199, 177, 177, - /* 2010 */ 198, 199, 177, 181, 177, 177, 177, 251, 31, 251, - /* 2020 */ 181, 190, 190, 200, 200, 190, 200, 190, 190, 190, - /* 2030 */ 106, 107, 177, 198, 199, 177, 198, 199, 202, 4, - /* 2040 */ 241, 122, 118, 200, 4, 190, 200, 99, 190, 251, - /* 2050 */ 203, 177, 251, 198, 199, 177, 198, 199, 177, 251, - /* 2060 */ 4, 177, 4, 251, 190, 181, 200, 4, 190, 177, - /* 2070 */ 177, 190, 198, 199, 190, 208, 198, 199, 203, 198, - /* 2080 */ 199, 4, 190, 190, 4, 177, 251, 4, 200, 251, - /* 2090 */ 198, 199, 177, 180, 177, 177, 4, 177, 190, 177, - /* 2100 */ 200, 4, 99, 180, 4, 190, 251, 190, 190, 251, - /* 2110 */ 190, 177, 190, 198, 199, 198, 199, 177, 198, 199, - /* 2120 */ 198, 199, 177, 177, 190, 251, 241, 177, 99, 251, - /* 2130 */ 190, 27, 251, 264, 158, 190, 190, 227, 198, 199, - /* 2140 */ 190, 106, 107, 251, 198, 199, 106, 107, 198, 199, - /* 2150 */ 99, 265, 215, 118, 99, 62, 99, 250, 118, 215, - /* 2160 */ 96, 180, 106, 107, 106, 107, 251, 241, 251, 106, - /* 2170 */ 107, 251, 177, 251, 118, 177, 118, 100, 99, 227, - /* 2180 */ 100, 118, 180, 106, 107, 190, 106, 107, 190, 106, - /* 2190 */ 107, 251, 100, 99, 241, 177, 217, 251, 106, 107, - /* 2200 */ 177, 251, 60, 106, 107, 177, 106, 107, 190, 177, - /* 2210 */ 177, 177, 99, 190, 177, 177, 217, 99, 190, 99, - /* 2220 */ 177, 217, 190, 190, 190, 217, 177, 190, 190, 99, - /* 2230 */ 241, 99, 268, 190, 18, 152, 268, 241, 99, 190, - /* 2240 */ 99, 241, 99, 270, 16, 224, 226, 261, 201, 152, - /* 2250 */ 256, 261, 152, 240, 242, 201, 206, 242, 210, 242, - /* 2260 */ 175, 202, 191, 227, 191, 224, 191, 191, 262, 253, - /* 2270 */ 263, 274, 207, 207, 222, 207, 216, 55, 239, 198, - /* 2280 */ 198, 211, + /* 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, }; #define YY_SHIFT_USE_DFLT (-81) #define YY_SHIFT_COUNT (434) #define YY_SHIFT_MIN (-80) -#define YY_SHIFT_MAX (2228) +#define YY_SHIFT_MAX (2208) 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, /* 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, 1736, 1654, 1818, 370, 798, - /* 60 */ 181, 370, 2083, 2083, 2083, 2083, 2083, 887, 887, 565, + /* 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, 2097, 2097, 2100, 439, 2097, 2092, 2083, + /* 80 */ 1379, 448, 1399, 2066, 2066, 2069, 439, 2066, 2064, 2001, /* 90 */ 565, 1039, 538, 538, 735, 84, 44, 171, 859, 775, /* 100 */ 906, 773, 910, 636, 1172, 5, 450, 5, 443, 413, - /* 110 */ 185, 2080, 1924, 1760, 1840, 1755, 1739, 2063, 2077, 2058, - /* 120 */ 1525, 2056, 1724, 2040, 2035, 1777, 1734, 1517, 1844, 1775, + /* 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, 2222, 2222, 2222, 2222, - /* 160 */ 2222, -81, -81, 459, 619, 619, 619, 619, 619, 619, + /* 150 */ 90, 829, 829, 829, 872, 544, 2202, 2202, 2202, 2202, + /* 160 */ 2202, -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, 2228, 2143, 2141, 2139, 2216, - /* 240 */ 2216, 2132, 2130, 2142, 2120, 2142, 2118, 2142, 2113, 2142, - /* 250 */ 2094, 1791, 1719, 2079, 1791, 2093, 2064, 2057, 2055, 2093, - /* 260 */ 1719, 2051, 1976, 2104, 2029, 1791, 2003, 1791, 1948, 1859, - /* 270 */ 1880, 1880, 1880, 1880, 1987, 1859, 1880, 1919, 1880, 1987, - /* 280 */ 1880, 1880, 1856, 1887, 1877, 1804, 1859, 1872, 1859, 1889, - /* 290 */ 1848, 1762, 1787, 1748, 1738, 1719, 1737, 1813, 1749, 1791, - /* 300 */ 1765, 1765, 1658, 1658, 1658, 1658, -81, -81, -81, -81, + /* 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, 1676, 1661, 1601, - /* 340 */ 1612, 1591, 1549, 1558, 1543, 1511, 1541, 1519, 1496, 1459, + /* 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, @@ -758,40 +755,40 @@ static const short yy_shift_ofst[] = { #define YY_REDUCE_USE_DFLT (-100) #define YY_REDUCE_COUNT (315) #define YY_REDUCE_MIN (-99) -#define YY_REDUCE_MAX (2085) +#define YY_REDUCE_MAX (2067) static const short yy_reduce_ofst[] = { /* 0 */ 615, 1195, 699, -99, 764, 1138, 189, 705, 1259, 1218, - /* 10 */ 1201, 261, 196, 884, 599, 1187, 1950, 1946, 1940, 1922, - /* 20 */ 1920, 1917, 1915, 1892, 1881, 1878, 1874, 1858, 1855, 1838, - /* 30 */ 1835, 1812, 1808, 1801, 1798, 1768, 1766, 1750, 1743, 1732, - /* 40 */ 1717, 1712, 1681, 1675, 1636, 1617, 1613, 1599, 1572, 1568, + /* 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, 1562, 1884, 1839, 1832, 1803, 1727, 1648, 1611, 1603, - /* 80 */ 1270, 1520, 203, 1346, 1255, 131, 347, 950, 1397, 195, - /* 90 */ 885, 265, 1134, 1132, 125, 377, 1011, 2049, 2043, 2028, - /* 100 */ 1792, 1792, 2038, 2037, 2034, 697, 2033, 11, 1792, 2032, - /* 110 */ 2028, 2023, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 2018, - /* 120 */ 1792, 1792, 1998, 1792, 1792, 1995, 1792, 1792, 1792, 1945, - /* 130 */ 1934, 1918, 1908, 1893, 1837, 1141, 1140, 1831, 1802, 1065, - /* 140 */ 1800, 1792, 1728, 1659, 1614, 1485, 632, 1474, 1452, 1294, + /* 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, 2070, 2082, - /* 200 */ 2081, 1462, 1997, 1997, 2068, 2066, 2065, 2039, 2060, 2016, - /* 210 */ 2052, 2007, 2006, 2076, 2075, 2073, 2071, 2041, 2085, 2036, - /* 220 */ 2017, 2015, 2059, 2048, 2050, 2054, 2012, 2013, 1994, 2047, - /* 230 */ 1990, 1986, 1462, 2020, 2021, 1973, 1799, 2000, 1996, 1968, - /* 240 */ 1964, 1989, 1799, 2008, 1799, 2004, 1799, 1999, 1799, 1979, - /* 250 */ 1953, 2002, 1952, 1926, 1981, 1944, 1907, 1799, 1799, 1937, - /* 260 */ 1910, 1799, 1886, 1869, 1885, 1923, 1799, 1913, 1799, 1875, - /* 270 */ 1900, 1888, 1866, 1846, 1867, 1847, 1843, 1836, 1826, 1796, - /* 280 */ 1824, 1823, 1764, 1740, 1730, 1706, 1757, 1698, 1751, 1700, - /* 290 */ 1462, 1682, 1673, 1667, 1657, 1651, 1638, 1679, 1645, 1647, - /* 300 */ 1643, 1642, 1629, 1610, 1592, 1587, 1478, 1472, 1473, 1578, - /* 310 */ 1573, 1506, 1462, 1462, 1462, 1540, + /* 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, }; static const YYACTIONTYPE yy_default[] = { /* 0 */ 729, 1037, 1142, 1142, 1026, 1026, 1026, 1142, 1026, 1026, @@ -3183,23 +3180,15 @@ static void yy_reduce( } break; case 81: /* term ::= NULL */ -{ - yygotominor.yy21 = new QVariant(); - } +{yygotominor.yy21 = new QVariant();} break; case 82: /* term ::= INTEGER */ -{ - int base = 10; - if (yymsp[0].minor.yy0->value.startsWith("0x", Qt::CaseInsensitive)) - base = 16; - - yygotominor.yy21 = new QVariant(yymsp[0].minor.yy0->value.toLongLong(nullptr, base)); - } + case 351: /* number ::= INTEGER */ yytestcase(yyruleno==351); +{yygotominor.yy21 = parserContext->handleNumberToken(yymsp[0].minor.yy0->value);} break; case 83: /* term ::= FLOAT */ -{ - yygotominor.yy21 = new QVariant(QVariant(yymsp[0].minor.yy0->value).toDouble()); - } + case 352: /* number ::= FLOAT */ yytestcase(yyruleno==352); +{yygotominor.yy21 = new QVariant(QVariant(yymsp[0].minor.yy0->value).toDouble());} break; case 84: /* term ::= STRING|BLOB */ case 345: /* nmnum ::= ON */ yytestcase(yyruleno==345); @@ -4273,7 +4262,6 @@ static void yy_reduce( } break; case 277: /* exprx ::= BITNOT expr */ - case 278: /* exprx ::= MINUS expr */ yytestcase(yyruleno==278); case 279: /* exprx ::= PLUS expr */ yytestcase(yyruleno==279); { yygotominor.yy490 = new SqliteExpr(); @@ -4281,6 +4269,23 @@ static void yy_reduce( objectForTokens = yygotominor.yy490; } break; + case 278: /* exprx ::= MINUS expr */ +{ + yygotominor.yy490 = new SqliteExpr(); + if (yymsp[0].minor.yy490->mode == SqliteExpr::Mode::LITERAL_VALUE && + parserContext->isCandidateForMaxNegativeNumber() && + yymsp[0].minor.yy490->literalValue == static_cast<qint64>(0L)) + { + yygotominor.yy490->initLiteral(std::numeric_limits<qint64>::min()); + delete yymsp[0].minor.yy490; + } + else + { + yygotominor.yy490->initUnaryOp(yymsp[0].minor.yy490, yymsp[-1].minor.yy0->value); + } + objectForTokens = yygotominor.yy490; + } + break; case 280: /* exprx ::= expr not_opt BETWEEN expr AND expr */ { yygotominor.yy490 = new SqliteExpr(); @@ -4316,7 +4321,7 @@ static void yy_reduce( case 284: /* exprx ::= expr not_opt IN nm dbnm */ { yygotominor.yy490 = new SqliteExpr(); - yygotominor.yy490->initIn(yymsp[-4].minor.yy490, yymsp[-3].minor.yy237, *(yymsp[-1].minor.yy211), *(yymsp[0].minor.yy211)); + yygotominor.yy490->initIn(yymsp[-4].minor.yy490, *(yymsp[-3].minor.yy237), *(yymsp[-1].minor.yy211), *(yymsp[0].minor.yy211)); delete yymsp[-3].minor.yy237; delete yymsp[-1].minor.yy211; objectForTokens = yygotominor.yy490; @@ -4577,19 +4582,18 @@ static void yy_reduce( if (yymsp[0].minor.yy21->type() == QVariant::Double) *(yymsp[0].minor.yy21) = -(yymsp[0].minor.yy21->toDouble()); else if (yymsp[0].minor.yy21->type() == QVariant::LongLong) - *(yymsp[0].minor.yy21) = -(yymsp[0].minor.yy21->toLongLong()); + { + if (parserContext->isCandidateForMaxNegativeNumber()) + *(yymsp[0].minor.yy21) = std::numeric_limits<qint64>::min(); + else + *(yymsp[0].minor.yy21) = -(yymsp[0].minor.yy21->toLongLong()); + } else Q_ASSERT_X(true, "producing minus number", "QVariant is neither of Double or LongLong."); yygotominor.yy21 = yymsp[0].minor.yy21; } break; - case 351: /* number ::= INTEGER */ -{yygotominor.yy21 = new QVariant(QVariant(yymsp[0].minor.yy0->value).toLongLong());} - break; - case 352: /* number ::= FLOAT */ -{yygotominor.yy21 = new QVariant(QVariant(yymsp[0].minor.yy0->value).toDouble());} - break; case 353: /* cmd ::= CREATE temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON nm foreach_clause when_clause BEGIN trigger_cmd_list END */ { yygotominor.yy399 = new SqliteCreateTrigger( diff --git a/SQLiteStudio3/coreSQLiteStudio/parser/sqlite3_parse.y b/SQLiteStudio3/coreSQLiteStudio/parser/sqlite3_parse.y index 0353e2c..0bab877 100644 --- a/SQLiteStudio3/coreSQLiteStudio/parser/sqlite3_parse.y +++ b/SQLiteStudio3/coreSQLiteStudio/parser/sqlite3_parse.y @@ -57,6 +57,7 @@ #include "parser/ast/sqlitewith.h" #include <QObject> #include <QDebug> +#include <limits.h> #define assert(X) Q_ASSERT(X) #define UNUSED_PARAMETER(X) (void)(X) @@ -539,19 +540,9 @@ ccons(X) ::= CHECK LP RP. { %type term {QVariant*} %destructor term {delete $$;} -term(X) ::= NULL. { - X = new QVariant(); - } -term(X) ::= INTEGER(N). { - int base = 10; - if (N->value.startsWith("0x", Qt::CaseInsensitive)) - base = 16; - - X = new QVariant(N->value.toLongLong(nullptr, base)); - } -term(X) ::= FLOAT(N). { - X = new QVariant(QVariant(N->value).toDouble()); - } +term(X) ::= NULL. {X = new QVariant();} +term(X) ::= INTEGER(N). {X = parserContext->handleNumberToken(N->value);} +term(X) ::= FLOAT(N). {X = new QVariant(QVariant(N->value).toDouble());} term(X) ::= STRING|BLOB(S). {X = new QVariant(S->value);} // The optional AUTOINCREMENT keyword @@ -1625,7 +1616,17 @@ exprx(X) ::= BITNOT(O) expr(E). { } exprx(X) ::= MINUS(O) expr(E). [BITNOT] { X = new SqliteExpr(); - X->initUnaryOp(E, O->value); + if (E->mode == SqliteExpr::Mode::LITERAL_VALUE && + parserContext->isCandidateForMaxNegativeNumber() && + E->literalValue == static_cast<qint64>(0L)) + { + X->initLiteral(std::numeric_limits<qint64>::min()); + delete E; + } + else + { + X->initUnaryOp(E, O->value); + } objectForTokens = X; } exprx(X) ::= PLUS(O) expr(E). [BITNOT] { @@ -1664,7 +1665,7 @@ exprx(X) ::= expr(E) not_opt(N) IN LP exprx(X) ::= expr(E) not_opt(N) IN nm(N1) dbnm(N2). [IN] { X = new SqliteExpr(); - X->initIn(E, N, *(N1), *(N2)); + X->initIn(E, *(N), *(N1), *(N2)); delete N; delete N1; objectForTokens = X; @@ -1991,7 +1992,12 @@ minus_num(X) ::= MINUS number(N). { if (N->type() == QVariant::Double) *(N) = -(N->toDouble()); else if (N->type() == QVariant::LongLong) - *(N) = -(N->toLongLong()); + { + if (parserContext->isCandidateForMaxNegativeNumber()) + *(N) = std::numeric_limits<qint64>::min(); + else + *(N) = -(N->toLongLong()); + } else Q_ASSERT_X(true, "producing minus number", "QVariant is neither of Double or LongLong."); @@ -2000,7 +2006,7 @@ minus_num(X) ::= MINUS number(N). { %type number {QVariant*} %destructor number {delete $$;} -number(X) ::= INTEGER(N). {X = new QVariant(QVariant(N->value).toLongLong());} +number(X) ::= INTEGER(N). {X = parserContext->handleNumberToken(N->value);} number(X) ::= FLOAT(N). {X = new QVariant(QVariant(N->value).toDouble());} //////////////////////////// The CREATE TRIGGER command ///////////////////// diff --git a/SQLiteStudio3/coreSQLiteStudio/services/impl/dbmanagerimpl.cpp b/SQLiteStudio3/coreSQLiteStudio/services/impl/dbmanagerimpl.cpp index 70aa568..e96e181 100644 --- a/SQLiteStudio3/coreSQLiteStudio/services/impl/dbmanagerimpl.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/services/impl/dbmanagerimpl.cpp @@ -107,9 +107,14 @@ bool DbManagerImpl::updateDb(Db* db, const QString &name, const QString &path, c result = CFG->removeDb(name); InvalidDb* invalidDb = dynamic_cast<InvalidDb*>(db); + bool wasReloaded = false; Db* reloadedDb = db; if (pathDifferent && invalidDb) - reloadedDb = tryToLoadDb(invalidDb); + { + reloadedDb = tryToLoadDb(invalidDb, false); + if (reloadedDb) // we need to know that, so we can emit dbLoaded() signal later, out of the listLock + wasReloaded = true; + } if (reloadedDb) // reloading was not necessary (was not invalid) or it was successful db = reloadedDb; @@ -119,6 +124,10 @@ bool DbManagerImpl::updateDb(Db* db, const QString &name, const QString &path, c listLock.unlock(); + // If we did reload the db, we need to emit proper signal, because it was suppressed in tryToLoadDb(), because of the listLock + if (wasReloaded) + emit dbLoaded(db); + if (result && reloadedDb) emit dbUpdated(oldName, db); else if (reloadedDb) // database reloaded correctly, but update failed @@ -355,7 +364,7 @@ QList<Db*> DbManagerImpl::getInvalidDatabases() const }); } -Db* DbManagerImpl::tryToLoadDb(InvalidDb* invalidDb) +Db* DbManagerImpl::tryToLoadDb(InvalidDb* invalidDb, bool emitNotifySignal) { QUrl url = QUrl::fromUserInput(invalidDb->getPath()); if (url.isLocalFile() && !QFile::exists(invalidDb->getPath())) @@ -373,7 +382,9 @@ Db* DbManagerImpl::tryToLoadDb(InvalidDb* invalidDb) if (CFG->getDbGroup(db->getName())->open) db->open(); - emit dbLoaded(db); + if (emitNotifySignal) + emit dbLoaded(db); + return db; } diff --git a/SQLiteStudio3/coreSQLiteStudio/services/impl/dbmanagerimpl.h b/SQLiteStudio3/coreSQLiteStudio/services/impl/dbmanagerimpl.h index 8e28080..5797ac6 100644 --- a/SQLiteStudio3/coreSQLiteStudio/services/impl/dbmanagerimpl.h +++ b/SQLiteStudio3/coreSQLiteStudio/services/impl/dbmanagerimpl.h @@ -94,7 +94,7 @@ class API_EXPORT DbManagerImpl : public DbManager */ QList<Db*> getInvalidDatabases() const; - Db* tryToLoadDb(InvalidDb* invalidDb); + Db* tryToLoadDb(InvalidDb* invalidDb, bool emitNotifySignal = true); /** * @brief Creates database object. diff --git a/SQLiteStudio3/coreSQLiteStudio/services/importmanager.h b/SQLiteStudio3/coreSQLiteStudio/services/importmanager.h index 6f13826..2401e78 100644 --- a/SQLiteStudio3/coreSQLiteStudio/services/importmanager.h +++ b/SQLiteStudio3/coreSQLiteStudio/services/importmanager.h @@ -36,6 +36,8 @@ class API_EXPORT ImportManager : public PluginServiceBase * (for example from a clipboard). */ QString inputFileName; + + bool ignoreErrors = false; }; enum StandardConfigFlag diff --git a/SQLiteStudio3/coreSQLiteStudio/services/notifymanager.cpp b/SQLiteStudio3/coreSQLiteStudio/services/notifymanager.cpp index 0980399..f8b7f25 100644 --- a/SQLiteStudio3/coreSQLiteStudio/services/notifymanager.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/services/notifymanager.cpp @@ -1,4 +1,5 @@ #include "services/notifymanager.h"
+#include <QDebug>
DEFINE_SINGLETON(NotifyManager)
@@ -71,11 +72,13 @@ QList<QString> NotifyManager::getRecentErrors() const void notifyError(const QString &msg)
{
+ qDebug() << "Error from notify manager:" << msg;
NotifyManager::getInstance()->error(msg);
}
void notifyWarn(const QString &msg)
{
+ qDebug() << "Warning from notify manager:" << msg;
NotifyManager::getInstance()->warn(msg);
}
diff --git a/SQLiteStudio3/coreSQLiteStudio/sqlitestudio.cpp b/SQLiteStudio3/coreSQLiteStudio/sqlitestudio.cpp index 2d2bbd3..361b2e4 100644 --- a/SQLiteStudio3/coreSQLiteStudio/sqlitestudio.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/sqlitestudio.cpp @@ -39,7 +39,7 @@ DEFINE_SINGLETON(SQLiteStudio) -static const int sqlitestudioVersion = 30003; +static const int sqlitestudioVersion = 30004; SQLiteStudio::SQLiteStudio() { diff --git a/SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp b/SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp index 8dc36ee..973402a 100644 --- a/SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/tablemodifier.cpp @@ -10,6 +10,7 @@ #include "parser/ast/sqliteupdate.h" #include "parser/ast/sqliteinsert.h" #include "parser/ast/sqlitedelete.h" +#include "common/unused.h" #include <QDebug> // TODO no attach/temp db name support in this entire class @@ -458,7 +459,7 @@ void TableModifier::handleTriggerQueries(SqliteCreateTriggerPtr trigger) foreach (SqliteQuery* query, trigger->queries) { // The handleTriggerQuery() may delete the input query object. Don't refer to it later. - newQuery = handleTriggerQuery(query, trigger->trigger); + newQuery = handleTriggerQuery(query, trigger->trigger, trigger->table); if (newQuery) newQueries << newQuery; else @@ -497,28 +498,28 @@ void TableModifier::handleView(SqliteCreateViewPtr view) modifiedViews << view->view; } -SqliteQuery* TableModifier::handleTriggerQuery(SqliteQuery* query, const QString& trigName) +SqliteQuery* TableModifier::handleTriggerQuery(SqliteQuery* query, const QString& trigName, const QString& trigTable) { SqliteSelect* select = dynamic_cast<SqliteSelect*>(query); if (select) - return handleSelect(select); + return handleSelect(select, trigTable); SqliteUpdate* update = dynamic_cast<SqliteUpdate*>(query); if (update) - return handleTriggerUpdate(update, trigName); + return handleTriggerUpdate(update, trigName, trigTable); SqliteInsert* insert = dynamic_cast<SqliteInsert*>(query); if (insert) - return handleTriggerInsert(insert, trigName); + return handleTriggerInsert(insert, trigName, trigTable); SqliteDelete* del = dynamic_cast<SqliteDelete*>(query); if (del) - return handleTriggerDelete(del, trigName); + return handleTriggerDelete(del, trigName, trigTable); return nullptr; } -SqliteSelect* TableModifier::handleSelect(SqliteSelect* select) +SqliteSelect* TableModifier::handleSelect(SqliteSelect* select, const QString& trigTable) { // Table name TokenList tableTokens = select->getContextTableTokens(false); @@ -561,76 +562,92 @@ SqliteSelect* TableModifier::handleSelect(SqliteSelect* select) return nullptr; } + if (!trigTable.isNull() && !handleAllExprWithTrigTable(selectPtr.data(), trigTable)) + return nullptr; + return new SqliteSelect(*selectPtr.data()); } -SqliteUpdate* TableModifier::handleTriggerUpdate(SqliteUpdate* update, const QString& trigName) +SqliteUpdate* TableModifier::handleTriggerUpdate(SqliteUpdate* update, const QString& trigName, const QString& trigTable) { - // Table name if (update->table.compare(originalTable, Qt::CaseInsensitive) == 0) + { + // Table name update->table = newName; - // Column names - handleUpdateColumns(update); + // Column names + handleUpdateColumns(update); + } // Any embedded selects - bool embedSelectsOk = handleSubSelects(update); - if (!embedSelectsOk) + bool embedSelectsOk = handleSubSelects(update, trigTable); + bool embedExprOk = handleAllExprWithTrigTable(update, trigTable); + if (!embedSelectsOk || !embedExprOk) { warnings << QObject::tr("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.").arg("UPDATE").arg(trigName).arg(originalTable); + "One of the %1 substatements which might be referring to table %3 cannot be properly modified. " + "Manual update of the trigger may be necessary.").arg("UPDATE", trigName, originalTable); } return update; } -SqliteInsert* TableModifier::handleTriggerInsert(SqliteInsert* insert, const QString& trigName) +SqliteInsert* TableModifier::handleTriggerInsert(SqliteInsert* insert, const QString& trigName, const QString& trigTable) { - // Table name if (insert->table.compare(originalTable, Qt::CaseInsensitive) == 0) + { + // Table name insert->table = newName; - // Column names - handleColumnNames(insert->columnNames); + // Column names + handleColumnNames(insert->columnNames); + } // Any embedded selects - bool embedSelectsOk = handleSubSelects(insert); - if (!embedSelectsOk) + bool embedSelectsOk = handleSubSelects(insert, trigTable); + bool embedExprOk = handleAllExprWithTrigTable(insert, trigTable); + if (!embedSelectsOk || !embedExprOk) { warnings << QObject::tr("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. " + "One of the %1 substatements which might be referring to table %3 cannot be properly modified. " "Manual update of the trigger may be necessary.").arg("INSERT", trigName, originalTable); } return insert; } -SqliteDelete* TableModifier::handleTriggerDelete(SqliteDelete* del, const QString& trigName) +SqliteDelete* TableModifier::handleTriggerDelete(SqliteDelete* del, const QString& trigName, const QString& trigTable) { // Table name if (del->table.compare(originalTable, Qt::CaseInsensitive) == 0) del->table = newName; // Any embedded selects - bool embedSelectsOk = handleSubSelects(del); - if (!embedSelectsOk) + bool embedSelectsOk = handleSubSelects(del, trigTable); + bool embedExprOk = handleAllExprWithTrigTable(del, trigTable); + if (!embedSelectsOk || !embedExprOk) { warnings << QObject::tr("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. " + "One of the %1 substatements which might be referring to table %3 cannot be properly modified. " "Manual update of the trigger may be necessary.").arg("DELETE", trigName, originalTable); } return del; } -bool TableModifier::handleSubSelects(SqliteStatement* stmt) +bool TableModifier::handleSubSelects(SqliteStatement* stmt, const QString& trigTable) { bool embedSelectsOk = true; QList<SqliteSelect*> selects = stmt->getAllTypedStatements<SqliteSelect>(); SqliteExpr* expr = nullptr; foreach (SqliteSelect* select, selects) { + if (select->coreSelects.size() >= 1 && select->coreSelects.first()->valuesMode) + { + // INSERT with VALUES() as subselect + continue; + } + expr = dynamic_cast<SqliteExpr*>(select->parentStatement()); if (!expr) { @@ -638,13 +655,13 @@ bool TableModifier::handleSubSelects(SqliteStatement* stmt) continue; } - if (!handleExprWithSelect(expr)) + if (!handleExprWithSelect(expr, trigTable)) embedSelectsOk = false; } return embedSelectsOk; } -bool TableModifier::handleExprWithSelect(SqliteExpr* expr) +bool TableModifier::handleExprWithSelect(SqliteExpr* expr, const QString& trigTable) { if (!expr->select) { @@ -652,7 +669,7 @@ bool TableModifier::handleExprWithSelect(SqliteExpr* expr) return false; } - SqliteSelect* newSelect = handleSelect(expr->select); + SqliteSelect* newSelect = handleSelect(expr->select, trigTable); if (!newSelect) { qCritical() << "Could not generate new SELECT in TableModifier::handleExprWithSelect()"; @@ -665,6 +682,49 @@ bool TableModifier::handleExprWithSelect(SqliteExpr* expr) return true; } +bool TableModifier::handleAllExprWithTrigTable(SqliteStatement* stmt, const QString& contextTable) +{ + if (contextTable != originalTable) + return true; + + return handleExprListWithTrigTable(stmt->getAllTypedStatements<SqliteExpr>()); +} + +bool TableModifier::handleExprListWithTrigTable(const QList<SqliteExpr*>& exprList) +{ + for (SqliteExpr* expr : exprList) + { + if (!handleExprWithTrigTable(expr)) + return false; + } + return true; +} + +bool TableModifier::handleExprWithTrigTable(SqliteExpr* expr) +{ + if (expr->mode != SqliteExpr::Mode::ID) + return true; + + if (!expr->database.isNull()) + return true; + + if (expr->table.compare("old", Qt::CaseInsensitive) != 0 && expr->table.compare("new", Qt::CaseInsensitive) != 0) + 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 d3977ee..f063693 100644 --- a/SQLiteStudio3/coreSQLiteStudio/tablemodifier.h +++ b/SQLiteStudio3/coreSQLiteStudio/tablemodifier.h @@ -45,13 +45,16 @@ class API_EXPORT TableModifier void handleTriggerQueries(SqliteCreateTriggerPtr trigger); void handleViews(); void handleView(SqliteCreateViewPtr view); - SqliteQuery* handleTriggerQuery(SqliteQuery* query, const QString& trigName); - SqliteSelect* handleSelect(SqliteSelect* select); - SqliteUpdate* handleTriggerUpdate(SqliteUpdate* update, const QString& trigName); - SqliteInsert* handleTriggerInsert(SqliteInsert* insert, const QString& trigName); - SqliteDelete* handleTriggerDelete(SqliteDelete* del, const QString& trigName); - bool handleSubSelects(SqliteStatement* stmt); - bool handleExprWithSelect(SqliteExpr* expr); + SqliteQuery* handleTriggerQuery(SqliteQuery* query, const QString& trigName, const QString& trigTable); + SqliteSelect* handleSelect(SqliteSelect* select, const QString& trigTable = QString()); + SqliteUpdate* handleTriggerUpdate(SqliteUpdate* update, const QString& trigName, const QString& trigTable); + SqliteInsert* handleTriggerInsert(SqliteInsert* insert, const QString& trigName, const QString& trigTable); + SqliteDelete* handleTriggerDelete(SqliteDelete* del, const QString& trigName, const QString& trigTable); + bool handleSubSelects(SqliteStatement* stmt, const QString& trigTable); + bool handleExprWithSelect(SqliteExpr* expr, const QString& trigTable); + bool handleAllExprWithTrigTable(SqliteStatement* stmt, const QString& contextTable); + bool handleExprListWithTrigTable(const QList<SqliteExpr*>& exprList); + bool handleExprWithTrigTable(SqliteExpr* expr); void simpleHandleIndexes(); void simpleHandleTriggers(const QString& view = QString::null); SqliteQueryPtr parseQuery(const QString& ddl); diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_de.ts b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_de.ts index 7656d3b..46425fc 100644 --- a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_de.ts +++ b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_de.ts @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS> -<TS version="2.0" language="de_DE"> +<TS version="2.1" language="de_DE"> <context> <name>AbstractDb</name> <message> @@ -147,30 +147,30 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="125"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="134"/> <source>Database %1 could not be updated, because of an error: %2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="299"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="328"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="308"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="337"/> <source>Database file doesn't exist.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="301"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="330"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="483"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="310"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="339"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="494"/> <source>No supporting plugin loaded.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="402"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="413"/> <source>Database could not be initialized.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="412"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="423"/> <source>No suitable database driver plugin found.</source> <translation type="unfinished"></translation> </message> @@ -318,33 +318,33 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> <context> <name>ExportWorker</name> <message> - <location filename="../exportworker.cpp" line="116"/> + <location filename="../exportworker.cpp" line="121"/> <source>Error while exporting query results: %1</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="175"/> + <location filename="../exportworker.cpp" line="201"/> <source>Error while counting data column width to export from query results: %1</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="275"/> - <location filename="../exportworker.cpp" line="326"/> + <location filename="../exportworker.cpp" line="353"/> + <location filename="../exportworker.cpp" line="411"/> <source>Could not parse %1 in order to export it. It will be excluded from the export output.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="482"/> + <location filename="../exportworker.cpp" line="612"/> <source>Error while reading data to export from table %1: %2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="490"/> + <location filename="../exportworker.cpp" line="620"/> <source>Error while counting data to export from table %1: %2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="506"/> + <location filename="../exportworker.cpp" line="636"/> <source>Error while counting data column width to export from table %1: %2</source> <translation type="unfinished"></translation> </message> @@ -443,18 +443,23 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> </message> <message> <location filename="../importworker.cpp" line="125"/> - <location filename="../importworker.cpp" line="152"/> - <location filename="../importworker.cpp" line="158"/> + <location filename="../importworker.cpp" line="162"/> + <location filename="../importworker.cpp" line="169"/> <source>Error while importing data: %1</source> <translation type="unfinished"></translation> </message> <message> <location filename="../importworker.cpp" line="125"/> - <location filename="../importworker.cpp" line="158"/> + <location filename="../importworker.cpp" line="169"/> <source>Interrupted.</source> <comment>import process status update</comment> <translation type="unfinished"></translation> </message> + <message> + <location filename="../importworker.cpp" line="157"/> + <source>Could not import data row number %1. The row was ignored. Problem details: %2</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>PluginManagerImpl</name> @@ -765,7 +770,7 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> </message> <message> <location filename="../db/abstractdb2.h" line="796"/> - <location filename="../db/abstractdb3.h" line="1082"/> + <location filename="../db/abstractdb3.h" line="1092"/> <source>Result set expired or no row available.</source> <translation type="unfinished"></translation> </message> @@ -834,13 +839,13 @@ Error details: %2</source> </message> <message> <location filename="../parser/sqlite2_parse.cpp" line="1904"/> - <location filename="../parser/sqlite3_parse.cpp" line="2170"/> + <location filename="../parser/sqlite3_parse.cpp" line="2167"/> <source>Parser stack overflow</source> <translation type="unfinished"></translation> </message> <message> <location filename="../parser/sqlite2_parse.cpp" line="4461"/> - <location filename="../parser/sqlite3_parse.cpp" line="5076"/> + <location filename="../parser/sqlite3_parse.cpp" line="5080"/> <source>Syntax error</source> <translation type="unfinished"></translation> </message> @@ -947,41 +952,41 @@ Error details: %2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="107"/> + <location filename="../tablemodifier.cpp" line="108"/> <source>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.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="379"/> + <location filename="../tablemodifier.cpp" line="380"/> <source>All columns indexed by the index %1 are gone. The index will not be recreated after table modification.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="418"/> + <location filename="../tablemodifier.cpp" line="419"/> <source>There is problem with proper processing trigger %1. It may be not fully updated afterwards and will need your attention.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="465"/> + <location filename="../tablemodifier.cpp" line="466"/> <source>Cannot not update trigger %1 according to table %2 modification.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="433"/> - <source>All columns covered by the trigger %1 are gone. The trigger will not be recreated after table modification.</source> + <location filename="../tablemodifier.cpp" line="587"/> + <location filename="../tablemodifier.cpp" line="611"/> + <location filename="../tablemodifier.cpp" line="630"/> + <source>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.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="483"/> - <source>Cannot not update view %1 according to table %2 modifications. -The view will remain as it is.</source> + <location filename="../tablemodifier.cpp" line="434"/> + <source>All columns covered by the trigger %1 are gone. The trigger will not be recreated after table modification.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="580"/> - <location filename="../tablemodifier.cpp" line="601"/> - <location filename="../tablemodifier.cpp" line="619"/> - <source>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.</source> + <location filename="../tablemodifier.cpp" line="484"/> + <source>Cannot not update view %1 according to table %2 modifications. +The view will remain as it is.</source> <translation type="unfinished"></translation> </message> <message> diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_es.ts b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_es.ts index 420d0bb..9545030 100644 --- a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_es.ts +++ b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_es.ts @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS> -<TS version="2.0" language="es_ES"> +<TS version="2.1" language="es_ES"> <context> <name>AbstractDb</name> <message> @@ -147,30 +147,30 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="125"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="134"/> <source>Database %1 could not be updated, because of an error: %2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="299"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="328"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="308"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="337"/> <source>Database file doesn't exist.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="301"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="330"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="483"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="310"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="339"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="494"/> <source>No supporting plugin loaded.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="402"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="413"/> <source>Database could not be initialized.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="412"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="423"/> <source>No suitable database driver plugin found.</source> <translation type="unfinished"></translation> </message> @@ -318,33 +318,33 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> <context> <name>ExportWorker</name> <message> - <location filename="../exportworker.cpp" line="116"/> + <location filename="../exportworker.cpp" line="121"/> <source>Error while exporting query results: %1</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="175"/> + <location filename="../exportworker.cpp" line="201"/> <source>Error while counting data column width to export from query results: %1</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="275"/> - <location filename="../exportworker.cpp" line="326"/> + <location filename="../exportworker.cpp" line="353"/> + <location filename="../exportworker.cpp" line="411"/> <source>Could not parse %1 in order to export it. It will be excluded from the export output.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="482"/> + <location filename="../exportworker.cpp" line="612"/> <source>Error while reading data to export from table %1: %2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="490"/> + <location filename="../exportworker.cpp" line="620"/> <source>Error while counting data to export from table %1: %2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="506"/> + <location filename="../exportworker.cpp" line="636"/> <source>Error while counting data column width to export from table %1: %2</source> <translation type="unfinished"></translation> </message> @@ -443,18 +443,23 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> </message> <message> <location filename="../importworker.cpp" line="125"/> - <location filename="../importworker.cpp" line="152"/> - <location filename="../importworker.cpp" line="158"/> + <location filename="../importworker.cpp" line="162"/> + <location filename="../importworker.cpp" line="169"/> <source>Error while importing data: %1</source> <translation type="unfinished"></translation> </message> <message> <location filename="../importworker.cpp" line="125"/> - <location filename="../importworker.cpp" line="158"/> + <location filename="../importworker.cpp" line="169"/> <source>Interrupted.</source> <comment>import process status update</comment> <translation type="unfinished"></translation> </message> + <message> + <location filename="../importworker.cpp" line="157"/> + <source>Could not import data row number %1. The row was ignored. Problem details: %2</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>PluginManagerImpl</name> @@ -765,7 +770,7 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> </message> <message> <location filename="../db/abstractdb2.h" line="796"/> - <location filename="../db/abstractdb3.h" line="1082"/> + <location filename="../db/abstractdb3.h" line="1092"/> <source>Result set expired or no row available.</source> <translation type="unfinished"></translation> </message> @@ -834,13 +839,13 @@ Error details: %2</source> </message> <message> <location filename="../parser/sqlite2_parse.cpp" line="1904"/> - <location filename="../parser/sqlite3_parse.cpp" line="2170"/> + <location filename="../parser/sqlite3_parse.cpp" line="2167"/> <source>Parser stack overflow</source> <translation type="unfinished"></translation> </message> <message> <location filename="../parser/sqlite2_parse.cpp" line="4461"/> - <location filename="../parser/sqlite3_parse.cpp" line="5076"/> + <location filename="../parser/sqlite3_parse.cpp" line="5080"/> <source>Syntax error</source> <translation type="unfinished"></translation> </message> @@ -947,41 +952,41 @@ Error details: %2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="107"/> + <location filename="../tablemodifier.cpp" line="108"/> <source>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.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="379"/> + <location filename="../tablemodifier.cpp" line="380"/> <source>All columns indexed by the index %1 are gone. The index will not be recreated after table modification.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="418"/> + <location filename="../tablemodifier.cpp" line="419"/> <source>There is problem with proper processing trigger %1. It may be not fully updated afterwards and will need your attention.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="465"/> + <location filename="../tablemodifier.cpp" line="466"/> <source>Cannot not update trigger %1 according to table %2 modification.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="433"/> - <source>All columns covered by the trigger %1 are gone. The trigger will not be recreated after table modification.</source> + <location filename="../tablemodifier.cpp" line="587"/> + <location filename="../tablemodifier.cpp" line="611"/> + <location filename="../tablemodifier.cpp" line="630"/> + <source>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.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="483"/> - <source>Cannot not update view %1 according to table %2 modifications. -The view will remain as it is.</source> + <location filename="../tablemodifier.cpp" line="434"/> + <source>All columns covered by the trigger %1 are gone. The trigger will not be recreated after table modification.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="580"/> - <location filename="../tablemodifier.cpp" line="601"/> - <location filename="../tablemodifier.cpp" line="619"/> - <source>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.</source> + <location filename="../tablemodifier.cpp" line="484"/> + <source>Cannot not update view %1 according to table %2 modifications. +The view will remain as it is.</source> <translation type="unfinished"></translation> </message> <message> diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_fr.qm b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_fr.qm Binary files differindex a0b0a53..668a42a 100644 --- a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_fr.qm +++ b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_fr.qm diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_fr.ts b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_fr.ts index 46e3abc..6e53771 100644 --- a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_fr.ts +++ b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_fr.ts @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS> -<TS version="2.0" language="fr_FR"> +<TS version="2.1" language="fr_FR"> <context> <name>AbstractDb</name> <message> @@ -147,30 +147,30 @@ <translation>Impossible d'ajouter une base de données %1: %2</translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="125"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="134"/> <source>Database %1 could not be updated, because of an error: %2</source> <translation>La base de données %1 ne peut ëtre mise à jour à cause de l'erreur: %2</translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="299"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="328"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="308"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="337"/> <source>Database file doesn't exist.</source> <translation>Le fichier de la base de données n'existe pas.</translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="301"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="330"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="483"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="310"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="339"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="494"/> <source>No supporting plugin loaded.</source> <translation>Aucun plugin supporté chargé.</translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="402"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="413"/> <source>Database could not be initialized.</source> <translation>La base de données ne peut être initialisée.</translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="412"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="423"/> <source>No suitable database driver plugin found.</source> <translation>Aucun pilote de base de données approprié trouvé.</translation> </message> @@ -319,33 +319,33 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma <context> <name>ExportWorker</name> <message> - <location filename="../exportworker.cpp" line="116"/> + <location filename="../exportworker.cpp" line="121"/> <source>Error while exporting query results: %1</source> <translation>Erreur lors de l'exportation des résultats de la requête:%1</translation> </message> <message> - <location filename="../exportworker.cpp" line="175"/> + <location filename="../exportworker.cpp" line="201"/> <source>Error while counting data column width to export from query results: %1</source> <translation>Erreur lors de la totalisation des données de colonne issu de la requête: %1</translation> </message> <message> - <location filename="../exportworker.cpp" line="275"/> - <location filename="../exportworker.cpp" line="326"/> + <location filename="../exportworker.cpp" line="353"/> + <location filename="../exportworker.cpp" line="411"/> <source>Could not parse %1 in order to export it. It will be excluded from the export output.</source> <translation>Impossible d'analyser %1 afin de l'exporter. Celle-ci sera excluse de l'exportation.</translation> </message> <message> - <location filename="../exportworker.cpp" line="482"/> + <location filename="../exportworker.cpp" line="612"/> <source>Error while reading data to export from table %1: %2</source> <translation>Erreur lors de la lecture des données à exporter de la table %1: %2</translation> </message> <message> - <location filename="../exportworker.cpp" line="490"/> + <location filename="../exportworker.cpp" line="620"/> <source>Error while counting data to export from table %1: %2</source> <translation>Erreur lors du comptage des données à exporter de la table %1: %2</translation> </message> <message> - <location filename="../exportworker.cpp" line="506"/> + <location filename="../exportworker.cpp" line="636"/> <source>Error while counting data column width to export from table %1: %2</source> <translation>Erreur lors de la totalisation des données à exporter de la table %1: %2</translation> </message> @@ -444,18 +444,23 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma </message> <message> <location filename="../importworker.cpp" line="125"/> - <location filename="../importworker.cpp" line="152"/> - <location filename="../importworker.cpp" line="158"/> + <location filename="../importworker.cpp" line="162"/> + <location filename="../importworker.cpp" line="169"/> <source>Error while importing data: %1</source> <translation>Erreur lors de l'import des données: %1</translation> </message> <message> <location filename="../importworker.cpp" line="125"/> - <location filename="../importworker.cpp" line="158"/> + <location filename="../importworker.cpp" line="169"/> <source>Interrupted.</source> <comment>import process status update</comment> <translation>Transaction interrompue.</translation> </message> + <message> + <location filename="../importworker.cpp" line="157"/> + <source>Could not import data row number %1. The row was ignored. Problem details: %2</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>PluginManagerImpl</name> @@ -766,7 +771,7 @@ Tables, index, déclencheurs et vues copiés de la base de données %3 seront ma </message> <message> <location filename="../db/abstractdb2.h" line="796"/> - <location filename="../db/abstractdb3.h" line="1082"/> + <location filename="../db/abstractdb3.h" line="1092"/> <source>Result set expired or no row available.</source> <translation>Terminé ou aucune ligne valide.</translation> </message> @@ -836,13 +841,13 @@ Détails erreur: %2</translation> </message> <message> <location filename="../parser/sqlite2_parse.cpp" line="1904"/> - <location filename="../parser/sqlite3_parse.cpp" line="2170"/> + <location filename="../parser/sqlite3_parse.cpp" line="2167"/> <source>Parser stack overflow</source> <translation>Analyse dépassement pile</translation> </message> <message> <location filename="../parser/sqlite2_parse.cpp" line="4461"/> - <location filename="../parser/sqlite3_parse.cpp" line="5076"/> + <location filename="../parser/sqlite3_parse.cpp" line="5080"/> <source>Syntax error</source> <translation>Erreur de syntaxe </translation> </message> @@ -949,43 +954,47 @@ Détails erreur: %2</translation> <translation>Peuplement de la table</translation> </message> <message> - <location filename="../tablemodifier.cpp" line="107"/> + <location filename="../tablemodifier.cpp" line="108"/> <source>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.</source> <translation>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.</translation> </message> <message> - <location filename="../tablemodifier.cpp" line="379"/> + <location filename="../tablemodifier.cpp" line="380"/> <source>All columns indexed by the index %1 are gone. The index will not be recreated after table modification.</source> <translation>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.</translation> </message> <message> - <location filename="../tablemodifier.cpp" line="418"/> + <location filename="../tablemodifier.cpp" line="419"/> <source>There is problem with proper processing trigger %1. It may be not fully updated afterwards and will need your attention.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="465"/> + <location filename="../tablemodifier.cpp" line="466"/> <source>Cannot not update trigger %1 according to table %2 modification.</source> <translation>Impossible de mettre à jour le déclencheur%1 selon la modification de la table %2.</translation> </message> <message> - <location filename="../tablemodifier.cpp" line="433"/> + <location filename="../tablemodifier.cpp" line="587"/> + <location filename="../tablemodifier.cpp" line="611"/> + <location filename="../tablemodifier.cpp" line="630"/> + <source>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.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../tablemodifier.cpp" line="434"/> <source>All columns covered by the trigger %1 are gone. The trigger will not be recreated after table modification.</source> <translation>Toutes les colonnes couvertes par le déclencheur %1 sont faites. Le déclencheur ne sera pas recréé après la modification de la table.</translation> </message> <message> - <location filename="../tablemodifier.cpp" line="483"/> + <location filename="../tablemodifier.cpp" line="484"/> <source>Cannot not update view %1 according to table %2 modifications. The view will remain as it is.</source> <translation>Impossible de mettre à jour les modifications de la vue %1 issue de la table %2 La vue restera telque.</translation> </message> <message> - <location filename="../tablemodifier.cpp" line="580"/> - <location filename="../tablemodifier.cpp" line="601"/> - <location filename="../tablemodifier.cpp" line="619"/> <source>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.</source> - <translation>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.</translation> + <translation type="obsolete">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.</translation> </message> <message> <location filename="../viewmodifier.cpp" line="25"/> diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_pl.qm b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_pl.qm Binary files differindex 8d09cfa..6859097 100644 --- a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_pl.qm +++ b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_pl.qm diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_pl.ts b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_pl.ts index 9ca5ff5..7c061e5 100644 --- a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_pl.ts +++ b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_pl.ts @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS> -<TS version="2.0" language="pl_PL"> +<TS version="2.1" language="pl_PL"> <context> <name>AbstractDb</name> <message> @@ -147,30 +147,30 @@ <translation>Nie udało się dodać bazę danych %1: %2</translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="125"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="134"/> <source>Database %1 could not be updated, because of an error: %2</source> <translation>Nie udało się zaktualizować baza danych %1 z powodu błędu: %2</translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="299"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="328"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="308"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="337"/> <source>Database file doesn't exist.</source> <translation>Plik bazy danych nie istnieje.</translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="301"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="330"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="483"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="310"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="339"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="494"/> <source>No supporting plugin loaded.</source> <translation>Nie załadowano obsługującej wtyczki.</translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="402"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="413"/> <source>Database could not be initialized.</source> <translation>Nie udało się zainicjalizować bazy danych.</translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="412"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="423"/> <source>No suitable database driver plugin found.</source> <translation>Nie znaleziono odpowiedniej wtyczki sterownika.</translation> </message> @@ -323,7 +323,7 @@ Tabele, indeksy, wyzwalacze i widoki skopiowane do bazy danych %3 pozostaną na <context> <name>ExportWorker</name> <message> - <location filename="../exportworker.cpp" line="116"/> + <location filename="../exportworker.cpp" line="121"/> <source>Error while exporting query results: %1</source> <translation>Błąd podczas eksportowania wyników zapytania: %1</translation> </message> @@ -332,28 +332,28 @@ Tabele, indeksy, wyzwalacze i widoki skopiowane do bazy danych %3 pozostaną na <translation type="obsolete">Błąd podczas liczenia szerokości kolumn danych do eksportu wyników zapytania: %2</translation> </message> <message> - <location filename="../exportworker.cpp" line="175"/> + <location filename="../exportworker.cpp" line="201"/> <source>Error while counting data column width to export from query results: %1</source> <translation>Błąd podczas liczenia szerokości kolumn danych do eksportu wyników zapytania: %1</translation> </message> <message> - <location filename="../exportworker.cpp" line="275"/> - <location filename="../exportworker.cpp" line="326"/> + <location filename="../exportworker.cpp" line="353"/> + <location filename="../exportworker.cpp" line="411"/> <source>Could not parse %1 in order to export it. It will be excluded from the export output.</source> <translation>Nie udało się przeanalizować %1 w celu wyeksportowania. Element ten zostanie pominięty w wynikach eksportu.</translation> </message> <message> - <location filename="../exportworker.cpp" line="482"/> + <location filename="../exportworker.cpp" line="612"/> <source>Error while reading data to export from table %1: %2</source> <translation>Błąd podczas odczytu danych do eksportu z tabeli %1: %2</translation> </message> <message> - <location filename="../exportworker.cpp" line="490"/> + <location filename="../exportworker.cpp" line="620"/> <source>Error while counting data to export from table %1: %2</source> <translation>Błąd podczas liczenia danych do eksportu z tabeli %1: %2</translation> </message> <message> - <location filename="../exportworker.cpp" line="506"/> + <location filename="../exportworker.cpp" line="636"/> <source>Error while counting data column width to export from table %1: %2</source> <translation>Błąd podczas obliczania szerokości kolumn danych do eksportu z tabeli %1: %2</translation> </message> @@ -452,18 +452,23 @@ Tabele, indeksy, wyzwalacze i widoki skopiowane do bazy danych %3 pozostaną na </message> <message> <location filename="../importworker.cpp" line="125"/> - <location filename="../importworker.cpp" line="152"/> - <location filename="../importworker.cpp" line="158"/> + <location filename="../importworker.cpp" line="162"/> + <location filename="../importworker.cpp" line="169"/> <source>Error while importing data: %1</source> <translation>Błąd podczas importowania danych: %1</translation> </message> <message> <location filename="../importworker.cpp" line="125"/> - <location filename="../importworker.cpp" line="158"/> + <location filename="../importworker.cpp" line="169"/> <source>Interrupted.</source> <comment>import process status update</comment> <translation>Przerwano.</translation> </message> + <message> + <location filename="../importworker.cpp" line="157"/> + <source>Could not import data row number %1. The row was ignored. Problem details: %2</source> + <translation>Nie udało się zaimportować wiersza danych numer %1. Wiersz ten został zignorowany. Szczegóły problemu: %2</translation> + </message> </context> <context> <name>PluginManagerImpl</name> @@ -831,13 +836,13 @@ Szczegóły błędu: %2</translation> </message> <message> <location filename="../parser/sqlite2_parse.cpp" line="1904"/> - <location filename="../parser/sqlite3_parse.cpp" line="2170"/> + <location filename="../parser/sqlite3_parse.cpp" line="2167"/> <source>Parser stack overflow</source> <translation>Przeciążenie stosu analizatora.</translation> </message> <message> <location filename="../parser/sqlite2_parse.cpp" line="4461"/> - <location filename="../parser/sqlite3_parse.cpp" line="5076"/> + <location filename="../parser/sqlite3_parse.cpp" line="5080"/> <source>Syntax error</source> <translation>Błąd składni</translation> </message> @@ -944,43 +949,47 @@ Szczegóły błędu: %2</translation> <translation>Zaludnianie tabel</translation> </message> <message> - <location filename="../tablemodifier.cpp" line="107"/> + <location filename="../tablemodifier.cpp" line="108"/> <source>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.</source> <translation>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.</translation> </message> <message> - <location filename="../tablemodifier.cpp" line="379"/> + <location filename="../tablemodifier.cpp" line="380"/> <source>All columns indexed by the index %1 are gone. The index will not be recreated after table modification.</source> <translation>Wszystkie kolumny indeksowane przez indeks %1 już nie istnieją. Indeks ten nie będzie odtworzony po modyfikacji tabeli.</translation> </message> <message> - <location filename="../tablemodifier.cpp" line="418"/> + <location filename="../tablemodifier.cpp" line="419"/> <source>There is problem with proper processing trigger %1. It may be not fully updated afterwards and will need your attention.</source> <translation>Wystąpił problem z poprawnym przetworzeniem wyzwalacza %1. Może on zostać zaktualizowany tylko częściowo i będzie wymagał twojej uwagi.</translation> </message> <message> - <location filename="../tablemodifier.cpp" line="465"/> + <location filename="../tablemodifier.cpp" line="466"/> <source>Cannot not update trigger %1 according to table %2 modification.</source> <translation>Nie można zaktualizować wyzwalacza %1 zgodnie z modyfikacjami tabeli %2.</translation> </message> <message> - <location filename="../tablemodifier.cpp" line="433"/> + <location filename="../tablemodifier.cpp" line="587"/> + <location filename="../tablemodifier.cpp" line="611"/> + <location filename="../tablemodifier.cpp" line="630"/> + <source>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.</source> + <translation>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.</translation> + </message> + <message> + <location filename="../tablemodifier.cpp" line="434"/> <source>All columns covered by the trigger %1 are gone. The trigger will not be recreated after table modification.</source> <translation>Wszystkie kolumny obsługiwane przez wyzwalacz %1 już nie istnieją. Wyzwalacz ten nie będzie odtworzony po modyfikacji tabeli.</translation> </message> <message> - <location filename="../tablemodifier.cpp" line="483"/> + <location filename="../tablemodifier.cpp" line="484"/> <source>Cannot not update view %1 according to table %2 modifications. The view will remain as it is.</source> <translation>Nie można zaktualizować widoku %1 w związku z modyfikacjami tabeli %2. Widok pozostanie nienaruszony.</translation> </message> <message> - <location filename="../tablemodifier.cpp" line="580"/> - <location filename="../tablemodifier.cpp" line="601"/> - <location filename="../tablemodifier.cpp" line="619"/> <source>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.</source> - <translation>Jest problem ze zaktualizowaniem zapytania %1 w wyzwalaczu %2. Jedeno z podzapytań SELECT, które może odwoływać się do tabeli %2 nie może być poprawnie zmodyfikowane. Ręczna aktualizacja tego wyzwalacza może być niezbędna.</translation> + <translation type="obsolete">Jest problem ze zaktualizowaniem zapytania %1 w wyzwalaczu %2. Jedeno z podzapytań SELECT, 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.</translation> </message> <message> <location filename="../viewmodifier.cpp" line="25"/> @@ -1010,7 +1019,7 @@ Widok pozostanie nienaruszony.</translation> </message> <message> <location filename="../db/abstractdb2.h" line="796"/> - <location filename="../db/abstractdb3.h" line="1082"/> + <location filename="../db/abstractdb3.h" line="1092"/> <source>Result set expired or no row available.</source> <translation>Wyniki zapytania są nieaktualne, lub nie ma dostępnych wierszy.</translation> </message> diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_pt_BR.ts b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_pt_BR.ts index 5c08361..d22af44 100644 --- a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_pt_BR.ts +++ b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_pt_BR.ts @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS> -<TS version="2.0" language="pt_BR"> +<TS version="2.1" language="pt_BR"> <context> <name>AbstractDb</name> <message> @@ -147,30 +147,30 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="125"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="134"/> <source>Database %1 could not be updated, because of an error: %2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="299"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="328"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="308"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="337"/> <source>Database file doesn't exist.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="301"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="330"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="483"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="310"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="339"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="494"/> <source>No supporting plugin loaded.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="402"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="413"/> <source>Database could not be initialized.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="412"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="423"/> <source>No suitable database driver plugin found.</source> <translation type="unfinished"></translation> </message> @@ -318,33 +318,33 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> <context> <name>ExportWorker</name> <message> - <location filename="../exportworker.cpp" line="116"/> + <location filename="../exportworker.cpp" line="121"/> <source>Error while exporting query results: %1</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="175"/> + <location filename="../exportworker.cpp" line="201"/> <source>Error while counting data column width to export from query results: %1</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="275"/> - <location filename="../exportworker.cpp" line="326"/> + <location filename="../exportworker.cpp" line="353"/> + <location filename="../exportworker.cpp" line="411"/> <source>Could not parse %1 in order to export it. It will be excluded from the export output.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="482"/> + <location filename="../exportworker.cpp" line="612"/> <source>Error while reading data to export from table %1: %2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="490"/> + <location filename="../exportworker.cpp" line="620"/> <source>Error while counting data to export from table %1: %2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="506"/> + <location filename="../exportworker.cpp" line="636"/> <source>Error while counting data column width to export from table %1: %2</source> <translation type="unfinished"></translation> </message> @@ -443,18 +443,23 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> </message> <message> <location filename="../importworker.cpp" line="125"/> - <location filename="../importworker.cpp" line="152"/> - <location filename="../importworker.cpp" line="158"/> + <location filename="../importworker.cpp" line="162"/> + <location filename="../importworker.cpp" line="169"/> <source>Error while importing data: %1</source> <translation type="unfinished"></translation> </message> <message> <location filename="../importworker.cpp" line="125"/> - <location filename="../importworker.cpp" line="158"/> + <location filename="../importworker.cpp" line="169"/> <source>Interrupted.</source> <comment>import process status update</comment> <translation type="unfinished"></translation> </message> + <message> + <location filename="../importworker.cpp" line="157"/> + <source>Could not import data row number %1. The row was ignored. Problem details: %2</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>PluginManagerImpl</name> @@ -765,7 +770,7 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> </message> <message> <location filename="../db/abstractdb2.h" line="796"/> - <location filename="../db/abstractdb3.h" line="1082"/> + <location filename="../db/abstractdb3.h" line="1092"/> <source>Result set expired or no row available.</source> <translation type="unfinished"></translation> </message> @@ -834,13 +839,13 @@ Error details: %2</source> </message> <message> <location filename="../parser/sqlite2_parse.cpp" line="1904"/> - <location filename="../parser/sqlite3_parse.cpp" line="2170"/> + <location filename="../parser/sqlite3_parse.cpp" line="2167"/> <source>Parser stack overflow</source> <translation type="unfinished"></translation> </message> <message> <location filename="../parser/sqlite2_parse.cpp" line="4461"/> - <location filename="../parser/sqlite3_parse.cpp" line="5076"/> + <location filename="../parser/sqlite3_parse.cpp" line="5080"/> <source>Syntax error</source> <translation type="unfinished"></translation> </message> @@ -947,41 +952,41 @@ Error details: %2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="107"/> + <location filename="../tablemodifier.cpp" line="108"/> <source>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.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="379"/> + <location filename="../tablemodifier.cpp" line="380"/> <source>All columns indexed by the index %1 are gone. The index will not be recreated after table modification.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="418"/> + <location filename="../tablemodifier.cpp" line="419"/> <source>There is problem with proper processing trigger %1. It may be not fully updated afterwards and will need your attention.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="465"/> + <location filename="../tablemodifier.cpp" line="466"/> <source>Cannot not update trigger %1 according to table %2 modification.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="433"/> - <source>All columns covered by the trigger %1 are gone. The trigger will not be recreated after table modification.</source> + <location filename="../tablemodifier.cpp" line="587"/> + <location filename="../tablemodifier.cpp" line="611"/> + <location filename="../tablemodifier.cpp" line="630"/> + <source>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.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="483"/> - <source>Cannot not update view %1 according to table %2 modifications. -The view will remain as it is.</source> + <location filename="../tablemodifier.cpp" line="434"/> + <source>All columns covered by the trigger %1 are gone. The trigger will not be recreated after table modification.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="580"/> - <location filename="../tablemodifier.cpp" line="601"/> - <location filename="../tablemodifier.cpp" line="619"/> - <source>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.</source> + <location filename="../tablemodifier.cpp" line="484"/> + <source>Cannot not update view %1 according to table %2 modifications. +The view will remain as it is.</source> <translation type="unfinished"></translation> </message> <message> diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_ru.qm b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_ru.qm Binary files differindex 0b3d737..24f5549 100644 --- a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_ru.qm +++ b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_ru.qm diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_ru.ts b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_ru.ts index 6890ba9..ca7fc68 100644 --- a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_ru.ts +++ b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_ru.ts @@ -147,31 +147,31 @@ <translation>Не удалось добавить базу данных %1: %2</translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="125"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="134"/> <source>Database %1 could not be updated, because of an error: %2</source> <translation>Невозможно обновить базу данных %1 из-за ошибки: %2</translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="299"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="328"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="308"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="337"/> <source>Database file doesn't exist.</source> <translation>Файл базы данных не существует.</translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="301"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="330"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="483"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="310"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="339"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="494"/> <source>No supporting plugin loaded.</source> <translatorcomment>Unclear error string. Checking the source didn't help.</translatorcomment> <translation>Модуль поддержки не загружен.</translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="402"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="413"/> <source>Database could not be initialized.</source> <translation>Невозможно инициализировать базу данных.</translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="412"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="423"/> <source>No suitable database driver plugin found.</source> <translation>Не найден подходящий драйвер базы данных.</translation> </message> @@ -320,33 +320,33 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> <context> <name>ExportWorker</name> <message> - <location filename="../exportworker.cpp" line="116"/> + <location filename="../exportworker.cpp" line="121"/> <source>Error while exporting query results: %1</source> <translation>Ошибка при экспорте результатов запроса: %1</translation> </message> <message> - <location filename="../exportworker.cpp" line="175"/> + <location filename="../exportworker.cpp" line="201"/> <source>Error while counting data column width to export from query results: %1</source> <translation>Ошибка при подсчёте ширины столбца данных для экспорта результатов запроса: %1</translation> </message> <message> - <location filename="../exportworker.cpp" line="275"/> - <location filename="../exportworker.cpp" line="326"/> + <location filename="../exportworker.cpp" line="353"/> + <location filename="../exportworker.cpp" line="411"/> <source>Could not parse %1 in order to export it. It will be excluded from the export output.</source> <translation>Невозможно проанализировать структуру %1. Данный объект будет исключён при выполнении экспорта.</translation> </message> <message> - <location filename="../exportworker.cpp" line="482"/> + <location filename="../exportworker.cpp" line="612"/> <source>Error while reading data to export from table %1: %2</source> <translation>Ошибка при считывании данных для экспорта из таблицы %1: %2</translation> </message> <message> - <location filename="../exportworker.cpp" line="490"/> + <location filename="../exportworker.cpp" line="620"/> <source>Error while counting data to export from table %1: %2</source> <translation>Ошибка при подсчёте количества данных для экспорта из таблицы %1: %2</translation> </message> <message> - <location filename="../exportworker.cpp" line="506"/> + <location filename="../exportworker.cpp" line="636"/> <source>Error while counting data column width to export from table %1: %2</source> <translation>Ошибка при подсчёте ширины столбца данных для экспорта из таблицы %1: %2</translation> </message> @@ -445,18 +445,23 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> </message> <message> <location filename="../importworker.cpp" line="125"/> - <location filename="../importworker.cpp" line="152"/> - <location filename="../importworker.cpp" line="158"/> + <location filename="../importworker.cpp" line="162"/> + <location filename="../importworker.cpp" line="169"/> <source>Error while importing data: %1</source> <translation>Ошибка при импорте данных: %1</translation> </message> <message> <location filename="../importworker.cpp" line="125"/> - <location filename="../importworker.cpp" line="158"/> + <location filename="../importworker.cpp" line="169"/> <source>Interrupted.</source> <comment>import process status update</comment> <translation>Прервано.</translation> </message> + <message> + <location filename="../importworker.cpp" line="157"/> + <source>Could not import data row number %1. The row was ignored. Problem details: %2</source> + <translation>Невозможно импортировать строку данных № %1. Строка пропущена. Подробности проблемы: %2</translation> + </message> </context> <context> <name>PluginManagerImpl</name> @@ -767,7 +772,7 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> </message> <message> <location filename="../db/abstractdb2.h" line="796"/> - <location filename="../db/abstractdb3.h" line="1082"/> + <location filename="../db/abstractdb3.h" line="1092"/> <source>Result set expired or no row available.</source> <translation>Результирующая выборка устарела или ни одна строка не доступна.</translation> </message> @@ -836,13 +841,13 @@ Error details: %2</source> </message> <message> <location filename="../parser/sqlite2_parse.cpp" line="1904"/> - <location filename="../parser/sqlite3_parse.cpp" line="2170"/> + <location filename="../parser/sqlite3_parse.cpp" line="2167"/> <source>Parser stack overflow</source> <translation>Переполнение стека анализатора</translation> </message> <message> <location filename="../parser/sqlite2_parse.cpp" line="4461"/> - <location filename="../parser/sqlite3_parse.cpp" line="5076"/> + <location filename="../parser/sqlite3_parse.cpp" line="5080"/> <source>Syntax error</source> <translation>Синтаксическая ошибка</translation> </message> @@ -949,43 +954,47 @@ Error details: %2</source> <translation>Заполнение таблиц</translation> </message> <message> - <location filename="../tablemodifier.cpp" line="107"/> + <location filename="../tablemodifier.cpp" line="108"/> <source>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.</source> <translation>Таблица %1 ссылается на таблицу %2, но описание внешнего ключа не будет обновлено для описания новой таблицы из-за проблем с анализом DDL таблицы %3.</translation> </message> <message> - <location filename="../tablemodifier.cpp" line="379"/> + <location filename="../tablemodifier.cpp" line="380"/> <source>All columns indexed by the index %1 are gone. The index will not be recreated after table modification.</source> <translation>Все столбцы, проиндексированные индексом %1, удалены. Индекс не будет воссоздан после модификации таблицы.</translation> </message> <message> - <location filename="../tablemodifier.cpp" line="418"/> + <location filename="../tablemodifier.cpp" line="419"/> <source>There is problem with proper processing trigger %1. It may be not fully updated afterwards and will need your attention.</source> - <translation type="unfinished"></translation> + <translation>Возникла проблема при обработке триггера %1. Впоследствии он не будет полностью обновлён и потребует вашего внимания.</translation> </message> <message> - <location filename="../tablemodifier.cpp" line="465"/> + <location filename="../tablemodifier.cpp" line="466"/> <source>Cannot not update trigger %1 according to table %2 modification.</source> <translation>Невозможно обновить триггер %1 в соответствии с модификацией таблицы %2.</translation> </message> <message> - <location filename="../tablemodifier.cpp" line="433"/> + <location filename="../tablemodifier.cpp" line="587"/> + <location filename="../tablemodifier.cpp" line="611"/> + <location filename="../tablemodifier.cpp" line="630"/> + <source>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.</source> + <translation>Возникла проблема при обновлении конструкции %1 внутри триггера %2. Одна из вложенных конструкций %1, которая возможно ссылается на таблицу %3, не может быть корректно модифицирована. Возможно необходима ручная правка триггера.</translation> + </message> + <message> + <location filename="../tablemodifier.cpp" line="434"/> <source>All columns covered by the trigger %1 are gone. The trigger will not be recreated after table modification.</source> <translation>Все столбцы, затронутые в триггере %1, удалены. Триггер не будет воссоздан после модификации таблицы.</translation> </message> <message> - <location filename="../tablemodifier.cpp" line="483"/> + <location filename="../tablemodifier.cpp" line="484"/> <source>Cannot not update view %1 according to table %2 modifications. The view will remain as it is.</source> <translation>Невозможно обновить представление %1 в соответствии с модификациями таблицы %2. Представление останется как есть.</translation> </message> <message> - <location filename="../tablemodifier.cpp" line="580"/> - <location filename="../tablemodifier.cpp" line="601"/> - <location filename="../tablemodifier.cpp" line="619"/> <source>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.</source> - <translation>Возникла проблема при обновлении конструкции %1 внутри триггера %2. Одна из вложенных конструкций SELECT, которая возможно ссылается на таблицу %3, не может быть корректно модифицирована. Возможно необходима ручная правка триггера.</translation> + <translation type="obsolete">Возникла проблема при обновлении конструкции %1 внутри триггера %2. Одна из вложенных конструкций SELECT, которая возможно ссылается на таблицу %3, не может быть корректно модифицирована. Возможно необходима ручная правка триггера.</translation> </message> <message> <location filename="../viewmodifier.cpp" line="25"/> diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_sk.qm b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_sk.qm Binary files differindex 1776294..e857185 100644 --- a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_sk.qm +++ b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_sk.qm diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_sk.ts b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_sk.ts index 497b7fe..24da18a 100644 --- a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_sk.ts +++ b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_sk.ts @@ -12,7 +12,7 @@ <message> <location filename="../db/abstractdb.cpp" line="603"/> <source>Error attaching database %1: %2</source> - <translation type="unfinished"></translation> + <translation>Chyba pri pripájaní databázy %1: %2</translation> </message> </context> <context> @@ -20,7 +20,7 @@ <message> <location filename="../services/bugreporter.cpp" line="46"/> <source>Invalid login or password</source> - <translation type="unfinished"></translation> + <translation>Neplatné meno alebo heslo</translation> </message> </context> <context> @@ -144,33 +144,33 @@ <message> <location filename="../services/impl/dbmanagerimpl.cpp" line="63"/> <source>Could not add database %1: %2</source> - <translation type="unfinished"></translation> + <translation>Nemôžem pridať databázu %1: %2</translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="125"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="134"/> <source>Database %1 could not be updated, because of an error: %2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="299"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="328"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="308"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="337"/> <source>Database file doesn't exist.</source> - <translation type="unfinished"></translation> + <translation>Databázový súbor neexistuje.</translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="301"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="330"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="483"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="310"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="339"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="494"/> <source>No supporting plugin loaded.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="402"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="413"/> <source>Database could not be initialized.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="412"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="423"/> <source>No suitable database driver plugin found.</source> <translation type="unfinished"></translation> </message> @@ -181,7 +181,7 @@ <location filename="../dbobjectorganizer.cpp" line="380"/> <location filename="../dbobjectorganizer.cpp" line="412"/> <source>Error while creating table in target database: %1</source> - <translation type="unfinished"></translation> + <translation>Vyskytla sa chyba počas vytvárania tabuľky v cieľovej databáze: %1</translation> </message> <message> <location filename="../dbobjectorganizer.cpp" line="380"/> @@ -232,17 +232,17 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> <message> <location filename="../dbversionconverter.cpp" line="923"/> <source>Target file exists, but could not be overwritten.</source> - <translation type="unfinished"></translation> + <translation>Cieľový súbor existuje ale nemôže byť prepísaný.</translation> </message> <message> <location filename="../dbversionconverter.cpp" line="942"/> <source>Could not find proper database plugin to create target database.</source> - <translation type="unfinished"></translation> + <translation>Nieje možné nájsť správny databázový plugin pre vytvorenie cieľovej databázy.</translation> </message> <message> <location filename="../dbversionconverter.cpp" line="1176"/> <source>Error while converting database: %1</source> - <translation type="unfinished"></translation> + <translation>Vyskytla sa chyba počas konvertovania databázy: %1</translation> </message> </context> <context> @@ -297,54 +297,54 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> <message> <location filename="../services/exportmanager.cpp" line="218"/> <source>Export to the clipboard was successful.</source> - <translation type="unfinished"></translation> + <translation>Export do schránky bol úspešný.</translation> </message> <message> <location filename="../services/exportmanager.cpp" line="222"/> <source>Export to the file '%1' was successful.</source> - <translation type="unfinished"></translation> + <translation>Export do súboru '%1' bol úspešný.</translation> </message> <message> <location filename="../services/exportmanager.cpp" line="224"/> <source>Export was successful.</source> - <translation type="unfinished"></translation> + <translation>Export bol úspešný.</translation> </message> <message> <location filename="../services/exportmanager.cpp" line="266"/> <source>Could not export to file %1. File cannot be open for writting.</source> - <translation type="unfinished"></translation> + <translation>Nemôžem exportovať do súboru %1.Súbor nieje možné otvoriť pre zápis.</translation> </message> </context> <context> <name>ExportWorker</name> <message> - <location filename="../exportworker.cpp" line="116"/> + <location filename="../exportworker.cpp" line="121"/> <source>Error while exporting query results: %1</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="175"/> + <location filename="../exportworker.cpp" line="201"/> <source>Error while counting data column width to export from query results: %1</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="275"/> - <location filename="../exportworker.cpp" line="326"/> + <location filename="../exportworker.cpp" line="353"/> + <location filename="../exportworker.cpp" line="411"/> <source>Could not parse %1 in order to export it. It will be excluded from the export output.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="482"/> + <location filename="../exportworker.cpp" line="612"/> <source>Error while reading data to export from table %1: %2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="490"/> + <location filename="../exportworker.cpp" line="620"/> <source>Error while counting data to export from table %1: %2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="506"/> + <location filename="../exportworker.cpp" line="636"/> <source>Error while counting data column width to export from table %1: %2</source> <translation type="unfinished"></translation> </message> @@ -443,18 +443,23 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> </message> <message> <location filename="../importworker.cpp" line="125"/> - <location filename="../importworker.cpp" line="152"/> - <location filename="../importworker.cpp" line="158"/> + <location filename="../importworker.cpp" line="162"/> + <location filename="../importworker.cpp" line="169"/> <source>Error while importing data: %1</source> <translation type="unfinished"></translation> </message> <message> <location filename="../importworker.cpp" line="125"/> - <location filename="../importworker.cpp" line="158"/> + <location filename="../importworker.cpp" line="169"/> <source>Interrupted.</source> <comment>import process status update</comment> <translation type="unfinished"></translation> </message> + <message> + <location filename="../importworker.cpp" line="157"/> + <source>Could not import data row number %1. The row was ignored. Problem details: %2</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>PluginManagerImpl</name> @@ -497,7 +502,7 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> <location filename="../plugins/populateconstant.cpp" line="10"/> <source>Constant</source> <comment>populate constant plugin name</comment> - <translation type="unfinished"></translation> + <translation>Konštanta</translation> </message> </context> <context> @@ -505,7 +510,7 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> <message> <location filename="../plugins/populateconstant.ui" line="20"/> <source>Constant value:</source> - <translation type="unfinished"></translation> + <translation>Hodnota konštanty:</translation> </message> </context> <context> @@ -514,7 +519,7 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> <location filename="../plugins/populatedictionary.cpp" line="15"/> <source>Dictionary</source> <comment>dictionary populating plugin name</comment> - <translation type="unfinished"></translation> + <translation>Slovník</translation> </message> </context> <context> @@ -565,7 +570,7 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> <message> <location filename="../services/populatemanager.cpp" line="88"/> <source>Table '%1' populated successfully.</source> - <translation type="unfinished"></translation> + <translation>Tabuľka %1 úspešne naplnená.</translation> </message> </context> <context> @@ -573,7 +578,7 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> <message> <location filename="../plugins/populaterandom.cpp" line="12"/> <source>Random number</source> - <translation type="unfinished"></translation> + <translation>Náhodné číslo</translation> </message> </context> <context> @@ -614,7 +619,7 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> <message> <location filename="../plugins/populaterandomtext.cpp" line="12"/> <source>Random text</source> - <translation type="unfinished"></translation> + <translation>Náhodný text</translation> </message> </context> <context> @@ -690,7 +695,7 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> <message> <location filename="../plugins/populatescript.cpp" line="13"/> <source>Script</source> - <translation type="unfinished"></translation> + <translation>Skript</translation> </message> </context> <context> @@ -721,7 +726,7 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> <message> <location filename="../plugins/populatesequence.cpp" line="13"/> <source>Sequence</source> - <translation type="unfinished"></translation> + <translation>Sekvencia</translation> </message> </context> <context> @@ -765,7 +770,7 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> </message> <message> <location filename="../db/abstractdb2.h" line="796"/> - <location filename="../db/abstractdb3.h" line="1082"/> + <location filename="../db/abstractdb3.h" line="1092"/> <source>Result set expired or no row available.</source> <translation type="unfinished"></translation> </message> @@ -834,15 +839,15 @@ Error details: %2</source> </message> <message> <location filename="../parser/sqlite2_parse.cpp" line="1904"/> - <location filename="../parser/sqlite3_parse.cpp" line="2170"/> + <location filename="../parser/sqlite3_parse.cpp" line="2167"/> <source>Parser stack overflow</source> <translation type="unfinished"></translation> </message> <message> <location filename="../parser/sqlite2_parse.cpp" line="4461"/> - <location filename="../parser/sqlite3_parse.cpp" line="5076"/> + <location filename="../parser/sqlite3_parse.cpp" line="5080"/> <source>Syntax error</source> - <translation type="unfinished"></translation> + <translation>Chyba syntaxe</translation> </message> <message> <location filename="../plugins/populatedictionary.cpp" line="30"/> @@ -926,7 +931,7 @@ Error details: %2</source> <location filename="../sqlitestudio.cpp" line="291"/> <source>Scripting languages</source> <comment>plugin category name</comment> - <translation type="unfinished"></translation> + <translation>Skriptovacie jazyky</translation> </message> <message> <location filename="../sqlitestudio.cpp" line="292"/> @@ -947,41 +952,41 @@ Error details: %2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="107"/> + <location filename="../tablemodifier.cpp" line="108"/> <source>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.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="379"/> + <location filename="../tablemodifier.cpp" line="380"/> <source>All columns indexed by the index %1 are gone. The index will not be recreated after table modification.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="418"/> + <location filename="../tablemodifier.cpp" line="419"/> <source>There is problem with proper processing trigger %1. It may be not fully updated afterwards and will need your attention.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="465"/> + <location filename="../tablemodifier.cpp" line="466"/> <source>Cannot not update trigger %1 according to table %2 modification.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="433"/> - <source>All columns covered by the trigger %1 are gone. The trigger will not be recreated after table modification.</source> + <location filename="../tablemodifier.cpp" line="587"/> + <location filename="../tablemodifier.cpp" line="611"/> + <location filename="../tablemodifier.cpp" line="630"/> + <source>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.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="483"/> - <source>Cannot not update view %1 according to table %2 modifications. -The view will remain as it is.</source> + <location filename="../tablemodifier.cpp" line="434"/> + <source>All columns covered by the trigger %1 are gone. The trigger will not be recreated after table modification.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="580"/> - <location filename="../tablemodifier.cpp" line="601"/> - <location filename="../tablemodifier.cpp" line="619"/> - <source>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.</source> + <location filename="../tablemodifier.cpp" line="484"/> + <source>Cannot not update view %1 according to table %2 modifications. +The view will remain as it is.</source> <translation type="unfinished"></translation> </message> <message> @@ -1048,31 +1053,32 @@ The view will remain as it is.</source> <location filename="../sqlhistorymodel.cpp" line="30"/> <source>Database</source> <comment>sql history header</comment> - <translation type="unfinished"></translation> + <translatorcomment>Dátum spustenia</translatorcomment> + <translation>Databáza</translation> </message> <message> <location filename="../sqlhistorymodel.cpp" line="32"/> <source>Execution date</source> <comment>sql history header</comment> - <translation type="unfinished"></translation> + <translation>Dátum spustenia</translation> </message> <message> <location filename="../sqlhistorymodel.cpp" line="34"/> <source>Time spent</source> <comment>sql history header</comment> - <translation type="unfinished"></translation> + <translation>Trvanie dotazu</translation> </message> <message> <location filename="../sqlhistorymodel.cpp" line="36"/> <source>Rows affected</source> <comment>sql history header</comment> - <translation type="unfinished"></translation> + <translation>Počet riadkov</translation> </message> <message> <location filename="../sqlhistorymodel.cpp" line="38"/> <source>SQL</source> <comment>sql history header</comment> - <translation type="unfinished"></translation> + <translation>SQL</translation> </message> </context> <context> @@ -1256,12 +1262,12 @@ Details: %3</source> <location filename="../services/updatemanager.cpp" line="921"/> <location filename="../services/updatemanager.cpp" line="930"/> <source>Could not rename directory %1 to %2.</source> - <translation type="unfinished"></translation> + <translation>Nemôžem premenovať adresár %1na %2.</translation> </message> <message> <location filename="../services/updatemanager.cpp" line="943"/> <source>Could not delete directory %1.</source> - <translation type="unfinished"></translation> + <translation>Nemôžem vymazať adresár %1.</translation> </message> <message> <location filename="../services/updatemanager.cpp" line="959"/> diff --git a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_zh_CN.ts b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_zh_CN.ts index 0cfd10d..1c95d67 100644 --- a/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_zh_CN.ts +++ b/SQLiteStudio3/coreSQLiteStudio/translations/coreSQLiteStudio_zh_CN.ts @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS> -<TS version="2.0" language="zh_CN"> +<TS version="2.1" language="zh_CN"> <context> <name>AbstractDb</name> <message> @@ -147,30 +147,30 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="125"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="134"/> <source>Database %1 could not be updated, because of an error: %2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="299"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="328"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="308"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="337"/> <source>Database file doesn't exist.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="301"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="330"/> - <location filename="../services/impl/dbmanagerimpl.cpp" line="483"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="310"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="339"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="494"/> <source>No supporting plugin loaded.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="402"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="413"/> <source>Database could not be initialized.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../services/impl/dbmanagerimpl.cpp" line="412"/> + <location filename="../services/impl/dbmanagerimpl.cpp" line="423"/> <source>No suitable database driver plugin found.</source> <translation type="unfinished"></translation> </message> @@ -318,33 +318,33 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> <context> <name>ExportWorker</name> <message> - <location filename="../exportworker.cpp" line="116"/> + <location filename="../exportworker.cpp" line="121"/> <source>Error while exporting query results: %1</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="175"/> + <location filename="../exportworker.cpp" line="201"/> <source>Error while counting data column width to export from query results: %1</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="275"/> - <location filename="../exportworker.cpp" line="326"/> + <location filename="../exportworker.cpp" line="353"/> + <location filename="../exportworker.cpp" line="411"/> <source>Could not parse %1 in order to export it. It will be excluded from the export output.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="482"/> + <location filename="../exportworker.cpp" line="612"/> <source>Error while reading data to export from table %1: %2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="490"/> + <location filename="../exportworker.cpp" line="620"/> <source>Error while counting data to export from table %1: %2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../exportworker.cpp" line="506"/> + <location filename="../exportworker.cpp" line="636"/> <source>Error while counting data column width to export from table %1: %2</source> <translation type="unfinished"></translation> </message> @@ -443,18 +443,23 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> </message> <message> <location filename="../importworker.cpp" line="125"/> - <location filename="../importworker.cpp" line="152"/> - <location filename="../importworker.cpp" line="158"/> + <location filename="../importworker.cpp" line="162"/> + <location filename="../importworker.cpp" line="169"/> <source>Error while importing data: %1</source> <translation type="unfinished"></translation> </message> <message> <location filename="../importworker.cpp" line="125"/> - <location filename="../importworker.cpp" line="158"/> + <location filename="../importworker.cpp" line="169"/> <source>Interrupted.</source> <comment>import process status update</comment> <translation type="unfinished"></translation> </message> + <message> + <location filename="../importworker.cpp" line="157"/> + <source>Could not import data row number %1. The row was ignored. Problem details: %2</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>PluginManagerImpl</name> @@ -765,7 +770,7 @@ Tables, indexes, triggers and views copied to database %3 will remain.</source> </message> <message> <location filename="../db/abstractdb2.h" line="796"/> - <location filename="../db/abstractdb3.h" line="1082"/> + <location filename="../db/abstractdb3.h" line="1092"/> <source>Result set expired or no row available.</source> <translation type="unfinished"></translation> </message> @@ -834,13 +839,13 @@ Error details: %2</source> </message> <message> <location filename="../parser/sqlite2_parse.cpp" line="1904"/> - <location filename="../parser/sqlite3_parse.cpp" line="2170"/> + <location filename="../parser/sqlite3_parse.cpp" line="2167"/> <source>Parser stack overflow</source> <translation type="unfinished"></translation> </message> <message> <location filename="../parser/sqlite2_parse.cpp" line="4461"/> - <location filename="../parser/sqlite3_parse.cpp" line="5076"/> + <location filename="../parser/sqlite3_parse.cpp" line="5080"/> <source>Syntax error</source> <translation type="unfinished"></translation> </message> @@ -947,41 +952,41 @@ Error details: %2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="107"/> + <location filename="../tablemodifier.cpp" line="108"/> <source>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.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="379"/> + <location filename="../tablemodifier.cpp" line="380"/> <source>All columns indexed by the index %1 are gone. The index will not be recreated after table modification.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="418"/> + <location filename="../tablemodifier.cpp" line="419"/> <source>There is problem with proper processing trigger %1. It may be not fully updated afterwards and will need your attention.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="465"/> + <location filename="../tablemodifier.cpp" line="466"/> <source>Cannot not update trigger %1 according to table %2 modification.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="433"/> - <source>All columns covered by the trigger %1 are gone. The trigger will not be recreated after table modification.</source> + <location filename="../tablemodifier.cpp" line="587"/> + <location filename="../tablemodifier.cpp" line="611"/> + <location filename="../tablemodifier.cpp" line="630"/> + <source>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.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="483"/> - <source>Cannot not update view %1 according to table %2 modifications. -The view will remain as it is.</source> + <location filename="../tablemodifier.cpp" line="434"/> + <source>All columns covered by the trigger %1 are gone. The trigger will not be recreated after table modification.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../tablemodifier.cpp" line="580"/> - <location filename="../tablemodifier.cpp" line="601"/> - <location filename="../tablemodifier.cpp" line="619"/> - <source>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.</source> + <location filename="../tablemodifier.cpp" line="484"/> + <source>Cannot not update view %1 according to table %2 modifications. +The view will remain as it is.</source> <translation type="unfinished"></translation> </message> <message> diff --git a/SQLiteStudio3/coreSQLiteStudio/tsvserializer.cpp b/SQLiteStudio3/coreSQLiteStudio/tsvserializer.cpp index 486763b..a42c76d 100644 --- a/SQLiteStudio3/coreSQLiteStudio/tsvserializer.cpp +++ b/SQLiteStudio3/coreSQLiteStudio/tsvserializer.cpp @@ -45,7 +45,39 @@ QList<QStringList> TsvSerializer::deserialize(const QString& data) { QList<QStringList> rows; QStringList cells; + QStringList tokens; + QStringList parts = data.split(columnSeparator); + for (const QString& part : parts) + { + if (!part.contains(rowSeparator)) + { + cells << part; + continue; + } + + tokens = tokenizeStrWithRowSeparator(part); + for (const QString& token : tokens) + { + if (token != rowSeparator) + { + cells << token; + continue; + } + + rows << cells; + cells.clear(); + } + } + + if ((cells.size() > 0 && !cells.first().isEmpty()) || cells.size() > 1) + rows << cells; + return rows; +} + +QStringList TsvSerializer::tokenizeStrWithRowSeparator(const QString& data) +{ + QStringList tokens; int pos = 0; int lgt = data.length(); bool quotes = false; @@ -59,32 +91,27 @@ QList<QStringList> TsvSerializer::deserialize(const QString& data) { if (field.isEmpty()) quotes = true; - else - field += c; + + field += c; } else if (quotes && c == '"' ) { + field += c; if (pos + 1 < data.length() && data[pos+1] == '"' ) { - field += c; - pos++; + field += c; + pos++; } else { - quotes = false; + quotes = false; } } - else if (!quotes && c == columnSeparator) - { - cells << field; - field.clear(); - } else if (!quotes && c == rowSeparator) { - cells << field; - rows << cells; - cells.clear(); + tokens << flushToken(field); field.clear(); + tokens << QString(c); } else { @@ -94,10 +121,19 @@ QList<QStringList> TsvSerializer::deserialize(const QString& data) } if (field.size() > 0) - cells << field; + tokens << flushToken(field); - if (cells.size() > 0) - rows << cells; + return tokens; +} - return rows; +QString TsvSerializer::flushToken(const QString& token) +{ + if (!token.startsWith('"') || !token.contains(rowSeparator)) + return token; + + int decr = 1; + if (token.endsWith('"')) + decr++; + + return token.mid(1, token.length() - decr).replace("\"\"", "\""); } diff --git a/SQLiteStudio3/coreSQLiteStudio/tsvserializer.h b/SQLiteStudio3/coreSQLiteStudio/tsvserializer.h index efb3934..27d1da6 100644 --- a/SQLiteStudio3/coreSQLiteStudio/tsvserializer.h +++ b/SQLiteStudio3/coreSQLiteStudio/tsvserializer.h @@ -13,6 +13,8 @@ class API_EXPORT TsvSerializer static QList<QStringList> deserialize(const QString& data); private: + static QStringList tokenizeStrWithRowSeparator(const QString& data); + static QString flushToken(const QString& token); static QString rowSeparator; static QString columnSeparator; }; |
