mirror of
https://github.com/sqlitebrowser/sqlitebrowser.git
synced 2026-01-20 19:11:39 -06:00
Make it possible to add rows to a WITHOUT rowid table
This commit allows you to add new rows to a table without rowid column. The main problem here is that SQLite won't create the next value for the primary key column itself, so we have to do that instead. See issue #51.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -156,28 +156,29 @@ QPair<Table, bool> 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 + ";";
|
||||
|
||||
@@ -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();
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user