public Schema Associate(Schema schema1, Schema schema2)
        {
            Schema associationSchema = GetAssociationSchema(schema1, schema2);
            InstantiateSchema(associationSchema);

            return associationSchema;
        }
 public CreateAssociationDlg(Model model, Schema fromSchema)
 {
     this.model = model;
     this.fromSchema = fromSchema;
     InitializeComponent();
     PopulateSemanticTypes();
 }
 protected void AddConcreteTypes(TreeNode tn, Schema schema)
 {
     schema.ConcreteTypes.ForEach(ct =>
         {
             AddConcreteTypeToNode(tn, ct);
         });
 }
 public void Process(ISemanticProcessor proc, IMembrane membrane, ST_AddNewSubtype data)
 {
     TreeNode sttn = selectedNode;
     Schema parentSchema = (Schema)sttn.Parent.Tag;
     Schema schema = new Schema() { Name = data.Name, Alias = data.Alias, Parent = parentSchema };
     parentSchema.Subtypes.Add(schema);
     AddSchemaNode(sttn, schema);
 }
        /// <summary>
        /// Recurses into subtypes to create a flat view of the semantic hierarchy.
        /// </summary>
        public static DataTable InitializeSemanticColumns(Schema schema, out List<ConcreteType> semanticColumns)
        {
            DataTable dt = new DataTable();
            dt.TableName = schema.Name;
            semanticColumns = new List<ConcreteType>();
            dt.Columns.Add("_id");
            PopulateSemanticColumns(dt, schema, semanticColumns);

            return dt;
        }
 protected void ShowCollection(Schema schema)
 {
     Helpers.Try(() =>
     {
         List<BsonDocument> docs = model.Db.GetAll(schema.Name);
         DataTable dt = InitializeCollectionColumns(schema);
         PopulateCollectionTable(dt, docs, schema);
         Program.serviceManager.Get<ISemanticProcessor>().ProcessInstance<CollectionViewMembrane, ST_Data>(data => data.Table = dt);
     });
 }
 public void Process(ISemanticProcessor proc, IMembrane membrane, ST_Data data)
 {
     schema = data.Schema;
     DataView dv = new DataView(data.Table);
     dgView.FindForm().BeginInvoke(() =>
         {
             dgView.DataSource = dv;
             dgView.Columns[0].Visible = false;			// Hide the ID field.
             label.Text = "Semantic Type: " + data.Table.TableName;
         });
 }
        public static string GetSchemaNodeText(Schema schema)
        {
            string ret = schema.Name;

            if (schema.IsAliased)
            {
                ret = ret + " (" + schema.Alias + ")";
            }

            return ret;
        }
        /// <summary>
        /// Initializes the columns of a table with the concrete types for collection associated with the schema,
        /// therefore no sub-types are parsed.
        /// </summary>
        protected DataTable InitializeCollectionColumns(Schema schema)
        {
            DataTable dt = new DataTable();
            dt.TableName = schema.Name;

            foreach (ConcreteType ct in schema.ConcreteTypes)
            {
                dt.Columns.Add(ct.Name);
            }

            return dt;
        }
        public static void PopulateSemanticColumns(DataTable dt, Schema schema, List<ConcreteType> columns)
        {
            foreach (ConcreteType ct in schema.ConcreteTypes)
            {
                dt.Columns.Add(ct.Alias);
                columns.Add(ct);
            }

            foreach (Schema st in schema.Subtypes)
            {
                PopulateSemanticColumns(dt, st, columns);
            }
        }
        protected void PopulateCollectionTable(DataTable dt, List<BsonDocument> docs, Schema schema)
        {
            foreach (BsonDocument doc in docs)
            {
                DataRow row = dt.NewRow();

                foreach (ConcreteType ct in schema.ConcreteTypes)
                {
                    row[ct.Name] = doc[ct.Name];
                }

                dt.Rows.Add(row);
            }
        }
        public void Process(ISemanticProcessor proc, IMembrane membrane, ST_AddSchema data)
        {
            Schema schema = new Schema() { Name = data.Name, Alias = data.Alias };
            model.Schemata.Add(schema);
            TreeNode tn = new TreeNode(Helpers.GetSchemaNodeText(schema));
            tn.Tag = schema;
            tn.Nodes.Add("Concrete Types");
            tn.Nodes.Add("Subtypes");

            tv.FindForm().BeginInvoke(() =>
                {
                    tv.Nodes[0].Nodes.Add(tn);
                });
        }
        /// <summary>
        /// Recurse into subtypes to populate all concrete data.
        /// </summary>
        public static void PopulateSemanticTable(DataTable dt, List<BsonDocument> docs, Schema schema)
        {
            foreach (BsonDocument doc in docs)
            {
                DataRow row = dt.NewRow();

                if (doc.Contains("_id"))
                {
                    row["_id"] = doc["_id"];
                }

                PopulateConcreteTypes(row, doc, schema);
                dt.Rows.Add(row);
            }
        }
 protected void InstantiateMonthLookup(SemanticDatabase sd, Schema schema)
 {
     sd.Insert(schema, BsonDocument.Parse("{month: 1, monthName: 'January', monthAbbr: 'Jan'}"));
     sd.Insert(schema, BsonDocument.Parse("{month: 2, monthName: 'February', monthAbbr: 'Feb'}"));
     sd.Insert(schema, BsonDocument.Parse("{month: 3, monthName: 'March', monthAbbr: 'Mar'}"));
     sd.Insert(schema, BsonDocument.Parse("{month: 4, monthName: 'April', monthAbbr: 'Apr'}"));
     sd.Insert(schema, BsonDocument.Parse("{month: 5, monthName: 'May', monthAbbr: 'May'}"));
     sd.Insert(schema, BsonDocument.Parse("{month: 6, monthName: 'June', monthAbbr: 'Jun'}"));
     sd.Insert(schema, BsonDocument.Parse("{month: 7, monthName: 'July', monthAbbr: 'Jul'}"));
     sd.Insert(schema, BsonDocument.Parse("{month: 8, monthName: 'August', monthAbbr: 'Aug'}"));
     sd.Insert(schema, BsonDocument.Parse("{month: 9, monthName: 'September', monthAbbr: 'Sep'}"));
     sd.Insert(schema, BsonDocument.Parse("{month: 10, monthName: 'October', monthAbbr: 'Oct'}"));
     sd.Insert(schema, BsonDocument.Parse("{month: 11, monthName: 'November', monthAbbr: 'Nov'}"));
     sd.Insert(schema, BsonDocument.Parse("{month: 12, monthName: 'December', monthAbbr: 'Dec'}"));
 }
        /// <summary>
        /// Treeview selection.
        /// </summary>
        public void AfterSelectEvent(object sender, TreeViewEventArgs e)
        {
            Helpers.Try(() =>
            {
                object item = e.Node.Tag;

                if (item is Schema)
                {
                    currentSchema = (Schema)item;
                    ShowCollection(currentSchema);
                }
                else if (item is ConcreteType)
                {
                }
            });
        }
        /// <summary>
        /// Treeview selection.
        /// </summary>
        public void AfterSelectEvent(object sender, TreeViewEventArgs e)
        {
            Helpers.Try(() =>
                {
                    object item = e.Node.Tag;

                    if (item is Schema)
                    {
                        currentSchema = (Schema)item;
                        string plan = model.Db.ShowPlan(currentSchema);
                        Program.serviceManager.Get<ISemanticProcessor>().ProcessInstance<PlanViewMembrane, ST_Plan>(p => p.Plan = plan);
                        ResetBuffers();
                        ShowSemanticData(currentSchema);
                    }
                    else if (item is ConcreteType)
                    {
                    }
                });
        }
        public static void PopulateConcreteTypes(DataRow row, BsonDocument doc, Schema schema)
        {
            foreach (ConcreteType ct in schema.ConcreteTypes)
            {
                if (doc.Contains(ct.Alias))
                {
                    row[ct.Alias] = doc[ct.Alias];
                }
                else if (doc.Contains(ct.Name))
                {
                    row[ct.Alias] = doc[ct.Name];
                }
                else
                {
                    row[ct.Alias] = " --- ";
                }
            }

            foreach (Schema st in schema.Subtypes)
            {
                PopulateConcreteTypes(row, doc, st);
            }
        }
        public void Update(Schema schema)
        {
            this.schema = schema;
            string fwdName = schema.Name + "_";
            string revName = "_" + schema.Name;
            List<string> collections = model.Db.GetCollections();
            List<string> forwardAssoc = collections.Where(n => n.BeginsWith(fwdName) && !n.EndsWith("Association")).ToList();
            List<string> reverseAssoc = collections.Where(n => n.EndsWith(revName)).ToList();

            // Update forward and reverse navigation buttons.
            Program.serviceManager.Get<ISemanticProcessor>().ProcessInstance<AssociationViewMembrane, ST_Associations>(data =>
            {
                data.ForwardSchemaNames = forwardAssoc;
                data.ReverseSchemaNames = reverseAssoc;
            });

            List<string> fullList = new List<string>();
            fullList.AddRange(forwardAssoc);
            fullList.AddRange(reverseAssoc);

            DataTable dt = Helpers.FillTable(fullList, "Associations");
            dataView = new DataView(dt);
            view.DataSource = dataView;
        }
        /// <summary>
        /// Add ID's of the source from/to records so we can use the "to" ID's for filtering records when the user moves schema to the main schema view for further navigation.
        /// </summary>
        protected void AddSchemaFromToIds(DataTable dt, List<BsonDocument> docs, Schema fromSchema, Schema toSchema)
        {
            string fromSchemaId = fromSchema.Name + "Id";
            string toSchemaId = model.ToSchema.Name + "Id";
            dt.Columns.Add(fromSchemaId);
            dt.Columns.Add(toSchemaId);

            for (int i = 0; i < dt.Rows.Count; i++)
            {
                dt.Rows[i][fromSchemaId] = docs[i][fromSchemaId];
                dt.Rows[i][toSchemaId] = docs[i][toSchemaId];
            }
        }
 // TODO: Mostly duplicate code
 public void Process(ISemanticProcessor proc, IMembrane membrane, ST_AssociatedData data)
 {
     model.ToData = data.Table;
     schema = data.Schema;
     DataView dv = new DataView(data.Table);
     dgView.FindForm().BeginInvoke(() =>
     {
         dgView.DataSource = dv;
         dgView.Columns[0].Visible = false;								// Hide the ID field.
         dgView.Columns[dgView.Columns.Count - 1].Visible = false;		// Also hide the last two ID fields, which are the ID's of the master and detail records.
         dgView.Columns[dgView.Columns.Count - 2].Visible = false;		// Also hide the last two ID fields, which are the ID's of the master and detail records.
         label.Text = "Semantic Type: " + data.Table.TableName;
     });
 }
        /// <summary>
        /// Delete an entry in the association schema where the doc contains the _id of the association record to delete.
        /// </summary>
        public void DeleteAssociation(Schema schema, BsonDocument doc)
        {
            // For example, person_phoneNumber
            List<BsonDocument> recs = GetAll(schema.Name, doc["_id"].ToString(), true);
            Assert.That(recs.Count == 1, "Association record does not exist.");
            BsonDocument rootRec = recs[0];
            Assert.That(rootRec["_ref"].ToString().to_i() == 1, "Deleting an association record that is itself associated is not supported.");

            // For example, person_phoneNumber_Association
            string rootAssociation = schema.Name + "_Association";
            string rootAssociationId = rootRec[rootAssociation + "Id"].ToString();
            List<BsonDocument> rootAssociationRecs = GetAll(rootAssociation, rootAssociationId, true);
            Assert.That(rootAssociationRecs.Count == 1, "Expected one and only one entry for " + rootAssociation + " where _id = " + rootAssociationId);
            BsonDocument rootAssociationRec = rootAssociationRecs[0];
            string associationId = rootAssociationRec["associationId"].ToString();

            // For example, person_phoneNumber_Assocation references the "assocation" collection.
            List<BsonDocument> associationRecs = GetAll("association", associationId, true);
            Assert.That(associationRecs.Count == 1, "Expected one and only one entry for 'association' where _id = " + associationId);
            BsonDocument associationRec = associationRecs[0];
            string fwdAssocNameId = associationRec["forwardAssociationNameId"].ToString();
            string revAssocNameId = associationRec["reverseAssociationNameId"].ToString();

            // Drill into the forward/reverse AssociationName collections
            List<BsonDocument> fwdRefNamesRecs = GetAll("forwardAssociationName", fwdAssocNameId, true);
            Assert.That(fwdRefNamesRecs.Count == 1, "Expected one and only one name record with _id = " + fwdAssocNameId);
            BsonDocument fwdRefNameRec = fwdRefNamesRecs[0];
            int fwdRefNameCount = fwdRefNameRec["_ref"].ToString().to_i();
            string fwdNameId = fwdRefNameRec["nameId"].ToString();
            List<BsonDocument> revRefNamesRecs = GetAll("reverseAssociationName", revAssocNameId, true);
            Assert.That(revRefNamesRecs.Count == 1, "Expected one and only one name record with _id = " + revAssocNameId);
            BsonDocument revRefNameRec = revRefNamesRecs[0];
            int revRefNameCount = revRefNameRec["_ref"].ToString().to_i();
            string revNameId = revRefNameRec["nameId"].ToString();

            // Drill into the name collection.
            List<BsonDocument> fwdNameRecs = GetAll("name", fwdNameId, true);
            Assert.That(fwdNameRecs.Count == 1, "Expected one and only one name record with _id = " + fwdNameId);
            BsonDocument fwdNameRec = fwdNameRecs[0];
            string fwdName = fwdNameRec["name"].ToString();
            List<BsonDocument> revNameRecs = GetAll("name", revNameId, true);
            Assert.That(revNameRecs.Count == 1, "Expected one and only one name record with _id = " + revNameId);
            BsonDocument revNameRec = revNameRecs[0];
            string revName = revNameRec["name"].ToString();

            // We now have all the pieces needed to traverse back up the hierarchy.
            Schema nameSchema = GetNameSchema();
            InternalDelete(nameSchema, BsonDocument.Parse("{name: '" + fwdName + "'}"));
            InternalDelete(nameSchema, BsonDocument.Parse("{name: '" + revName + "'}"));

            // The rest have no concrete types, so we can't use InternalDelete because we haven't really implemented Delete correctly to handle cascading (downward) deletes.  A big TODO to understand this correctly.
            DecrementRefCountOrDelete("forwardAssociationName", fwdRefNameRec, fwdRefNameCount);
            DecrementRefCountOrDelete("reverseAssociationName", revRefNameRec, revRefNameCount);
            DecrementRefCountOrDelete("association", associationRec, associationRec["_ref"].ToString().to_i());
            DecrementRefCountOrDelete(rootAssociation, rootAssociationRec, rootAssociationRec["_ref"].ToString().to_i());
            DecrementRefCountOrDelete(schema.Name, rootRec, rootRec["_ref"].ToString().to_i());
        }
        protected string InternalInsert(Schema schema, BsonDocument doc)
        {
            string id = null;

            if (schema.IsConcreteType)
            {
                int refCount;
                BsonDocument currentObject = GetConcreteObjects(schema, doc);

                if (currentObject.Elements.Count() == 0)
                {
                    id = null;			// nothing to insert!
                }
                else
                {
                    BsonDocument dealiasedDocument = DeAliasDocument(schema, currentObject);

                    if (IsDuplicate(schema.Name, dealiasedDocument, out id, out refCount))
                    {
                        IncrementRefCount(schema.Name, id, refCount);
                    }
                    else
                    {
                        BsonDocument withRef = AddRef1(dealiasedDocument);
                        id = InsertRecord(schema, withRef);
                    }
                }
            }
            else
            {
                BsonDocument currentObject = GetConcreteObjects(schema, doc);
                BsonDocument subjobj = RemoveCurrentConcreteObjects(schema, doc);
                InsertRecurseIntoSubtypes(schema, currentObject, subjobj);
                int refCount;

                if (currentObject.Elements.Count() == 0)
                {
                    id = null;			// nothing to insert!
                }
                else
                {
                    BsonDocument dealiasedDocument = DeAliasDocument(schema, currentObject);

                    if (IsDuplicate(schema.Name, dealiasedDocument, out id, out refCount))
                    {
                        IncrementRefCount(schema.Name, id, refCount);
                    }
                    else
                    {
                        BsonDocument withRef = AddRef1(dealiasedDocument);
                        id = InsertRecord(schema, withRef);
                    }
                }
            }

            return id;
        }
 protected void InstantiateTestPersonRecords(SemanticDatabase sd, Schema schema)
 {
     sd.Insert(schema, BsonDocument.Parse("{firstName: 'Marc', lastName: 'Clifton'}"));
     sd.Insert(schema, BsonDocument.Parse("{firstName: 'April', lastName: 'Jones'}"));
 }
 protected void InstantiateTestDateRecords(SemanticDatabase sd, Schema schema)
 {
     sd.Insert(schema, BsonDocument.Parse("{month: 8, day: 19, year: 1962}"));
     sd.Insert(schema, BsonDocument.Parse("{month: 4, day: 1, year: 2016}"));
 }
 protected void AddConcreteTypes(Schema schema, TreeNode cttn)
 {
     foreach (ConcreteType ct in schema.ConcreteTypes)
     {
         TreeNode ctNode = cttn.Nodes.Add(Helpers.GetConcreteTypeText(ct));
         ctNode.Tag = ct;
     }
 }
 protected void OnShowReverseAssociatedData(object sender, EventArgs e)
 {
     try
     {
         showForward = false;
         // TODO: If we make this a separate view class, it can maintain the from/to/assoc Schema variables itself instead of hold them in the main form class!
         string assocName = (string)((Button)sender).Tag;
         string fromSchemaName = assocName.LeftOf("_");
         string toSchemaName = assocName.RightOf("_");
         model.FromSchema = model.GetSchema(fromSchemaName);
         model.ToSchema = model.GetSchema(toSchemaName);
         model.IsReverseAssociation = true;
         assocSchema = model.Db.GetAssociationSchema(model.FromSchema, model.ToSchema);
         ShowReverseAssociatedData();
         EnableMoveUp();
     }
     catch (Exception ex)
     {
         Helpers.Log(ex.Message);
         ClearAssociationData();
     }
 }
 /// <summary>
 /// Recurse into subtypes, adding only uniquely named schemas.
 /// </summary>
 protected void AddSchema(Schema schema, List<Schema> schemas)
 {
     schemas.AddIfUnique(schema, x => x.Name == schema.Name);
     schema.Subtypes.ForEach(s => AddSchema(s, schemas));
 }
 protected void AddSubtypes(Schema schema, TreeNode subTypesNode)
 {
     foreach(Schema st in schema.Subtypes)
     {
         TreeNode tn = CreateSchemaNode(st);
         subTypesNode.Nodes.Add(tn);
     }
 }
        public static Schema InstantiateSchema(string json)
        {
            Schema target = new Schema();
            JsonConvert.PopulateObject(json, target);

            return target;
        }
        protected TreeNode CreateSchemaNode(Schema schema)
        {
            TreeNode schemaRootNode = new TreeNode(Helpers.GetSchemaNodeText(schema));
            schemaRootNode.Tag = schema;
            TreeNode concreteTypesNode = schemaRootNode.Nodes.Add("Concrete Types");
            TreeNode subTypesNode = schemaRootNode.Nodes.Add("Subtypes");

            AddConcreteTypes(schema, concreteTypesNode);
            AddSubtypes(schema, subTypesNode);

            return schemaRootNode;
        }