protected BaseItem GetItem(SQLiteDataReader reader, string itemType) { BaseItem item = null; try { item = Serializer.Instantiate<BaseItem>(itemType); } catch (Exception e) { Logger.ReportException("Error trying to create instance of type: " + itemType, e); return null; } if (item != null) { SQLInfo itemSQL; lock (ItemSQL) { if (!ItemSQL.TryGetValue(item.GetType(), out itemSQL)) { itemSQL = new SQLInfo(item); ItemSQL.Add(item.GetType(), itemSQL); //make sure our schema matches itemSQL.FixUpSchema(connection); } } foreach (var col in itemSQL.AtomicColumns) { var data = SQLizer.Extract(reader, col); if (data != null) if (col.MemberType == MemberTypes.Property) col.PropertyInfo.SetValue(item, data, null); else col.FieldInfo.SetValue(item, data); } // and our list columns //this is an optimization - we go get all the list values for this item in one statement var listCmd = connection.CreateCommand(); listCmd.CommandText = "select property, value from list_items where guid = @guid and property != 'ActorName' order by property, sort_order"; listCmd.AddParam("@guid", item.Id); string currentProperty = ""; System.Collections.IList list = null; SQLInfo.ColDef column = new SQLInfo.ColDef(); using (var listReader = listCmd.ExecuteReader()) { while (listReader.Read()) { string property = listReader.GetString(0); if (property != currentProperty) { //new column... if (list != null) { //fill in the last one if (column.MemberType == MemberTypes.Property) column.PropertyInfo.SetValue(item, list, null); else column.FieldInfo.SetValue(item, list); } currentProperty = property; column = itemSQL.Columns.Find(c => c.ColName == property); list = (System.Collections.IList)column.ColType.GetConstructor(new Type[] { }).Invoke(null); //Logger.ReportVerbose("Added list item '" + listReader[0] + "' to " + col.ColName); } try { list.Add(SQLizer.Extract(listReader, new SQLInfo.ColDef() { ColName = "value", ColType = column.InternalType })); } catch (Exception e) { Logger.ReportException("Error adding item to list " + column.ColName + " on item " + item.Name, e); } } if (list != null) { //fill in the last one if (column.MemberType == MemberTypes.Property) column.PropertyInfo.SetValue(item, list, null); else column.FieldInfo.SetValue(item, list); } } } else { Logger.ReportWarning("Ignoring invalid item " + itemType + ". Would not instantiate in current environment."); } return item; }
public IList<Index> RetrieveIndex(Folder folder, string property, Func<string, BaseItem> constructor) { bool allowEpisodes = property == "Directors" || property == "ProductionYear"; List<Index> children = new List<Index>(); var cmd = connection.CreateCommand(); //we'll build the unknown items now and leave them out of child table List<BaseItem> unknownItems = new List<BaseItem>(); //create a temporary table of this folder's recursive children to use in the retrievals string tableName = "["+folder.Id.ToString().Replace("-","")+"_"+property+"]"; if (connection.TableExists(tableName)) { connection.Exec("delete from " + tableName); } else { connection.Exec("create temporary table if not exists " + tableName + "(child)"); } cmd.CommandText = "Insert into "+tableName+" (child) values(@1)"; var childParam = cmd.Parameters.Add("@1", DbType.Guid); var containerList = new Dictionary<Guid, IContainer>(); //initialize this for our index SQLInfo.ColDef col = new SQLInfo.ColDef(); Type currentType = null; lock (connection) //can't use delayed writer here - need this table now... { var tran = connection.BeginTransaction(); foreach (var child in folder.RecursiveChildren) { if (child is IShow && !(child is Season) && ((allowEpisodes && !(child is Series)) || (!allowEpisodes && !(child is Episode)))) { if (child is IGroupInIndex) { //add the series object containerList[child.Id] = (child as IGroupInIndex).MainContainer; } //determine if property has any value if (child.GetType() != currentType) { currentType = child.GetType(); col = ItemSQL[currentType].Columns.Find(c => c.ColName == property); } object data = null; if (col.MemberType == MemberTypes.Property) { data = col.PropertyInfo.GetValue(child, null); } else if (col.MemberType == MemberTypes.Field) { data = col.FieldInfo.GetValue(child); } if (data != null) { //Logger.ReportVerbose("Adding child " + child.Name + " to temp table"); childParam.Value = child.Id; cmd.ExecuteNonQuery(); } else { //add to Unknown AddItemToIndex("<Unknown>", unknownItems, containerList, child); } } } tran.Commit(); } //fill in series ContainerDict[tableName] = containerList; //create our Unknown Index - if there were any if (unknownItems.Count > 0) children.Add(new Index(constructor("<Unknown>"), unknownItems)); //now retrieve the values for the main indicies cmd = connection.CreateCommand(); //new command property = property == "Actors" ? "ActorName" : property; //re-map to our name entry if (col.ListType) { //need to get values from list table cmd.CommandText = "select distinct value from list_items where property = '" + property + "' and guid in (select child from " + tableName + ") order by value"; } else { cmd.CommandText = "select distinct " + property + " from items where guid in (select child from " + tableName + ") order by "+property; } using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { //Logger.ReportVerbose("Creating index " + reader[0].ToString() + " on " + folder.Name); object value = reader[0]; children.Add(new Index(constructor(value.ToString()), tableName, property, value)); } } return children; }