/// <summary> /// Reads a table and inject it as a tuple set in OPL. /// </summary> /// <param name="name">The name of the Data Set</param> /// <param name="reader">The SqlDataReader to read from</param> private void ReadTupleSet(String name, DbDataReader reader) { OplDataHandler handler = DataHandler; OplElement element = handler.getElement(name); ITupleSchema schema = element.AsTupleSet().Schema; int size = schema.Size; String[] oplFieldsName = new String[size]; OplElementDefinitionType.Type[] oplFieldsType = new OplElementDefinitionType.Type[size]; this.FillNamesAndTypes(schema, oplFieldsName, oplFieldsType); handler.StartElement(name); handler.StartSet(); while (reader.Read()) { handler.StartTuple(); for (int column = 0; column < oplFieldsName.Length; column++) { String columnName = oplFieldsName[column]; HandleColumnValue(handler, oplFieldsType[column], reader[columnName]); } handler.EndTuple(); } handler.EndSet(); }
public override void CustomRead() { OplDataHandler handler = DataHandler; // Get the element of the predefined name. // If no such element is defined then exit early. // The element must be either a tuple or a set of tuples. // Any custom load specification specified by the element is then processed. OplElement spec = handler.getElement(ELEM_NAME); if (spec == null) { return; } if (spec.ElementType == OplElementType.Type.TUPLE) { loadSpec(handler, spec.AsTuple()); } else if (spec.ElementType == OplElementType.Type.SET_TUPLE) { foreach (ITuple tuple in spec.AsTupleSet()) { loadSpec(handler, tuple); } } else { throw new NotImplementedException(ELEM_NAME + " must be (set of) tuple"); } }
/// <summary> /// Load an element that is a plain tuple. /// </summary> private void loadTuple(OplDataHandler handler, string name, IEnumerator <IRow> rows) { OplElement elem = handler.getElement(name); ITuple tuple = elem.AsTuple(); handler.StartElement(name); rows.MoveNext(); fillTuple(handler, tuple.Schema, rows.Current, 0); handler.EndElement(); }
/// <summary> /// Writes the specified data set as the specified target table. /// </summary> /// <param name="name">The name of the OPL data set</param> /// <param name="targetTable">The target table</param> public void WriteTable(DbConnection con, string name, String targetTable) { // The opl element to write OplElement element = this.Model.GetElement(name); ITupleSet tupleSet = element.AsTupleSet(); ITupleSchema tupleSchema = tupleSet.Schema; // drop existing table DropTable(con, targetTable); // Create table String[] tableDef = TableDefinitionFromOplTupleSchema(tupleSchema, true); CreateTable(con, tableDef, targetTable); // Populate table String insertCommand = CreateInsertCommand(tupleSchema, targetTable); foreach (ITuple t in tupleSet) { InsertIntoTable(con, tupleSchema, t, insertCommand); } }
/// <summary> /// Interpolate model elements or environment variables into a string. /// Character sequences like $(NAME) are replaced with the model element NAME. /// Character sequences like ${NAME} are replaced with the environment variable NAME. /// </summary> /// <param name="text">The text in which the replacement happens.</param> /// <param name="handler">The handler from which model elements are read.</param> /// <returns></returns> private static string Interpolate(string text, OplDataHandler handler) { // Return value StringBuilder b = new StringBuilder(text.Length); // The closing parenthesis we are looking for (or NUL) char unquote = '\0'; // The text between open and closing parenthesis. StringBuilder quoted = null; // Was the last character a $ bool dollar = false; foreach (char c in text) { if (unquote != '\0') { if (c == unquote) { switch (unquote) { case ')': // Interpolate model element OplElement elem = handler.getElement(quoted.ToString()); if (elem == null) { throw new SystemException("undefined element " + quoted.ToString() + " referenced in " + text); } if (elem.ElementType.Equals(OplElementType.Type.INT)) { b.Append(elem.AsInt()); } else if (elem.ElementType.Equals(OplElementType.Type.NUM)) { b.Append(elem.AsNum()); } else if (elem.ElementType.Equals(OplElementType.Type.STRING)) { b.Append(elem.AsString()); } else { throw new SystemException("reference element " + quoted.ToString() + " has invalid type " + elem.ElementType); } break; case '}': // Interpolate environment variable. string value = Environment.GetEnvironmentVariable(quoted.ToString()); if (value != null) { b.Append(value); } break; } unquote = '\0'; quoted = null; } else { quoted.Append(c); } } else if (c == '$') { if (dollar) { // $$ is used to mean a literal $ b.Append('$'); dollar = false; } else { dollar = true; } } else if (dollar) { // last character was a $ but current one is not: we must start a quote switch (c) { case '(': unquote = ')'; quoted = new StringBuilder(); break; case '{': unquote = '}'; quoted = new StringBuilder(); break; default: throw new SystemException("ínvalid text " + text); } dollar = false; } else { b.Append(c); } } if (dollar || unquote != '\0') { throw new SystemException("bad quotes in " + text); } return(b.ToString()); }
/// <summary> /// Process one load specification. /// </summary> /// <param name="handler">The data loader that constructs OPL elements.</param> /// <param name="tuple">The load specification.</param> private void loadSpec(OplDataHandler handler, ITuple tuple) { // Get the connection string // In the SimpleData implementation we don't use that string. // If you create a data source that is backed up by a file or // by a database, then this string can be used to specify // locations and/or credentials. string connection = tuple.GetStringValue(CONN_FIELD); connection = Interpolate(connection, handler); string connectionType = tryLoadField(tuple, TYPE_FIELD, "SimpleData"); connectionType = Interpolate(connectionType, handler); IDataProvider provider = null; if (connectionType.Equals("SimpleData")) { provider = new SimpleData(connection); } else if (connectionType.Equals("SQLite")) { provider = new SQLiteData(connection); } else { provider = new GenericData(connectionType, connection); } // Process each of load specifications and load the respective // element. using (provider) { ISymbolSet data = tuple.GetSymbolSetValue(DATA_FIELD); IEnumerator e = data.GetEnumerator(); while (e.MoveNext()) { // Split specification into element name and // initialiation string (statement). string s = Interpolate(e.Current.ToString().Trim(), handler); int eq = s.IndexOf('='); string name = s.Substring(0, eq).Trim(); string stmt = s.Substring(eq + 1).Trim(); // Inspect the type of the element and populate it. OplElement elem = handler.getElement(name); OplElementType.Type type = elem.ElementType; using (IEnumerator <IRow> rows = provider.getRows(stmt)) { // (collections of) integers if (type == OplElementType.Type.INT) { loadPrimitive(handler, name, rows, SET_INT); } else if (type == OplElementType.Type.SET_INT) { loadPrimitiveCollection(handler, name, rows, START_SET, END_SET, SET_INT); } else if (type == OplElementType.Type.MAP_INT) { loadPrimitiveCollection(handler, name, rows, START_ARRAY, END_ARRAY, SET_INT); } // (collections of) floating point values else if (type == OplElementType.Type.NUM) { loadPrimitive(handler, name, rows, SET_FLOAT); } else if (type == OplElementType.Type.SET_NUM) { loadPrimitiveCollection(handler, name, rows, START_SET, END_SET, SET_FLOAT); } else if (type == OplElementType.Type.MAP_NUM) { loadPrimitiveCollection(handler, name, rows, START_ARRAY, END_ARRAY, SET_FLOAT); } // (collections of) tuples else if (type == OplElementType.Type.STRING) { loadPrimitive(handler, name, rows, SET_STRING); } else if (type == OplElementType.Type.SET_SYMBOL) { loadPrimitiveCollection(handler, name, rows, START_SET, END_SET, SET_STRING); } else if (type == OplElementType.Type.MAP_SYMBOL) { loadPrimitiveCollection(handler, name, rows, START_ARRAY, END_ARRAY, SET_STRING); } else if (type == OplElementType.Type.TUPLE) { loadTuple(handler, name, rows); } else if (type == OplElementType.Type.SET_TUPLE) { loadTupleCollection(handler, name, rows, elem.AsTupleSet().Schema, START_SET, END_SET); } else if (type == OplElementType.Type.MAP_TUPLE) { loadTupleCollection(handler, name, rows, elem.AsTupleMap().Schema, START_ARRAY, END_ARRAY); } else { throw new NotImplementedException("element type " + type + " not implemented"); } } } } }