/// <summary> /// add data item to the table /// </summary> /// <param name="item"></param> public bool AddItem(IDataItem item) { object obj; bool bRet = false; //check if table type to handle relations if (this is RelationshipDataTable) { //parse the table's relationships RelationshipDataTable rel_table = this as RelationshipDataTable; //get the fields long parent_id = Convert.ToInt64(item.GetType().GetField(rel_table.RelationshipMetadata.ParentRelationshipField).GetValue(item)); long child_id = Convert.ToInt64(item.GetType().GetField(rel_table.RelationshipMetadata.ChildRelationshipField).GetValue(item)); //lock the resource lock (rel_table.RelationshipParentLookup) { //add the relation //if (ReferenceEquals(AddOrUpdate(item.PrimaryKey, item), item)) { //look for the parent item IBucketDataTable bucket_table = rel_table.Bucket.BucketDataTables[rel_table.RelationshipMetadata.ParentTable.TableName]; IDataItem parent_item; if (bucket_table.TryGetValue(parent_id, bucket_table.TableMetadata.DataType, out obj)) { //add to the parent item parent_item = (IDataItem)obj; //List<long> list = (List<long>)parent_item.GetType().GetField(rel_table.RelationshipMetadata.ParentChildCollection).GetValue(parent_item); List <Tuple <List <long>, long> > list = (List <Tuple <List <long>, long> >)parent_item.GetType().GetField(rel_table.RelationshipMetadata.ParentChildCollection).GetValue(parent_item); lock (parent_item) { try { //check the list to init if (list == null) { list = new List <Tuple <List <long>, long> >(); } //check for no items if (list.Count == 0) { List <long> sub_list = new List <long>(); sub_list.Add(item.PrimaryKey); list.Add(new Tuple <List <long>, long>(sub_list, child_id)); bRet = true; } else { //get the sub list var tuple = list.FirstOrDefault(t => t.Item2 == child_id); if (tuple == null) { List <long> sub_list = new List <long>(); sub_list.Add(item.PrimaryKey); list.Add(new Tuple <List <long>, long>(sub_list, child_id)); bRet = true; } else { //is this a distinct relationship if (rel_table.RelationshipMetadata.DistinctRelationship) { //check if item is already added if (!tuple.Item1.Contains(item.PrimaryKey)) { tuple.Item1.Add(item.PrimaryKey); bRet = true; } } else { if (!list.Any(t => t.Item1.Contains(item.PrimaryKey))) { List <long> sub_list = new List <long>(); sub_list.Add(item.PrimaryKey); list.Add(new Tuple <List <long>, long>(sub_list, child_id)); bRet = true; } } } } //check if should update the field if (bRet) { parent_item.GetType().GetField(rel_table.RelationshipMetadata.ParentChildCollection).SetValue(parent_item, list); } //if (!list.Any(t => t.Item2 == child_id)) //{ // List<long> sub_list = new List<long>(); // sub_list.Add(item.PrimaryKey); // list.Add(new Tuple<List<long>, long>(sub_list, child_id)); // if (rel_table.RelationshipMetadata.DistinctRelationship) // parent_item.GetType().GetField(rel_table.RelationshipMetadata.ParentChildCollection).SetValue(parent_item, list); // bRet = true; //} } catch (Exception ex) { System.Diagnostics.Trace.WriteLine(ex.ToString()); } } } else { //update the lookup //rel_table.RelationshipParentLookup.AddOrUpdate // ( // parent_id, // new ConcurrentDictionary<long, long> // ( // new KeyValuePair<long, long>[] // { // new KeyValuePair<long, long> // ( // item.PrimaryKey, // child_id // ) // } // ), // (x, y) => // { // y.AddOrUpdate // ( // item.PrimaryKey, // child_id, // (j, k) => { return k; } // ); // return y; // } // ); } } } ////update the parent collection //IBucketDataTable bucket_table = rel_table.Bucket.BucketDataTables[rel_table.RelationshipMetadata.ParentTable.TableName]; //IDataItem parent_item; //if (bucket_table.TryGetValue(parent_id, bucket_table.TableMetadata.DataType, out obj)) //{ // parent_item = (IDataItem)obj; // parent_item.GetType().GetField(rel_table.RelationshipMetadata.ParentChildCollection).SetValue(parent_item, rel_table.GetChildList(parent_id)); //} } else if (this is BucketDataTable) { //cast the table BucketDataTable bucket_table = this as BucketDataTable; //add the bucket reference object objItem = AddOrUpdate(item.PrimaryKey, item); if (ReferenceEquals(objItem, item)) { //parse the table's relationships //foreach (RelationshipMetadata rel in this.TableMetadata.CatalogMetadata.Relationships.Where(r => r.Value.ParentTable.TableName == TableMetadata.TableName).Select(r => r.Value)) //{ // //get the relationship table // RelationshipDataTable rel_table = bucket_table.Bucket.BucketDataTables[rel.RelationTable.TableName] as RelationshipDataTable; // //lock the resource // lock (rel_table.RelationshipParentLookup) // { // //remove the lookup // ConcurrentDictionary<long, long> lookup; // if (rel_table.RelationshipParentLookup.TryGetValue(item.PrimaryKey, out lookup)) // { // //set the child collection // item.GetType().GetField(rel.ParentChildCollection).SetValue(item, rel_table.GetChildList(item.PrimaryKey)); // //remove the list // rel_table.RelationshipParentLookup.TryRemove(item.PrimaryKey, out lookup); // } // } //} bRet = true; } else { bRet = false; //parse the table's relationships //foreach (RelationshipMetadata rel in this.TableMetadata.CatalogMetadata.Relationships.Where(r => r.Value.ParentTable.TableName == TableMetadata.TableName).Select(r => r.Value)) //{ // //get the relationship table // RelationshipDataTable rel_table = bucket_table.Bucket.BucketDataTables[rel.RelationTable.TableName] as RelationshipDataTable; // //lock the resource // lock (rel_table.RelationshipParentLookup) // { // //copy the collection // item.GetType().GetField(rel.ParentChildCollection).SetValue(item, objItem.GetType().GetField(rel.ParentChildCollection).GetValue(objItem)); // } //} } //update our catalog var catalog_table = this.TableMetadata.CatalogMetadata.Catalog.CatalogDataTables[this.TableMetadata.TableName]; catalog_table.AddOrUpdate(item.PrimaryKey, item); } else { string test = "test"; } return(bRet); }
/// <summary> /// delete an item and its references /// </summary> /// <param name="item"></param> /// <param name="table"></param> private void DeleteItem(IDataItem item, IReferenceDataTable table, bool HardDelete) { //remove from table object objTable; object objCatalog; IDataItem removed; //check we need to handle relationship if (table is RelationshipDataTable) { //parse the table's relationships RelationshipDataTable rel_table = table as RelationshipDataTable; //get the fields long parent_id = Convert.ToInt64(item.GetType().GetField(rel_table.RelationshipMetadata.ParentRelationshipField).GetValue(item)); long child_id = Convert.ToInt64(item.GetType().GetField(rel_table.RelationshipMetadata.ChildRelationshipField).GetValue(item)); //lock the resource lock (rel_table.RelationshipParentLookup) { //remove the item if (table.TryRemove(item.PrimaryKey, table.TableMetadata.DataType, out objTable)) { removed = (IDataItem)objTable; } //check if this is a hard delete //HardDelete removes the relations //SoftDelete leave the references if (HardDelete) { //remove this relation ConcurrentDictionary <long, long> lookup; if (rel_table.RelationshipParentLookup.TryGetValue(parent_id, out lookup)) { //remove all lookup entries for association long id; bool found = true; while (found) { found = lookup.TryRemove(item.PrimaryKey, out id); } if (lookup.Count == 0) { //remove the lookup for this parent if (rel_table.RelationshipParentLookup.TryRemove(parent_id, out lookup)) { //lookup.Clear(); //lookup = null; } } } //get the parent item object objParent; IDataItem parent_item; //dynamic parent_item; IBucketDataTable parent_table = rel_table.Bucket.BucketDataTables[rel_table.RelationshipMetadata.ParentTable.TableName]; if (parent_table.TryGetValue(parent_id, parent_table.TableMetadata.DataType, out objParent)) { parent_item = (IDataItem)objParent; //parent_item.GetType().GetField(rel_table.RelationshipMetadata.ParentChildCollection).SetValue(parent_item, rel_table.GetChildList(parent_id)); var list = (List <Tuple <List <long>, long> >)parent_item.GetType().GetField(rel_table.RelationshipMetadata.ParentChildCollection).GetValue(parent_item); if (rel_table.RelationshipMetadata.DistinctRelationship) { var rel_item = list.FirstOrDefault(t => t.Item2 == child_id); if (rel_item != null) { if (rel_item.Item1.Contains(item.PrimaryKey)) { rel_item.Item1.Remove(item.PrimaryKey); } if (rel_item.Item1.Count == 0) { list.Remove(rel_item); } } } else { var rel_item = list.FirstOrDefault(t => t.Item1.Any(l => l == item.PrimaryKey)); if (rel_item != null) { list.Remove(rel_item); } } } } } //if(rel_table.DataItems.Count % 1000 == 0) //{ // System.Diagnostics.Trace.WriteLine( // string.Format( // "Lookup Status - Catalog:{0}, Table:{1}, TableCount:{2}, LookupCount:{3}", // rel_table.TableMetadata.CatalogMetadata.Catalog.CatalogName, // rel_table.TableMetadata.TableName, // rel_table.DataItems.Count, // rel_table.RelationshipParentLookup.Count)); //} } else if (table is BucketDataTable) { //remove the item if (table.TryRemove(item.PrimaryKey, table.TableMetadata.DataType, out objTable)) { removed = (IDataItem)objTable; } //parse the table's relationships BucketDataTable bucket_table = table as BucketDataTable; foreach (RelationshipMetadata rel in table.Catalog.CatalogMetadata.Relationships.Where(r => r.Value.ParentTable.TableName == table.TableMetadata.TableName).Select(r => r.Value)) { //get the relationship table RelationshipDataTable rel_table = bucket_table.Bucket.BucketDataTables[rel.RelationTable.TableName] as RelationshipDataTable; //lock the resource lock (rel_table.RelationshipParentLookup) { //remove the lookup for this parent ConcurrentDictionary <long, long> lookup; if (rel_table.RelationshipParentLookup.TryRemove(item.PrimaryKey, out lookup)) { lookup.Clear(); lookup = null; } } } } //remove from catalog if (table.Catalog.CatalogDataTables[table.TableMetadata.TableName].TryRemove(item.PrimaryKey, table.TableMetadata.DataType, out objCatalog)) { removed = (IDataItem)objCatalog; } }