diff --git a/src/sqlitedb.cpp b/src/sqlitedb.cpp
index d8e2b90c..279f3fb7 100644
--- a/src/sqlitedb.cpp
+++ b/src/sqlitedb.cpp
@@ -462,11 +462,22 @@ int DBBrowserDB::addRecord(const QString& sTableName)
char *errmsg;
if (!isOpen()) return false;
- // add record is seldom called, for now this is ok
- // but if we ever going to add a lot of records
- // we should cache the parsed tables somewhere
- sqlb::Table table = sqlb::Table::parseSQL(getObjectByName(sTableName).getsql()).first;
- QString sInsertstmt = table.emptyInsertStmt();
+ sqlb::Table table = getObjectByName(sTableName).table;
+
+ // For tables without rowid we have to set the primary key by ourselves. We do so by querying for the largest value in the PK column
+ // and adding one to it.
+ QString sInsertstmt;
+ int pk_value;
+ if(table.isWithoutRowidTable())
+ {
+ SqliteTableModel m(this, this);
+ m.setQuery(QString("SELECT MAX(`%1`) FROM `%2`;").arg(getObjectByName(sTableName).table.rowidColumn()).arg(sTableName));
+ pk_value = m.data(m.index(0, 0)).toInt() + 1;
+ sInsertstmt = table.emptyInsertStmt(pk_value);
+ } else {
+ sInsertstmt = table.emptyInsertStmt();
+ }
+
lastErrorMessage = "";
logSQL(sInsertstmt, kLogMsg_App);
setRestorePoint();
@@ -477,7 +488,10 @@ int DBBrowserDB::addRecord(const QString& sTableName)
qWarning() << "addRecord: " << lastErrorMessage;
return -1;
} else {
- return sqlite3_last_insert_rowid(_db);
+ if(table.isWithoutRowidTable())
+ return pk_value;
+ else
+ return sqlite3_last_insert_rowid(_db);
}
}
diff --git a/src/sqlitetypes.cpp b/src/sqlitetypes.cpp
index cda5ecf8..e3ae856f 100644
--- a/src/sqlitetypes.cpp
+++ b/src/sqlitetypes.cpp
@@ -156,28 +156,29 @@ QPair
Table::parseSQL(const QString &sSQL)
return qMakePair(Table(""), false);
}
-QString Table::emptyInsertStmt() const
+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->notnull())
+ if( f->primaryKey() && f->isInteger() )
{
fields << f->name();
- if( f->primaryKey() && f->isInteger() )
- {
+
+ if(pk_value != -1)
+ vals << QString::number(pk_value);
+ else
vals << "NULL";
- } else {
- if(f->isInteger())
- vals << "0";
- else
- vals << "''";
- }
- }
- else
- {
+ } else if(f->notnull()) {
+ 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)
@@ -228,7 +229,7 @@ QString Table::sql() const
sql += "\n)";
// without rowid
- if(m_rowidColumn != "_rowid_")
+ if(isWithoutRowidTable())
sql += " WITHOUT ROWID";
return sql + ";";
diff --git a/src/sqlitetypes.h b/src/sqlitetypes.h
index 6065de47..59c3bdbe 100644
--- a/src/sqlitetypes.h
+++ b/src/sqlitetypes.h
@@ -82,9 +82,10 @@ public:
/**
* @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;
+ QString emptyInsertStmt(int pk_value = -1) const;
/**
* @brief Returns the CREATE TABLE statement for this table object
@@ -98,6 +99,7 @@ public:
void setField(int index, FieldPtr f) { m_fields[index] = f; }
void setRowidColumn(const QString& rowid) { m_rowidColumn = rowid; }
const QString& rowidColumn() const { return m_rowidColumn; }
+ bool isWithoutRowidTable() const { return m_rowidColumn != "_rowid_"; }
void clear();
/**