private static int importItem(IServerSession session, SetConfig workingConf) { // hook API logger Logger.SetLogSink(HandleLogEntry); try { /*string ncHostname = "10.50.149.13"; * int ncPort = 80;9(*/ Oid targetTable = new Oid(workingConf.oidForWrite); //using (session /*IServerSession session = CSAPI.Create().CreateServerSession(ncHostname, ncPort)*/) //{ //if (false/*!Authenticate(session)*/) //{ // session.Dispose(); // return -1; //} // else // { /* Get access to read the table */ try { var result = session.DataAccess.Brokers.DataTable.ReadSingle( session.ModelFactory.CreateSelectorById(targetTable), new IRelationshipMetaData[] { MetaData.DataTableToDataTableDesign, MetaData.DataTableDesignToDataTableField, MetaData.DataTableToFileInDataTable, MetaData.DataTableToDataRow }); IDataTable datatable = result.Value; if (result.Value == null) { return(2); } } catch (InvalidOperationException) { Console.WriteLine("Connection/authentication error. Reauthenticating before next iteration"); return(-1); } /* The change set is a list of all changes to the database that will be sent after all edits are done */ IChangeSet changes = session.DataAccess.CreateChangeSet(); /* Delete all rows from the table */ session.DataAccess.Brokers.DataTable.DeleteDataRows(changes, targetTable, session.ModelFactory.CreateAllSelector()); /* TODO: Allow support for appending to tables instead of a fixed number of rows */ int i = 1; if (workingConf.allOneRecord == false) { List <List <string> > col_lists = new List <List <string> >(); List <IChangeSet> trigger_changes = new List <IChangeSet>(); /* TODO: Fork the process so that general datatable updates don't have to happen unless there is a change in the state of the triggered table */ foreach (colConf entry in workingConf.cols) { List <string> col_vals = new List <string>(); col_vals.Add(entry.name_of_col); XmlDocument xd = new XmlDocument(); int retries = 3; do //Solves transient network issues that occur when repeatedly pulling updated XML documents { try { xd.Load(entry.source); break; } catch (WebException) { Console.WriteLine("Failed to get XML file from server, retrying . . ."); if (retries <= 0) { Console.WriteLine("Retrying failed. Skipping document until next iteration."); } else { Thread.Sleep(300); } } }while (retries-- > 0); if (retries <= 0) { break; } XmlNamespaceManager nsmgr = new XmlNamespaceManager(xd.NameTable); /* Namespace entries (does not have to be exclusive to the entry that uses it, so long as there are no conflicts!) */ /* nsmgr.AddNamespace("yweather", "http://xml.weather.yahoo.com/ns/rss/1.0"); * nsmgr.AddNamespace("m", "http://www.w3.org/2005/Atom"); * nsmgr.AddNamespace("cap", "urn:oasis:names:tc:emergency:cap:1.1"); * nsmgr.AddNamespace("atom", "http://www.w3.org/2005/Atom"); */ /* (Experimental) Add user specified namespaces [TODO: Should add error handling so that program can continue if it fails] */ foreach (nsConf ns_info in workingConf.ns_list) { nsmgr.AddNamespace(ns_info.ns, ns_info.ns_source); } XmlNodeList found_nodes = xd.SelectNodes(entry.description, nsmgr); if (entry.firesTrigger) { bool triggered = false; /* Create new trigger_change set if column is triggerable*/ IChangeSet trigger_change = session.DataAccess.CreateChangeSet(); var result2 = session.DataAccess.Brokers.Trigger.ReadSingle(session.ModelFactory.CreateSelectorById(new Oid(entry.triggerID)), null); Oid m_triggerDataTableId = result2.Value.DataTable.Id; foreach (XmlNode nodeInList in found_nodes) { if (!triggered) { triggered = true; // Prevents multiple triggers when there is more than one node in the triggerable column /* Adding a row to the trigger payload table activates the trigger */ IDataRow trigger_row = session.ModelFactory.CreateDataRow(); trigger_row.ActivationDate = DateTime.Now; trigger_row.ExpirationDate = DateTime.Now.AddDays(5); //I really need to figure out how to write this in more clearly. Perhaps being able to clear triggers? trigger_row.SequenceNumber = 0; session.DataAccess.Brokers.DataTable.CreateDataRow(trigger_change, m_triggerDataTableId, trigger_row); trigger_changes.Add(trigger_change); } if (!String.IsNullOrEmpty(entry.attrib)) { col_vals.Add(nodeInList.Attributes[entry.attrib].Value); } else { string valueToAdd = String.IsNullOrEmpty(nodeInList.Value) ? nodeInList.InnerText : nodeInList.Value; col_vals.Add(valueToAdd); } } if (!triggered) // Clears the trigger if no data is added to the table upon update { session.DataAccess.Brokers.DataTable.DeleteDataRows(changes, m_triggerDataTableId, session.ModelFactory.CreateAllSelector()); trigger_changes.Add(trigger_change); } } else { foreach (XmlNode nodeInList in found_nodes) { if (!String.IsNullOrEmpty(entry.attrib)) { col_vals.Add(nodeInList.Attributes[entry.attrib].Value); } else { string valueToAdd = String.IsNullOrEmpty(nodeInList.Value) ? nodeInList.InnerText : nodeInList.Value; col_vals.Add(valueToAdd); } } } col_lists.Add(col_vals); } for (int j = 1; j <= workingConf.numRows; j++) { /* Add new rows to the table */ IDataRow row = session.ModelFactory.CreateDataRow(); row.SequenceNumber = i; row.ActivationDate = new DateTime(1601, 1, 1); row.ExpirationDate = new DateTime(3000, 1, 1); foreach (List <string> col in col_lists) { try { row.Values[col[0]] = col[j]; } catch (ArgumentOutOfRangeException) { break; } catch (IndexOutOfRangeException) { break; } } session.DataAccess.Brokers.DataTable.CreateDataRow(changes, targetTable, row); i++; } changes.Save(); foreach (IChangeSet trig_cha in trigger_changes) { trig_cha.Save(); } } else { /* TODO: Add a generic trigger to sources that are all on one record */ /* Access the Xml data source */ String URLString = workingConf.sourceUrl; XmlDocument xd = new XmlDocument(); xd.Load(URLString); XmlNamespaceManager nsmgr = new XmlNamespaceManager(xd.NameTable); /* (Experimental) Add user specified namespaces [Should add error handling so that program can continue if it fails] */ foreach (nsConf ns_info in workingConf.ns_list) { nsmgr.AddNamespace(ns_info.ns, ns_info.ns_source); } //nsmgr.AddNamespace("yweather", "http://xml.weather.yahoo.com/ns/rss/1.0"); XmlNodeList nodeOfRec = xd.SelectNodes(workingConf.itemOfRec, nsmgr); foreach (XmlNode node in nodeOfRec) { //Add new rows to the table IDataRow row = session.ModelFactory.CreateDataRow(); row.SequenceNumber = i; row.ActivationDate = new DateTime(1601, 1, 1); row.ExpirationDate = new DateTime(3000, 1, 1); if (node.HasChildNodes) /* Then the items we are looking for are not attributes of the node of record (but could be attributes of a child node) */ { foreach (XmlNode cnode in node.ChildNodes) { foreach (colConf testcols in workingConf.cols) { if (testcols.description == cnode.Name) { if (!String.IsNullOrEmpty(testcols.attrib)) { row.Values[testcols.name_of_col] = cnode.Attributes[testcols.attrib].Value; } else { row.Values[testcols.name_of_col] = cnode.Value; } } } } } else /* We are looking at the node of record's attributes only */ { XmlAttributeCollection xac = node.Attributes; foreach (XmlAttribute xa in xac) { foreach (colConf testcols in workingConf.cols) { if (testcols.attrib == xa.Name) { row.Values[testcols.name_of_col] = xa.Value; break; } } } session.DataAccess.Brokers.DataTable.CreateDataRow(changes, targetTable, row); i++; } } changes.Save(); } return(0); } finally { // unhook logger Logger.SetLogSink(null); } }
public static int Main(string[] args) { int ret = 0; Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e) { e.Cancel = true; Program.interrupted = true; }; int res; string ncHostname = "10.50.149.13"; int ncPort = 80; IServerSession session = CSAPI.Create().CreateServerSession(ncHostname, ncPort); //Authenticate(session); bool authenticated; do { authenticated = Authenticate(session); }while (!authenticated); while (!Program.interrupted) { Console.WriteLine("Updating internal database..."); Console.WriteLine((Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\" + Properties.Settings.Default.dbfilepath)); WatchedSets sets = new WatchedSets((Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\" + Properties.Settings.Default.dbfilepath)); foreach (w_set toLoad in sets.all_set) { workingConf = new SetConfig(toLoad.TABLE_DB_PATH); res = importItem(session, workingConf); Console.WriteLine("Updating table: " + toLoad.TABLE_NAME); if (res == 2) //Server Timeout { Console.WriteLine("Server timeout, disconnecting . . ."); bool reauthen = false; do { Thread.Sleep(5000); session = CSAPI.Create().CreateServerSession(ncHostname, ncPort); reauthen = Authenticate(session); }while (!reauthen); break; } else if (res == -1) { Console.WriteLine("Authentication error, retrying . . ."); bool reauthen = false; do { Thread.Sleep(5000); session = CSAPI.Create().CreateServerSession(ncHostname, ncPort); reauthen = Authenticate(session); }while (!reauthen); break; } else { Console.WriteLine("Updated: " + toLoad.TABLE_NAME); } } Console.WriteLine("Finished... Sleeping..."); Thread.Sleep(900000); } return(ret); }