private static void DropSoup(string databasePath, string soupName) { lock (smartlock) { DBHelper db = DBHelper.GetInstance(databasePath); string soupTableName = db.GetSoupTableName(soupName); if (!String.IsNullOrWhiteSpace(soupTableName)) { SQLiteResult result = db.Execute("DROP TABLE IF EXISTS " + soupTableName); bool success = result == SQLiteResult.DONE; var soupDrop = new Dictionary <string, object> { { SoupNameCol, soupName } }; try { db.BeginTransaction(); success &= db.Delete(SoupNamesTable, soupDrop); success &= db.Delete(SoupIndexMapTable, soupDrop); } finally { if (success) { db.CommitTransaction(); db.RemoveFromCache(soupName); } else { db.RollbackTransaction(); } } } } }
public bool Delete(string soupName, long[] soupEntryIds, Boolean handleTx) { lock (smartlock) { bool success = false; DBHelper db = DBHelper.GetInstance(DatabasePath); string soupTableName = db.GetSoupTableName(soupName); if (String.IsNullOrWhiteSpace(soupTableName)) { throw new SmartStoreException("Soup: " + soupName + " does not exist"); } if (handleTx) { db.BeginTransaction(); } try { success = db.Delete(soupTableName, GetSoupEntryIdsPredicate(soupEntryIds)); } finally { if (handleTx) { db.CommitTransaction(); } } return(success); } }
/// <summary> /// Create soup index map table to keep track of soups' index specs /// Create soup name map table to keep track of soup name to table name mappings /// Called when the database is first created /// </summary> public void CreateMetaTables() { lock (smartlock) { DBHelper db = DBHelper.GetInstance(DatabasePath); // Create soup_index_map table var sb = new StringBuilder(); db.BeginTransaction(); sb.Append("CREATE TABLE IF NOT EXISTS ").Append(SoupIndexMapTable).Append(" (") .Append(SoupNameCol).Append(" TEXT") .Append(",").Append(PathCol).Append(" TEXT") .Append(",").Append(ColumnNameCol).Append(" TEXT") .Append(",").Append(ColumnTypeCol).Append(" TEXT") .Append(")"); db.Execute(sb.ToString()); db.Execute(String.Format("CREATE INDEX IF NOT EXISTS {0} on {1} ( {2} )", SoupIndexMapTable + "_0", SoupIndexMapTable, SoupNameCol)); // Create soup_names table // The table name for the soup will simply be table_<soupId> sb = new StringBuilder(); sb.Append("CREATE TABLE IF NOT EXISTS ").Append(SoupNamesTable).Append(" (") .Append(IdCol).Append(" INTEGER PRIMARY KEY AUTOINCREMENT") .Append(",").Append(SoupNameCol).Append(" TEXT") .Append(")"); db.Execute(sb.ToString()); db.CommitTransaction(); // Create alter_soup_status table CreateLongOperationsStatusTable(db); } }
public JObject Update(String soupName, JObject soupElt, long soupEntryId, bool handleTx) { lock (smartlock) { DBHelper db = Database; string soupTableName = db.GetSoupTableName(soupName); if (String.IsNullOrWhiteSpace(soupTableName)) { throw new SmartStoreException("Soup: " + soupName + " does not exist"); } IndexSpec[] indexSpecs = db.GetIndexSpecs(soupName); long now = CurrentTimeMillis; if (soupElt[SoupEntryId] == null) { soupElt.Add(SoupEntryId, soupEntryId); } else { soupElt[SoupEntryId] = soupEntryId; } if (soupElt[SoupLastModifiedDate] == null) { soupElt.Add(SoupLastModifiedDate, now); } else { soupElt[SoupLastModifiedDate] = now; } var contentValues = new Dictionary <string, object> { { SoupCol, soupElt.ToString() }, { LastModifiedCol, now } }; foreach (IndexSpec indexSpec in indexSpecs) { ProjectIndexedPaths(soupElt, contentValues, indexSpec); } if (handleTx) { db.BeginTransaction(); } bool success = db.Update(soupTableName, contentValues, IdPredicate, soupEntryId.ToString()); if (success) { if (handleTx) { db.CommitTransaction(); } return(soupElt); } if (handleTx) { db.RollbackTransaction(); } return(null); } }
public JObject Create(string soupName, JObject soupElt, bool handleTx) { lock (smartlock) { DBHelper db = DBHelper.GetInstance(DatabasePath); string soupTableName = db.GetSoupTableName(soupName); IndexSpec[] indexSpecs = db.GetIndexSpecs(soupName); if (handleTx) { db.BeginTransaction(); } long now = CurrentTimeMillis; long soupEntryId = db.GetNextId(soupTableName); soupElt[SoupEntryId] = soupEntryId; soupElt[SoupLastModifiedDate] = now; var contentValues = new Dictionary <string, object> { { IdCol, soupEntryId }, { CreatedCol, now }, { LastModifiedCol, now }, { SoupCol, soupElt.ToString() } }; foreach (IndexSpec indexSpec in indexSpecs) { ProjectIndexedPaths(soupElt, contentValues, indexSpec); } bool success = db.Insert(soupTableName, contentValues) == soupEntryId; if (success) { if (handleTx) { db.CommitTransaction(); } return(soupElt); } if (handleTx) { db.RollbackTransaction(); } return(null); } }
/// <summary> /// Clear all rows from a soup /// </summary> /// <param name="soupName"></param> public void ClearSoup(string soupName) { lock (smartlock) { DBHelper db = DBHelper.GetInstance(DatabasePath); string soupTableName = db.GetSoupTableName(soupName); if (String.IsNullOrWhiteSpace(soupTableName)) { throw new SmartStoreException("Soup: " + soupName + " does not exist"); } db.BeginTransaction(); try { db.Delete(soupName); } finally { db.CommitTransaction(); } } }
/// <summary> /// Create table for soupName with a column for the soup itself and columns for paths specified in indexSpecs /// Create indexes on the new table to make lookup faster /// Create rows in soup index map table for indexSpecs /// </summary> /// <param name="soupName"></param> /// <param name="indexSpecs"></param> public void RegisterSoup(String soupName, IndexSpec[] indexSpecs) { lock (smartlock) { if (soupName == null) { throw new SmartStoreException("Null soup name"); } if (indexSpecs.Length == 0) { throw new SmartStoreException("No indexSpecs specified for soup: " + soupName); } if (HasSoup(soupName)) { return; // soup already exist - do nothing } // First get a table name String soupTableName = null; var soupMapValues = new Dictionary <string, object> { { SoupNameCol, soupName } }; DBHelper db = DBHelper.GetInstance(DatabasePath); try { db.BeginTransaction(); long soupId = db.Insert(SoupNamesTable, soupMapValues); soupTableName = GetSoupTableName(soupId); } finally { db.CommitTransaction(); } if (!String.IsNullOrWhiteSpace(soupTableName)) { // Do the rest - create table / indexes RegisterSoupUsingTableName(soupName, indexSpecs, soupTableName); } } }
/// <summary> /// Re-index all soup elements for passed indexPaths /// </summary> /// <param name="soupName"></param> /// <param name="indexPaths"></param> /// <param name="handleTx"></param> public void ReIndexSoup(string soupName, string[] indexPaths, bool handleTx) { lock (smartlock) { DBHelper db = DBHelper.GetInstance(DatabasePath); string soupTableName = db.GetSoupTableName(soupName); if (String.IsNullOrWhiteSpace(soupTableName)) { throw new SmartStoreException("Soup: " + soupName + " does not exist"); } Dictionary <string, IndexSpec> mapAllSpecs = IndexSpec.MapForIndexSpecs(GetSoupIndexSpecs(soupName)); IndexSpec[] indexSpecs = (from indexPath in indexPaths where mapAllSpecs.ContainsKey(indexPath) select mapAllSpecs[indexPath]) .ToArray(); if (indexSpecs.Length == 0) { return; // nothing to do } if (handleTx) { db.BeginTransaction(); } using ( ISQLiteStatement stmt = db.Query(soupTableName, new[] { IdCol, SoupCol }, String.Empty, String.Empty, String.Empty)) { if (stmt.DataCount > 0) { try { do { string soupEntryId = stmt.GetText(0); string soupRaw = stmt.GetText(1); try { JObject soupElt = JObject.Parse(soupRaw); var contentValues = new Dictionary <string, object>(); foreach (IndexSpec indexSpec in indexSpecs) { ProjectIndexedPaths(soupElt, contentValues, indexSpec); } db.Update(soupTableName, contentValues, IdPredicate, soupEntryId + String.Empty); } catch (JsonException e) { Debug.WriteLine("SmartStore.ReIndexSoup: Could not parse soup element " + soupEntryId + "\n" + e.Message); } } while (stmt.Step() == SQLiteResult.ROW); } finally { if (handleTx) { db.CommitTransaction(); } } } } } }
/// <summary> /// Helper method for registerSoup /// </summary> /// <param name="soupName"></param> /// <param name="indexSpecs"></param> /// <param name="soupTableName"></param> private void RegisterSoupUsingTableName(string soupName, IndexSpec[] indexSpecs, string soupTableName) { DBHelper db = DBHelper.GetInstance(DatabasePath); // Prepare SQL for creating soup table and its indices var createTableStmt = new StringBuilder(); // to create new soup table var createIndexStmts = new List <String>(); // to create indices on new soup table var soupIndexMapInserts = new List <Dictionary <string, object> >(); // to be inserted in soup index map table createTableStmt.Append("CREATE TABLE ").Append(soupTableName).Append(" (") .Append(IdCol).Append(" INTEGER PRIMARY KEY AUTOINCREMENT") .Append(", ").Append(SoupCol).Append(" TEXT") .Append(", ").Append(CreatedCol).Append(" INTEGER") .Append(", ").Append(LastModifiedCol).Append(" INTEGER"); int i = 0; var indexSpecsToCache = new IndexSpec[indexSpecs.Length]; foreach (IndexSpec indexSpec in indexSpecs) { // for create table String columnName = soupTableName + "_" + i; String columnType = indexSpec.SmartType.ColumnType; createTableStmt.Append(", ").Append(columnName).Append(" ").Append(columnType); // for insert var values = new Dictionary <string, object> { { SoupNameCol, soupName }, { PathCol, indexSpec.Path }, { ColumnNameCol, columnName }, { ColumnTypeCol, indexSpec.SmartType.ColumnType } }; soupIndexMapInserts.Add(values); // for create index String indexName = soupTableName + "_" + i + "_idx"; createIndexStmts.Add(String.Format("CREATE INDEX {0} on {1} ( {2} )", indexName, soupTableName, columnName)); // for the cache indexSpecsToCache[i] = new IndexSpec(indexSpec.Path, indexSpec.SmartType, columnName); i++; } createTableStmt.Append(")"); // Run SQL for creating soup table and its indices db.Execute(createTableStmt.ToString()); foreach (String createIndexStmt in createIndexStmts) { db.Execute(createIndexStmt); } try { db.BeginTransaction(); foreach (var values in soupIndexMapInserts) { db.Insert(SoupIndexMapTable, values); } // Add to soupNameToTableNamesMap db.CacheTableName(soupName, soupTableName); // Add to soupNameToIndexSpecsMap db.CacheIndexSpecs(soupName, indexSpecsToCache); } finally { db.CommitTransaction(); } }