Ejemplo n.º 1
0
        /// <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");
                    }
                }
            }
        }
    }