diff --git a/src/sqlitedb.cpp b/src/sqlitedb.cpp index f72f81a9..9d552616 100644 --- a/src/sqlitedb.cpp +++ b/src/sqlitedb.cpp @@ -484,6 +484,86 @@ bool DBBrowserDB::getRow(const QString& sTableName, int rowid, QList return ret; } +int64_t DBBrowserDB::max(const sqlb::Table& t, sqlb::FieldPtr field) const +{ + QString sQuery = QString("SELECT MAX(`%2`) from `%1`;").arg(t.name()).arg(field->name()); + QByteArray utf8Query = sQuery.toUtf8(); + sqlite3_stmt *stmt; + int64_t ret = 0; + + int status = sqlite3_prepare_v2(_db, utf8Query, utf8Query.size(), &stmt, NULL); + if(SQLITE_OK == status) + { + // even this is a while loop, the statement should always only return 1 row + while(sqlite3_step(stmt) == SQLITE_ROW) + { + if(sqlite3_column_count(stmt) == 1) + { + ret = sqlite3_column_int64(stmt, 0); + } + } + } + sqlite3_finalize(stmt); + + return ret; +} + +QString DBBrowserDB::emptyInsertStmt(const sqlb::Table& t, int pk_value) const +{ + QString stmt = QString("INSERT INTO `%1`").arg(t.name()); + + QStringList vals; + QStringList fields; + foreach(sqlb::FieldPtr f, t.fields()) { + if( f->primaryKey() && f->isInteger() ) + { + fields << f->name(); + + if(pk_value != -1) + vals << QString::number(pk_value); + else + { + if(f->notnull()) + { + int64_t maxval = this->max(t, f); + vals << QString::number(maxval + 1); + } + else + { + vals << "NULL"; + } + } + } else if(f->notnull() && f->defaultValue().length() == 0) { + fields << f->name(); + + if(f->isInteger()) + vals << "0"; + else + vals << "''"; + } else { + // don't insert into fields with a default value + // or we will never see it. + if(f->defaultValue().length() == 0) + { + fields << f->name(); + vals << "NULL"; + } + } + } + + if(!fields.empty()) + { + stmt.append("(`"); + stmt.append(fields.join("`,`")); + stmt.append("`)"); + } + stmt.append(" VALUES ("); + stmt.append(vals.join(",")); + stmt.append(");"); + + return stmt; +} + int DBBrowserDB::addRecord(const QString& sTableName) { char *errmsg; @@ -500,9 +580,9 @@ int DBBrowserDB::addRecord(const QString& sTableName) SqliteTableModel m(this, this); m.setQuery(QString("SELECT MAX(`%1`) FROM `%2`;").arg(table.rowidColumn()).arg(sTableName)); pk_value = m.data(m.index(0, 0)).toInt() + 1; - sInsertstmt = table.emptyInsertStmt(pk_value); + sInsertstmt = emptyInsertStmt(table, pk_value); } else { - sInsertstmt = table.emptyInsertStmt(); + sInsertstmt = emptyInsertStmt(table); } lastErrorMessage = ""; diff --git a/src/sqlitedb.h b/src/sqlitedb.h index fd86b200..86385ced 100644 --- a/src/sqlitedb.h +++ b/src/sqlitedb.h @@ -66,8 +66,23 @@ public: */ bool getRow(const QString& sTableName, int rowid, QList& rowdata); + /** + * @brief max Queries the table t for the max value of field. + * @param t Table to query + * @param field Field to get the max value + * @return the max value of the field or 0 on error + */ + int64_t max(const sqlb::Table& t, sqlb::FieldPtr field) const; + void updateSchema(); int addRecord(const QString& sTableName); + + /** + * @brief Creates an empty insert statement. + * @param pk_value This optional parameter can be used to manually set a specific value for the primary key column + * @return An sqlite conform INSERT INTO statement with empty values. (NULL,'',0) + */ + QString emptyInsertStmt(const sqlb::Table& t, int pk_value = -1) const; bool deleteRecord(const QString& table, int rowid); bool updateRecord(const QString& table, const QString& column, int row, const QByteArray& value); diff --git a/src/sqlitetypes.cpp b/src/sqlitetypes.cpp index c93fa135..3bccce9c 100644 --- a/src/sqlitetypes.cpp +++ b/src/sqlitetypes.cpp @@ -166,52 +166,6 @@ QPair Table::parseSQL(const QString &sSQL) return qMakePair(Table(""), false); } -QString Table::emptyInsertStmt(int pk_value) const -{ - QString stmt = QString("INSERT INTO `%1`").arg(m_name); - - QStringList vals; - QStringList fields; - foreach(FieldPtr f, m_fields) { - if( f->primaryKey() && f->isInteger() ) - { - fields << f->name(); - - if(pk_value != -1) - vals << QString::number(pk_value); - else - vals << "NULL"; - } else if(f->notnull() && f->defaultValue().length() == 0) { - fields << f->name(); - - if(f->isInteger()) - vals << "0"; - else - vals << "''"; - } else { - // don't insert into fields with a default value - // or we will never see it. - if(f->defaultValue().length() == 0) - { - fields << f->name(); - vals << "NULL"; - } - } - } - - if(!fields.empty()) - { - stmt.append("(`"); - stmt.append(fields.join("`,`")); - stmt.append("`)"); - } - stmt.append(" VALUES ("); - stmt.append(vals.join(",")); - stmt.append(");"); - - return stmt; -} - QString Table::sql() const { diff --git a/src/sqlitetypes.h b/src/sqlitetypes.h index 24b9c8f6..80299ea4 100644 --- a/src/sqlitetypes.h +++ b/src/sqlitetypes.h @@ -80,13 +80,6 @@ public: const QString& name() const { return m_name; } const FieldVector& fields() const { return m_fields; } - /** - * @brief Creates an empty insert statement. - * @param pk_value This optional parameter can be used to manually set a specific value for the primary key column - * @return An sqlite conform INSERT INTO statement with empty values. (NULL,'',0) - */ - QString emptyInsertStmt(int pk_value = -1) const; - /** * @brief Returns the CREATE TABLE statement for this table object * @return A QString with the CREATE TABLE object.