/// <summary>Updates the database to reflect the new values of the changed catalog item elements.</summary> /// /// <param name="item">The item to update in the databsse</param> /// <param name="updatedElements">The elements of the item that have changed and therefore should be updated.</param> public void UpdateItem(SqliteCatalogStoreItem item, StoreItemElements updatedElements) { if (!item.Stored) { throw new ArgumentException("Cannot update an item that has not been saved to the catalog", "item"); } if (!item.Loaded) { throw new ArgumentException("Cannot update an item that has not been loaded", "item"); } try { item.Persisting = true; //If any of the simple elements of the catalog_items table have //changed, update them. It's easier to just update them all if ((updatedElements & (StoreItemElements.Title | StoreItemElements.Uri | StoreItemElements.Type | StoreItemElements.AliasOf | StoreItemElements.Parent)) != 0) { String sql = @" update catalog_items set parent_catalog_item_id = ?, uri = ?, title = ?, type = ?, alias_catalog_item_id = ? where catalog_item_id = ?"; using (SQLiteCommand cmd = _conn.CreateCommand()) { cmd.CommandType = CommandType.Text; cmd.CommandText = sql; cmd.CreateAndAddUnnamedParameters(); cmd.Parameters[0].DbType = DbType.Int64; if (item.Parent == null || !item.Parent.Stored) { cmd.Parameters[0].Value = DBNull.Value; } else { cmd.Parameters[0].Value = item.Parent.Id; } cmd.Parameters[1].DbType = DbType.String; cmd.Parameters[1].Value = item.Uri; cmd.Parameters[2].DbType = DbType.String; cmd.Parameters[2].Value = item.Title; cmd.Parameters[3].DbType = DbType.String; cmd.Parameters[3].Value = item.Type; cmd.Parameters[4].DbType = DbType.Int64; if (item.AliasOf == null || !item.AliasOf.Stored) { cmd.Parameters[4].Value = DBNull.Value; } else { cmd.Parameters[4].Value = item.AliasOf.Id; } cmd.Parameters[5].DbType = DbType.Int64; cmd.Parameters[5].Value = item.Id; cmd.ExecuteNonQuery(); } //If the title has changed, need to rebuild the title graph too if ((updatedElements & StoreItemElements.Title) != 0) { SetItemTitleWords(item); } } //If the tags changed, update those if ((updatedElements & StoreItemElements.Tags) != 0) { //Delete existing tags, and replace with the new tags //Realistically, it would be a trivial optimization to //just update changed tags, delete removed, etc. String sql = @"delete from catalog_item_tags where catalog_item_id = ?"; using (SQLiteCommand cmd = _conn.CreateCommand()) { cmd.CommandType = CommandType.Text; cmd.CommandText = sql; cmd.CreateAndAddUnnamedParameters(); cmd.Parameters[0].DbType = DbType.Int64; cmd.Parameters[0].Value = item.Id; cmd.ExecuteNonQuery(); } //Now re-create the tags sql = "insert into catalog_item_tags(catalog_item_id, tag) values (?, ?)"; using (SQLiteCommand cmd = _conn.CreateCommand()) { cmd.CommandType = CommandType.Text; cmd.CommandText = sql; cmd.CreateAndAddUnnamedParameters(); cmd.Prepare(); cmd.Parameters[0].Value = item.Id; foreach (String tag in item.Tags) { cmd.Parameters[1].Value = tag; cmd.ExecuteNonQuery(); } } } //If the alias or children lists change, that's a special case. //it must mean that another item has changed its AliasOf or //Parent property. Since the children and aliases lists are //build from the Parent and AliasOf properties, respectively, //there's no need to explicitly save these lists; only the items within //them. } finally { item.Persisting = false; } }
/// <summary>Updates the database to reflect a change to one of the item's elements.</summary> /// /// <param name="elements"></param> private void UpdateElement(StoreItemElements elements) { if (_loaded && Stored && !_persisting) { //Item is already in the database, so update it _store.Persistor.UpdateItem(this, elements); } }