Пример #1
0
        /// <summary>
        /// Saves all instances to the database
        /// </summary>
        public void Save()
        {
            foreach (SEntity entity in this.Instances.Values)
            {
                Type t = entity.GetType();
                IList <FieldInfo> fields = SEntity.GetFieldsOrdered(t);

                if (entity.Existing)
                {
                    //...update attributes...
                }
                else
                {
                    // create new
                    StringBuilder sb = new StringBuilder();
                    sb.Append("INSERT INTO ");
                    sb.Append(t.Name);
                    sb.Append("(oid");
                    foreach (FieldInfo f in fields)
                    {
                        if (!f.FieldType.IsGenericType)                         // don't deal with lists
                        {
                            sb.Append(", ");
                            sb.Append(f.Name);
                        }
                    }
                    sb.Append(") VALUES (");
                    sb.Append(entity.OID.ToString());
                    foreach (FieldInfo f in fields)
                    {
                        if (!f.FieldType.IsGenericType)                         // don't deal with lists
                        {
                            sb.Append(", ");
                            object val = f.GetValue(entity);
                            if (val is SEntity)
                            {
                                SEntity entref = (SEntity)val;
                                sb.Append(entref.OID);
                            }
                            else if (val is byte[])
                            {
                                byte[] bval = (byte[])val;
                                sb.Append("'");
                                sb.Append(BitConverter.ToString(bval));
                                sb.Append("'");
                            }
                            else if (val != null)
                            {
                                string encoded = val.ToString();
                                if (encoded != null)
                                {
                                    if (val is string || val is Enum)
                                    {
                                        sb.Append("'");
                                    }
                                    sb.Append(encoded.Replace("'", "''"));                                     // escape single quotes - note: does not handle other unicode quotes
                                    if (val is string || val is Enum)
                                    {
                                        sb.Append("'");
                                    }
                                }
                                else
                                {
                                    sb.Append("NULL");
                                }
                            }
                            else
                            {
                                sb.Append("NULL");
                            }
                        }
                    }
                    sb.Append(");");

                    Execute(sb.ToString());
                    entity.Existing = true;
                }

                // lists
                foreach (FieldInfo f in fields)
                {
                    if (f.FieldType.IsGenericType)
                    {
                        string tablename = t.Name + "_" + f.Name;

                        // clear existing
                        Execute("DELETE FROM " + tablename + " WHERE source=" + entity.OID.ToString() + ";");

                        System.Collections.IList list = (System.Collections.IList)f.GetValue(entity);
                        if (list != null)
                        {
                            for (int i = 0; i < list.Count; i++)
                            {
                                SEntity target = (SEntity)list[i];

                                Execute("INSERT INTO " + tablename +
                                        " (source, sequence, target) VALUES (" +
                                        entity.OID.ToString() + ", " +
                                        i.ToString() + ", " +
                                        target.OID.ToString() + ");");
                            }
                        }
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Creates database table(s) for type
        /// </summary>
        /// <param name="t"></param>
        public void InitType(Type t)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("CREATE TABLE ");
            sb.Append(t.Name);
            sb.Append(" (oid INTEGER");
            IList <FieldInfo> fields = SEntity.GetFieldsOrdered(t);

            foreach (FieldInfo f in fields)
            {
                if (!f.FieldType.IsGenericType)                 // don't deal with lists
                {
                    sb.Append(", ");

                    sb.Append(f.Name);
                    sb.Append(" ");

                    if (typeof(SEntity).IsAssignableFrom(f.FieldType))
                    {
                        sb.Append(" INTEGER");                         // oid
                    }
                    else if (f.FieldType.IsEnum)
                    {
                        sb.Append(" VARCHAR");
                    }
                    else if (typeof(string) == f.FieldType)
                    {
                        //if (f.Name.Equals("_Documentation") || f.Name.Equals("_Description") || f.Name.Equals("_Expression"))
                        if (f.Name.Equals("_Name"))
                        {
                            // for name, indexable
                            sb.Append(" VARCHAR");
                        }
                        else
                        {
                            // all others unlimited text
                            sb.Append(" TEXT");
                        }
                    }
                    else if (typeof(bool) == f.FieldType)
                    {
                        sb.Append(" BIT");
                    }
                    else if (typeof(int) == f.FieldType)
                    {
                        sb.Append(" INTEGER");
                    }
                    else if (typeof(double) == f.FieldType)
                    {
                        sb.Append(" FLOAT");
                    }
                    else if (typeof(byte[]) == f.FieldType)
                    {
                        sb.Append(" TEXT");
                    }
                    else
                    {
                        System.Diagnostics.Debug.WriteLine("FormatMDB::InitType() - incompatible field type");
                    }
                }
            }
            sb.Append(");");
            Execute(sb.ToString());

            // populate relationships for LISTs
            foreach (FieldInfo f in fields)
            {
                if (f.FieldType.IsGenericType && f.FieldType.GetGenericTypeDefinition() == typeof(List <>))
                {
                    sb = new StringBuilder();
                    sb.Append("CREATE TABLE ");
                    sb.Append(t.Name);
                    sb.Append("_");
                    sb.Append(f.Name);
                    sb.Append(" (source INTEGER, sequence INTEGER, target INTEGER);");
                    Execute(sb.ToString());
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Loads all instances from the database
        /// </summary>
        public void Load()
        {
            // first pass: load all entities and non-list attributes
            foreach (Type t in this.m_typemap.Values)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("SELECT * FROM ");
                sb.Append(t.Name);

                IList <FieldInfo> fields = SEntity.GetFieldsOrdered(t);

                // load scalar attributes
                using (OleDbCommand cmd = this.m_connection.CreateCommand())
                {
                    cmd.CommandText = sb.ToString();
                    using (OleDbDataReader reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            int oid = reader.GetInt32(0);

                            SEntity entity = null;
                            if (!this.Instances.TryGetValue(oid, out entity))
                            {
                                entity          = (SEntity)System.Runtime.Serialization.FormatterServices.GetUninitializedObject(t);
                                entity.Existing = true;
                                entity.OID      = oid;
                                this.Instances.Add(entity.OID, entity);

                                if (entity.OID > m_lastOID)
                                {
                                    this.m_lastOID = entity.OID;
                                }
                            }

                            int index = 0;
                            foreach (FieldInfo f in fields)
                            {
                                if (!f.FieldType.IsGenericType)
                                {
                                    // non-list attribute
                                    index++;
                                    object value = reader.GetValue(index);
                                    if (value != null && !(value is DBNull))
                                    {
                                        if (f.FieldType.IsEnum)
                                        {
                                            object eval = Enum.Parse(f.FieldType, value.ToString());
                                            f.SetValue(entity, eval);
                                        }
                                        else if (typeof(SEntity).IsAssignableFrom(f.FieldType))
                                        {
                                            if (value is Int32)
                                            {
                                                int     ival = (int)value;
                                                SEntity eval = null;
                                                if (this.Instances.TryGetValue(ival, out eval))
                                                {
                                                    f.SetValue(entity, eval);
                                                }
                                            }
                                        }
                                        else if (typeof(byte[]) == f.FieldType)
                                        {
                                            string strval = (string)value;
                                            int    len    = strval.Length / 2;

                                            Byte[] valuevector = new byte[len];
                                            for (int i = 0; i < len; i++)
                                            {
                                                char hi = strval[i * 2 + 0];
                                                char lo = strval[i * 2 + 1];

                                                byte val = (byte)(
                                                    ((hi >= 'A' ? +(int)(hi - 'A' + 10) : (int)(hi - '0')) << 4) +
                                                    ((lo >= 'A' ? +(int)(lo - 'A' + 10) : (int)(lo - '0'))));

                                                valuevector[i] = val;
                                            }

                                            f.SetValue(entity, valuevector);
                                        }
                                        else
                                        {
                                            f.SetValue(entity, value);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // second pass: load lists (now that all entities are loaded)
            foreach (Type t in this.m_typemap.Values)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("SELECT * FROM ");
                sb.Append(t.Name);
                sb.Append(";");

                IList <FieldInfo> fields = SEntity.GetFieldsOrdered(t);

                // load vector attributes
                using (OleDbCommand cmd = this.m_connection.CreateCommand())
                {
                    cmd.CommandText = sb.ToString();
                    using (OleDbDataReader reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            long    oid    = (long)reader.GetInt32(0);
                            SEntity entity = this.Instances[oid];

                            foreach (FieldInfo f in fields)
                            {
                                if (f.FieldType.IsGenericType)
                                {
                                    // list
                                    System.Collections.IList list = (System.Collections.IList)f.GetValue(entity);
                                    if (list == null)
                                    {
                                        list = (System.Collections.IList)Activator.CreateInstance(f.FieldType);
                                        f.SetValue(entity, list);
                                    }

                                    using (OleDbCommand cmdList = this.m_connection.CreateCommand())
                                    {
                                        StringBuilder sbl = new StringBuilder();
                                        sbl.Append("SELECT * FROM ");
                                        sbl.Append(t.Name);
                                        sbl.Append("_");
                                        sbl.Append(f.Name);
                                        sbl.Append(" WHERE source=");
                                        sbl.Append(entity.OID.ToString());
                                        sbl.Append(" ORDER BY sequence;");
                                        cmdList.CommandText = sbl.ToString();
                                        using (OleDbDataReader readerList = cmdList.ExecuteReader())
                                        {
                                            while (readerList.Read())
                                            {
                                                long    refid  = (long)readerList.GetInt32(2);
                                                SEntity target = this.Instances[refid];
                                                list.Add(target);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #4
0
        private void WriteEntity(SEntity o)
        {
            // sanity check
            if (this.m_indent > 100)
            {
                return;
            }

            Type t = o.GetType();

            string hyperlink = "../../schema/" + t.Namespace.ToLower() + "/lexical/" + t.Name.ToLower() + ".htm";

            this.WriteStartElement(t.Name, hyperlink);

#if false
            // id
            if (gen != null)
            {
                bool firstTime;
                long id = gen.GetId(o, out firstTime);
                writer.WriteAttributeString("id", "i" + id.ToString());
            }
#endif

            /*
             * writer.WriteStartAttribute("id");
             * writer.WriteValue("i" + id.ToString());
             * writer.WriteEndAttribute();*/

            // write fields as attributes
            bool haselements         = false;
            IList <FieldInfo> fields = SEntity.GetFieldsOrdered(t);
            foreach (FieldInfo f in fields)
            {
                object v = f.GetValue(o);
                if (v != null)
                {
                    if (f.FieldType.IsValueType)
                    {
                        Type ft = f.FieldType;
                        if (ft.IsGenericType && ft.GetGenericTypeDefinition() == typeof(Nullable <>))
                        {
                            // special case for Nullable types
                            ft = ft.GetGenericArguments()[0];
                        }

                        Type typewrap = null;
                        while (ft.IsValueType && !ft.IsPrimitive)
                        {
                            FieldInfo fieldValue = ft.GetField("Value");
                            if (fieldValue != null)
                            {
                                v = fieldValue.GetValue(v);
                                if (typewrap == null)
                                {
                                    typewrap = ft;
                                }
                                ft = fieldValue.FieldType;
                            }
                            else
                            {
                                break;
                            }
                        }

                        if (v != null)
                        {
                            string encodedvalue = System.Security.SecurityElement.Escape(v.ToString());

                            m_writer.Write(" ");
                            m_writer.Write(f.Name);
                            m_writer.Write("=\"");
                            m_writer.Write(encodedvalue); //... escape it
                            m_writer.Write("\"");
                        }
                    }
                    else
                    {
                        haselements = true;
                    }
                }
            }

            IList <FieldInfo> inverses = SEntity.GetFieldsInverse(t);

            if (haselements || inverses.Count > 0)
            {
                WriteOpenElement();

                // write direct object references and lists
                foreach (FieldInfo f in fields)
                {
                    DocXsdFormat format = GetXsdFormat(f);

                    // hide fields where inverse attribute used instead
                    if (!f.FieldType.IsValueType &&
                        (format == null || (format.XsdFormat != DocXsdFormatEnum.Hidden)))
                    {
                        WriteAttribute(o, f);
                    }
                }

                // write inverse object references and lists
                foreach (FieldInfo f in inverses)
                {
                    DocXsdFormat format = GetXsdFormat(f);
                    if (format != null && format.XsdFormat == DocXsdFormatEnum.Element) //... check this
                    {
                        WriteAttribute(o, f);                                           //... careful - don't write back-references...
                    }
                }

                WriteEndElement(t.Name);
            }
            else
            {
                // close opening tag
                if (this.m_markup)
                {
                    this.m_writer.WriteLine("/&gt;<br/>");
                }
                else
                {
                    this.m_writer.WriteLine("/>");
                }

                this.m_indent--;
            }
        }