Update Item.save() to use manually bound parameters for itemData

This should theoretically speed up large imports a bit.
This commit is contained in:
Dan Stillman 2006-09-27 17:11:38 +00:00
parent c490020031
commit 610f5b2c3a

View file

@ -542,44 +542,53 @@ Scholar.Item.prototype.save = function(){
// //
if (this._changedItemData.length){ if (this._changedItemData.length){
var del = new Array(); var del = new Array();
sql = "SELECT COUNT(*) FROM itemData WHERE itemID=? AND fieldID=?";
var countStatement = Scholar.DB.getStatement(sql);
countStatement.bindInt32Parameter(0, this.getID());
sql = "UPDATE itemData SET value=? WHERE itemID=? AND fieldID=?";
var updateStatement = Scholar.DB.getStatement(sql);
updateStatement.bindInt32Parameter(1, this.getID());
sql = "INSERT INTO itemData VALUES (?,?,?)";
var insertStatement = Scholar.DB.getStatement(sql);
insertStatement.bindInt32Parameter(0, this.getID());
for (fieldID in this._changedItemData.items){ for (fieldID in this._changedItemData.items){
if (this.getField(fieldID)){ if (this.getField(fieldID)){
// Oh, for an INSERT...ON DUPLICATE KEY UPDATE // Oh, for an INSERT...ON DUPLICATE KEY UPDATE
sql2 = 'SELECT COUNT(*) FROM itemData ' countStatement.bindInt32Parameter(1, fieldID);
+ 'WHERE itemID=' + this.getID() countStatement.executeStep();
+ ' AND fieldID=' + fieldID; var exists = countStatement.getInt64(0);
// Update // Update
if (Scholar.DB.valueQuery(sql2)){ if (exists){
sqlValues = [];
Scholar.History.modify('itemData', 'itemID-fieldID', Scholar.History.modify('itemData', 'itemID-fieldID',
[this.getID(), fieldID]); [this.getID(), fieldID]);
sql = "UPDATE itemData SET value="; // Don't bind CURRENT_TIMESTAMP as string
if (Scholar.ItemFields.getID('accessDate')==fieldID if (Scholar.ItemFields.getID('accessDate')==fieldID
&& this.getField(fieldID)=='CURRENT_TIMESTAMP') && this.getField(fieldID)=='CURRENT_TIMESTAMP')
{ {
sql += "CURRENT_TIMESTAMP"; sql = "UPDATE itemData SET value=CURRENT_TIMESTAMP"
} + " WHERE itemID=? AND fieldID=?";
// Take advantage of SQLite's manifest typing Scholar.DB.query(sql,
else if (Scholar.ItemFields.isInteger(fieldID)){ [{int:this.getID()}, {int:fieldID}]);
sql += '?'
sqlValues.push({'int':this.getField(fieldID)});
} }
else { else {
sql += '?' // Take advantage of SQLite's manifest typing
sqlValues.push({'string':this.getField(fieldID)}); if (Scholar.ItemFields.isInteger(fieldID)){
updateStatement.bindInt32Parameter(0,
this.getField(fieldID));
}
else {
updateStatement.bindUTF8StringParameter(0,
this.getField(fieldID));
}
updateStatement.bindInt32Parameter(2, fieldID);
updateStatement.execute();
} }
sql += " WHERE itemID=? AND fieldID=?";
sqlValues.push(
{'int':this.getID()},
{'int':fieldID}
);
Scholar.DB.query(sql, sqlValues);
} }
// Insert // Insert
@ -587,27 +596,29 @@ Scholar.Item.prototype.save = function(){
Scholar.History.add('itemData', 'itemID-fieldID', Scholar.History.add('itemData', 'itemID-fieldID',
[this.getID(), fieldID]); [this.getID(), fieldID]);
sql = "INSERT INTO itemData VALUES (?,?,?)"; insertStatement.bindInt32Parameter(1, fieldID);
sqlValues = [
{'int':this.getID()},
{'int':fieldID},
];
if (Scholar.ItemFields.getID('accessDate')==fieldID if (Scholar.ItemFields.getID('accessDate')==fieldID
&& this.getField(fieldID)=='CURRENT_TIMESTAMP') && this.getField(fieldID)=='CURRENT_TIMESTAMP')
{ {
sql = "INSERT INTO itemData VALUES " sql = "INSERT INTO itemData VALUES "
+ "(?,?,CURRENT_TIMESTAMP)"; + "(?,?,CURRENT_TIMESTAMP)";
}
else if (Scholar.ItemFields.isInteger(fieldID)){ Scholar.DB.query(sql,
sqlValues.push({'int':this.getField(fieldID)}); [{int:this.getID()}, {int:fieldID}]);
} }
else { else {
sqlValues.push({'string':this.getField(fieldID)}); if (Scholar.ItemFields.isInteger(fieldID)){
insertStatement.bindInt32Parameter(2,
this.getField(fieldID));
}
else {
insertStatement.bindUTF8StringParameter(2,
this.getField(fieldID));
}
insertStatement.execute();
} }
Scholar.DB.query(sql, sqlValues);
} }
} }
@ -617,6 +628,10 @@ Scholar.Item.prototype.save = function(){
} }
} }
countStatement.reset();
updateStatement.reset();
insertStatement.reset();
// Delete blank fields // Delete blank fields
if (del.length){ if (del.length){
// Add to history // Add to history
@ -696,38 +711,39 @@ Scholar.Item.prototype.save = function(){
// ItemData // ItemData
// //
if (this._changedItemData.length){ if (this._changedItemData.length){
// Use manual bound parameters to speed things up
var statement =
Scholar.DB.getStatement("INSERT INTO itemData VALUES (?,?,?)");
statement.bindInt32Parameter(0, this.getID());
for (fieldID in this._changedItemData.items){ for (fieldID in this._changedItemData.items){
if (!this.getField(fieldID)){ if (!this.getField(fieldID)){
continue; continue;
} }
// TODO: update DB methods so that this can be statement.bindInt32Parameter(1, fieldID);
// implemented as a prepared statement that gets
// called multiple times
sql = "INSERT INTO itemData VALUES (?,?,?)";
sqlValues = [
{'int':itemID},
{'int':fieldID}
];
if (Scholar.ItemFields.getID('accessDate')==fieldID if (Scholar.ItemFields.getID('accessDate')==fieldID
&& this.getField(fieldID)=='CURRENT_TIMESTAMP') && this.getField(fieldID)=='CURRENT_TIMESTAMP')
{ {
sql = "INSERT INTO itemData VALUES (?,?,CURRENT_TIMESTAMP)"; sql = "INSERT INTO itemData VALUES (?,?,CURRENT_TIMESTAMP)";
} Scholar.DB.query(sql, [{int:this.getID()}, {int:fieldID}])
else if (Scholar.ItemFields.isInteger(fieldID)){
sqlValues.push({'int':this.getField(fieldID)});
} }
else { else {
sqlValues.push({'string':this.getField(fieldID)}); if (Scholar.ItemFields.isInteger(fieldID)){
statement.bindInt32Parameter(2, this.getField(fieldID));
}
else {
statement.bindUTF8StringParameter(2, this.getField(fieldID));
}
statement.execute();
} }
Scholar.DB.query(sql, sqlValues);
Scholar.History.add('itemData', 'itemID-fieldID', Scholar.History.add('itemData', 'itemID-fieldID',
[itemID, fieldID]); [itemID, fieldID]);
} }
statement.reset();
} }
// //