private void ProjectIndexedPaths(JObject soupElt, Dictionary <string, object> contentValues, IndexSpec indexSpec) { object value = Project(soupElt, indexSpec.Path); if (value == null) { return; } if (contentValues == null) { contentValues = new Dictionary <string, object>(); } if (SmartStoreType.SmartInteger.ColumnType.Equals(indexSpec.SmartType.ColumnType)) { contentValues.Add(indexSpec.ColumnName, Int32.Parse(value.ToString())); } else if (SmartStoreType.SmartString.ColumnType.Equals(indexSpec.SmartType.ColumnType)) { contentValues.Add(indexSpec.ColumnName, value.ToString()); } else if (SmartStoreType.SmartFloating.ColumnType.Equals(indexSpec.SmartType.ColumnType)) { contentValues.Add(indexSpec.ColumnName, Double.Parse(value.ToString())); } }
/// <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(); } }
/// <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(); } } } } } }
private void ProjectIndexedPaths(JObject soupElt, Dictionary<string, object> contentValues, IndexSpec indexSpec) { object value = Project(soupElt, indexSpec.Path); if (value == null) return; if (contentValues == null) { contentValues = new Dictionary<string, object>(); } if (SmartStoreType.SmartInteger.ColumnType.Equals(indexSpec.SmartType.ColumnType)) { contentValues.Add(indexSpec.ColumnName, Int32.Parse(value.ToString())); } else if (SmartStoreType.SmartString.ColumnType.Equals(indexSpec.SmartType.ColumnType)) { contentValues.Add(indexSpec.ColumnName, value.ToString()); } else if (SmartStoreType.SmartFloating.ColumnType.Equals(indexSpec.SmartType.ColumnType)) { contentValues.Add(indexSpec.ColumnName, Double.Parse(value.ToString())); } }
/// <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(); } }
/// <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); } } }
public static Dictionary<string, IndexSpec> MapForIndexSpecs(IndexSpec[] indexSpecs) { return indexSpecs.ToDictionary(indexSpec => indexSpec.Path); }
public void CacheIndexSpecs(string soupName, IndexSpec[] indexSpecs) { SoupNameToIndexSpecsMap.Add(soupName, indexSpecs); }