Ejemplo n.º 1
0
        /// <summary>
        /// Creates a list from the data entries in a cache table, using the given where clause and predicate.
        /// </summary>
        public static List <T> BuildListFromTable <T>(string connectionString, string table, WhereClause where, Func <CacheReader, T> func)
        {
            List <T> list = new List <T>();

            using (SqliteConnection db = new SqliteConnection(connectionString))
            {
                db.Open();

                // Check how large the result set will be so we're not constantly
                // Reallocating the array.
                string query = "select count(*) from " + table + " ";
                if (where != null)
                {
                    query += where.GetSql();
                }

                using (SqliteCommand cmd = new SqliteCommand(query, db))
                {
                    if (where != null)
                    {
                        where.AddParameters(cmd);
                    }

                    int val = (int)(long)cmd.ExecuteScalar();
                    list = new List <T>(val);
                }

                // Set up the actual full query.
                query = "select * from " + table;
                if (where != null)
                {
                    query += where.GetSql();
                }

                using (SqliteCommand cmd = new SqliteCommand(query, db))
                {
                    if (where != null)
                    {
                        where.AddParameters(cmd);
                    }

                    using (CacheReader reader = new CacheReader(cmd.ExecuteReader()))
                    {
                        while (reader.NextRow())
                        {
                            try
                            {
                                list.Add(func(reader));
                            }
                            catch (Exception)
                            {
                                throw;
                            }
                        }
                    }
                }
            }

            return(list);
        }
Ejemplo n.º 2
0
        internal static CacheReader CreateReader(SourcePackage upk, string filename)
        {
            var r = new CacheReader(upk, filename);

            r.VerifyMagic(Magic);
            return(r);
        }
Ejemplo n.º 3
0
        public static UxlDefine Read(CacheReader f)
        {
            var name = f.ReadGlobalString();
            var cond = f.ReadGlobalValue();

            return(new UxlDefine(name, cond));
        }
Ejemplo n.º 4
0
        public static ImageFile ReadImageFile(this CacheReader f)
        {
            var flags   = (UxlImageFileFlags)f.ReadByte();
            var srcName = f.ReadGlobalValue();

            SourceValue?dstName = null
            , cond = null;

            if (flags.HasFlag(UxlImageFileFlags.HasCondition))
            {
                cond = f.ReadGlobalValue();
            }
            if (flags.HasFlag(UxlImageFileFlags.HasTargetName))
            {
                dstName = f.ReadGlobalValue();
            }

            int?w = null, h = null;

            if (flags.HasFlag(UxlImageFileFlags.HasTargetWidth))
            {
                w = f.ReadCompressedInt();
            }
            if (flags.HasFlag(UxlImageFileFlags.HasTargetHeight))
            {
                h = f.ReadCompressedInt();
            }

            return(new ImageFile(srcName, cond, dstName, w, h));
        }
Ejemplo n.º 5
0
        /// <summary>
        /// 查询并填充子类信息
        /// </summary>
        /// <param name="pks"></param>
        /// <param name="mappingInfo"></param>
        /// <param name="dicEntity"></param>
        /// <param name="dao"></param>
        /// <param name="lstParamNames"></param>
        /// <param name="db"></param>
        /// <param name="curObjs"></param>
        /// <param name="filter"></param>
        private static void FillChildReader(Queue <object> pks, EntityMappingInfo mappingInfo, Dictionary <string, List <object> > dicEntity, BQLDbBase dao,
                                            ref List <EntityPropertyInfo> lstParamNames, DBInfo db, Queue <object> curObjs, ScopeList filter)
        {
            EntityInfoHandle childInfo = mappingInfo.TargetProperty.BelongInfo;
            string           fullName  = mappingInfo.TargetProperty.BelongInfo.EntityType.FullName;
            Type             childType = mappingInfo.TargetProperty.BelongInfo.EntityType;
            List <object>    senders   = null;

            while (pks.Count > 0)
            {
                Queue <object> searchPks = GetSearchPKs(pks);
                if (searchPks.Count <= 0)
                {
                    break;
                }

                ScopeList lstScope = new ScopeList();
                lstScope.AddScopeList(filter);
                lstScope.AddIn(mappingInfo.TargetProperty.PropertyName, searchPks);
                using (IDataReader reader = dao.QueryReader(lstScope, childInfo.EntityType))
                {
                    //获取子表的get列表
                    if (lstParamNames == null)
                    {
                        lstParamNames = CacheReader.GenerateCache(reader, childInfo);//创建一个缓存数值列表
                    }


                    while (reader.Read())
                    {
                        string fk = reader[mappingInfo.TargetProperty.ParamName].ToString();
                        if (!dicEntity.TryGetValue(fk, out senders))
                        {
                            continue;
                        }
                        object obj = childInfo.CreateSelectProxyInstance();

                        if (curObjs != null)
                        {
                            curObjs.Enqueue(obj);
                        }
                        CacheReader.FillObjectFromReader(reader, lstParamNames, obj, db);

                        foreach (object sender in senders)
                        {
                            if (mappingInfo.IsParent)
                            {
                                mappingInfo.SetValue(sender, obj);
                            }
                            else
                            {
                                IList lst = (IList)mappingInfo.GetValue(sender);
                                lst.Add(obj);
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 6
0
        public static UxlDeprecate Read(CacheReader f)
        {
            var src     = f.ReadSource();
            var oldName = f.ReadGlobalString();
            var newName = f.ReadGlobalString();

            return(new UxlDeprecate(src, oldName, newName));
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Creates a list from the data entries in a cache table, using the given where clause and predicate.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="table"></param>
        /// <param name="where"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        private async Task <List <T> > BuildListFromTable <T>(string table, WhereClause where, Func <CacheReader, Task <T> > func)
        {
            List <T> list = new List <T>();

            using (var db = new SQLiteConnection(_connectionString))
            {
                db.Open();
                // Check how large the result set will be so we're not constantly
                // Reallocating the array.
                var query = "select count(*) from " + table + " ";
                if (where != null)
                {
                    query += where.GetSql();
                }

                using (var cmd = new SQLiteCommand(query, db))
                {
                    if (where != null)
                    {
                        where.AddParameters(cmd);
                    }

                    int val = (int)((long)await cmd.ExecuteScalarAsync());
                    list = new List <T>(val);
                }

                // Set up the actual full query.
                query = "select * from " + table;
                if (where != null)
                {
                    query += where.GetSql();
                }

                using (var cmd = new SQLiteCommand(query, db))
                {
                    if (where != null)
                    {
                        where.AddParameters(cmd);
                    }

                    using (var reader = new CacheReader(cmd.ExecuteReader()))
                    {
                        while (reader.NextRow())
                        {
                            try
                            {
                                list.Add(await func(reader));
                            }
                            catch (Exception ex)
                            {
                                throw ex;
                            }
                        }
                    }
                }
            }
            return(list);
        }
Ejemplo n.º 8
0
        static void Repair(string cachePath)
        {
            var streamFile   = new FileInfo(Path.Combine(cachePath, CacheFetcher.CacheStreamName));
            var checkFile    = new FileInfo(Path.Combine(cachePath, CacheFetcher.CachePositionName));
            var replace      = new FileInfo(Path.Combine(cachePath, CacheFetcher.CachePositionName + ".fix"));
            var posReader    = new FileCheckpointArrayReader(checkFile, 2);
            var vector       = posReader.Read();
            var sourceStream = streamFile.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            var reader       = new CacheReader(new FixedCheckpointArrayReader(vector), sourceStream, posReader);


            var prev = 0L;
            var pos  = 0L;
            var i    = 0L;

            while (true)
            {
                try {
                    var result = reader.ReadAll(pos, 1000, (id, position, maxPosition) => { });
                    if (result.ReadRecords > 0)
                    {
                        prev = pos;
                        pos  = result.CurrentCachePosition;
                        i   += 1;
                        if ((i % 100) == 0)
                        {
                            Console.WriteLine("{0}:{1:F1}GB", i, 1F * pos / 1024 / 1024 / 1024);
                        }
                        continue;
                    }
                    Console.WriteLine("We are good");
                    return;
                }
                catch (InvalidStorageFormatException ex) {
                    Console.WriteLine("Last known position {0}", pos);
                    Console.WriteLine("Previous position {0} (-{1} bytes)", prev, pos - prev);
                    var previousBlock = reader.ReadAll(prev, 1);
                    var msg           = previousBlock.Messages.Single();
                    var offset        = msg.Message.Id.GetOffset();
                    Console.WriteLine("Previous offset {0}", offset);


                    var replaceCheck = new FileCheckpointArrayWriter(replace, 2);
                    replaceCheck.GetOrInitPosition();
                    replaceCheck.Update(new long[] { prev, offset });
                    Console.WriteLine("Backup written");
                }


                break;
            }


            Console.ReadLine();
        }
Ejemplo n.º 9
0
        /// <summary>
        /// 获取缓存中的Reader
        /// </summary>
        /// <param name="tables">表</param>
        /// <param name="sql">SQL语句</param>
        /// <param name="lstParam">变量集合</param>
        /// <returns></returns>
        public IDataReader SetReader(IDataReader reader, IDictionary <string, bool> tables,
                                     string sql, ParamList lstParam, DataBaseOperate oper)
        {
            if (_cache == null)
            {
                return(null);
            }

            DataSet        ds      = CacheReader.GenerateDataSet(reader, false);
            MemCacheReader mreader = new MemCacheReader(ds);

            SetDataSet(ds, tables, sql, lstParam, oper);
            return(mreader);
        }
Ejemplo n.º 10
0
        public static UxlElement Read(CacheReader f)
        {
            var         flags = (UxlElementFlags)f.ReadByte();
            var         key   = f.ReadGlobalValue();
            var         value = f.ReadGlobalValue();
            SourceValue?cond  = null;

            if (flags.HasFlag(UxlElementFlags.HasCondition))
            {
                cond = f.ReadGlobalValue();
            }

            return(new UxlElement((UxlElementType)(flags & UxlElementFlags.TypeMask), key, value, cond, flags.HasFlag(UxlElementFlags.IsDefault)));
        }
Ejemplo n.º 11
0
        public static UxlImplementation Read(CacheReader r)
        {
            var         flags = (UxlImplementationFlags)r.ReadByte();
            var         src   = r.ReadSource();
            var         body  = r.ReadGlobalValue();
            SourceValue?cond  = null;

            if (flags.HasFlag(UxlImplementationFlags.HasCondition))
            {
                cond = r.ReadGlobalValue();
            }

            return(new UxlImplementation(src, (ImplementationType)(flags & UxlImplementationFlags.TypeMask), body, cond, flags.HasFlag(UxlImplementationFlags.IsDefault)));
        }
Ejemplo n.º 12
0
 protected void ReadEntity(CacheReader f, UxlEntityFlags flags)
 {
     if (flags.HasFlag(UxlEntityFlags.Elements))
     {
         f.ReadList(Elements, UxlElement.Read);
     }
     if (flags.HasFlag(UxlEntityFlags.CopyFiles))
     {
         f.ReadList(CopyFiles, r => f.ReadCopyFile());
     }
     if (flags.HasFlag(UxlEntityFlags.ImageFiles))
     {
         f.ReadList(ImageFiles, r => f.ReadImageFile());
     }
 }
Ejemplo n.º 13
0
        public static UxlDeclare Read(CacheReader f)
        {
            var flags = (UxlDeclareFlags)f.ReadByte();
            var src   = f.ReadSource();
            var key   = f.ReadGlobalValue();

            SourceValue?cond = null;

            if (flags.HasFlag(UxlDeclareFlags.HasCondition))
            {
                cond = f.ReadGlobalValue();
            }

            return(new UxlDeclare(src, (UxlDeclareType)(flags & UxlDeclareFlags.TypeMask), key, cond));
        }
Ejemplo n.º 14
0
        public static UxlTemplate Read(CacheReader f)
        {
            var flags = (UxlTemplateFlags)f.ReadByte();

            SourceValue?cond = null;

            if (flags.HasFlag(UxlTemplateFlags.HasCondition))
            {
                cond = f.ReadGlobalValue();
            }

            var result = new UxlTemplate(f.ReadGlobalValue(), cond, flags.HasFlag(UxlTemplateFlags.IsDefault));

            result.ReadEntity(f, (UxlEntityFlags)flags);
            return(result);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// 查询并且返回DataSet(游标分页)
        /// </summary>
        /// <param name="sql">要查询的SQL语句</param>
        /// <param name="objPage">分页对象</param>
        /// <param name="oper">数据库对象</param>
        /// <param name="curType">映射的实体类型(如果用回数据库的原列名,则此为null)</param>
        /// <returns></returns>
        public static DataTable QueryDataTable(string sql, PageContent objPage, DataBaseOperate oper, Type curType)
        {
            DataTable ret       = new DataTable();
            ParamList lstParams = new ParamList();

            lstParams.AddNew("@sql", DbType.AnsiString, sql);
            lstParams.AddNew("@currentIndex", DbType.Int32, objPage.GetStarIndex() + 1);
            lstParams.AddNew("@pagesize", DbType.Int32, objPage.PageSize);
            lstParams.AddNew("@maxRecords", DbType.Int64, objPage.MaxSelectRecords);
            IDataReader reader = null;

            try
            {
                InitProc(oper);
                reader = oper.Query(ProcName, lstParams, CommandType.StoredProcedure, null);
                if (reader.NextResult())//第二个结果集为查询结果
                {
                    if (curType == null)
                    {
                        ret = CacheReader.GenerateDataTable(reader, "newDt", false);
                    }
                    else
                    {
                        ret = CacheReader.GenerateDataTable(reader, "newDt", curType, false);
                    }
                }
                if (reader.NextResult())//第三个结果集为总行数
                {
                    if (reader.Read())
                    {
                        int totalRecord = reader.GetInt32(0);
                        objPage.TotalRecords = totalRecord;
                        //int totalPage = (int)Math.Ceiling((double)objPage.TotalRecords / (double)objPage.PageSize);
                        //objPage.TotalPage = totalPage;
                        if (objPage.CurrentPage >= objPage.TotalPage - 1)
                        {
                            objPage.CurrentPage = objPage.TotalPage - 1;
                        }
                    }
                }
            }
            finally
            {
                reader.Close();
            }
            return(ret);
        }
Ejemplo n.º 16
0
        private void ReadItemGroups()
        {
            using (var reader = new CacheReader(this))
            {
                // NOTE: Order (alphabetical by group name followed by log messages) must match writer.
                Analyzers                   = reader.ReadItemGroup();
                CompileTimeAssemblies       = reader.ReadItemGroup();
                ContentFilesToPreprocess    = reader.ReadItemGroup();
                FrameworkAssemblies         = reader.ReadItemGroup();
                NativeLibraries             = reader.ReadItemGroup();
                ResourceAssemblies          = reader.ReadItemGroup();
                RuntimeAssemblies           = reader.ReadItemGroup();
                RuntimeTargets              = reader.ReadItemGroup();
                TransitiveProjectReferences = reader.ReadItemGroup();

                _logMessages = reader.ReadItemGroup();
            }
        }
Ejemplo n.º 17
0
        public static UxlDocument Read(CacheReader f, SourcePackage upk)
        {
            var backend = (UxlBackendType)f.ReadByte();
            var flags   = (UxlDocumentFlags)f.ReadByte();

            SourceValue?cond = null;

            if (flags.HasFlag(UxlDocumentFlags.HasCondition))
            {
                cond = f.ReadGlobalValue();
            }

            var doc = new UxlDocument(upk, backend, cond);

            if (flags.HasFlag(UxlDocumentFlags.Defines))
            {
                f.ReadList(doc.Defines, UxlDefine.Read);
            }
            if (flags.HasFlag(UxlDocumentFlags.Usings))
            {
                f.ReadList(doc.Usings, r => r.ReadGlobalValue());
            }
            if (flags.HasFlag(UxlDocumentFlags.Declarations))
            {
                f.ReadList(doc.Declarations, UxlDeclare.Read);
            }
            if (flags.HasFlag(UxlDocumentFlags.Deprecations))
            {
                f.ReadList(doc.Deprecations, UxlDeprecate.Read);
            }
            if (flags.HasFlag(UxlDocumentFlags.Templates))
            {
                f.ReadList(doc.Templates, UxlTemplate.Read);
            }
            if (flags.HasFlag(UxlDocumentFlags.Types))
            {
                f.ReadList(doc.Types, UxlType.Read);
            }

            var entityFlags = (UxlEntityFlags)f.ReadByte();

            doc.ReadEntity(f, entityFlags);
            return(doc);
        }
Ejemplo n.º 18
0
    /*
     * Default Required To Initialize the MainAsync() method.
     */
    public static void Main(string[] args)
    {
        Program p = new Program();

        int length = (int)CacheReader.Open();

        cache = CacheReader.SeekCache(0, length, length + 8192);
        CacheReader.Close();

        Task task = p.MainAsync();

        System.Runtime.CompilerServices.TaskAwaiter await = task.GetAwaiter();
        try
        {
            await.GetResult();
        } catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }
Ejemplo n.º 19
0
        /// <summary>
        /// 查询并且返回DataSet(游标分页)
        /// </summary>
        /// <param name="sql">要查询的SQL语句</param>
        /// <param name="lstParam">参数集合</param>
        /// <param name="objPage">分页对象</param>
        /// <param name="oper">数据库对象</param>
        /// <param name="curType">映射的实体类型(如果用回数据库的原列名,则此为null)</param>
        /// <returns></returns>
        public static DataTable QueryDataTable(string sql, ParamList lstParam, PageContent objPage,
                                               DataBaseOperate oper, Type curType, Dictionary <string, bool> cacheTables)
        {
            objPage.TotleRecords = CutPageSqlCreater.GetTotleRecord(lstParam, oper,
                                                                    sql, objPage.MaxSelectRecords, cacheTables);
            long totlePage = (long)Math.Ceiling((double)objPage.TotleRecords / (double)objPage.PageSize);

            objPage.TotlePage = totlePage;
            if (objPage.CurrentPage >= objPage.TotlePage - 1)
            {
                objPage.CurrentPage = objPage.TotlePage - 1;
            }
            if (objPage.CurrentPage >= objPage.TotlePage - 1)
            {
                objPage.CurrentPage = objPage.TotlePage - 1;
            }

            DataTable   ret    = new DataTable();
            IDataReader reader = null;

            try
            {
                string qsql = CutPageSqlCreater.GetCutPageSql(sql, objPage);
                reader = oper.Query(qsql, lstParam, cacheTables);

                if (curType == null)
                {
                    ret = CacheReader.GenerateDataTable(reader, "newDt", false);
                }
                else
                {
                    ret = CacheReader.GenerateDataTable(reader, "newDt", curType, false);
                }
            }
            finally
            {
                reader.Close();
                //oper.CloseDataBase();
            }
            return(ret);
        }
Ejemplo n.º 20
0
        public static UxlType Read(CacheReader f)
        {
            var flags = (UxlTypeFlags)f.ReadByte();
            var name  = f.ReadGlobalValue();

            SourceValue?cond = null;

            if (flags.HasFlag(UxlTypeFlags.HasCondition))
            {
                cond = f.ReadGlobalValue();
            }

            var result = new UxlType(name, cond, flags.HasFlag(UxlTypeFlags.IsDefault));

            if (flags.HasFlag(UxlTypeFlags.Methods))
            {
                f.ReadList(result.Methods, UxlMethod.Read);
            }

            result.ReadEntity(f, (UxlEntityFlags)flags);
            return(result);
        }
Ejemplo n.º 21
0
        public static UxlMethod Read(CacheReader f)
        {
            var flags = (UxlMethodFlags)f.ReadByte();
            var sig   = f.ReadGlobalValue();

            SourceValue?cond = null;

            if (flags.HasFlag(UxlMethodFlags.HasCondition))
            {
                cond = f.ReadGlobalValue();
            }

            var result = new UxlMethod(sig, cond, flags.HasFlag(UxlMethodFlags.IsDefault));

            if (flags.HasFlag(UxlMethodFlags.Implementations))
            {
                f.ReadList(result.Implementations, UxlImplementation.Read);
            }

            result.ReadEntity(f, (UxlEntityFlags)flags);
            return(result);
        }
Ejemplo n.º 22
0
        public static CopyFile ReadCopyFile(this CacheReader f)
        {
            var flags   = (UxlCopyFileFlags)f.ReadByte();
            var srcName = f.ReadGlobalValue();

            SourceValue?dstName = null
            , cond = null
            , type = null;

            if (flags.HasFlag(UxlCopyFileFlags.HasTargetName))
            {
                dstName = f.ReadGlobalValue();
            }
            if (flags.HasFlag(UxlCopyFileFlags.HasCondition))
            {
                cond = f.ReadGlobalValue();
            }
            if (flags.HasFlag(UxlCopyFileFlags.HasType))
            {
                type = f.ReadGlobalValue();
            }

            return(new CopyFile(srcName, (CopyFileFlags)(flags & UxlCopyFileFlags.FlagsMask), dstName, cond, type));
        }
Ejemplo n.º 23
0
        /// <summary>
        /// 从DataReader加载
        /// </summary>
        /// <param name="reader"></param>
        public void LoadFromReader(IDataReader reader)
        {
            EntityInfoHandle entityInfo = EntityInfoManager.GetEntityHandle(CH.GetRealType(this));

            CacheReader.FillInfoFromReader(reader, entityInfo, this);
        }
Ejemplo n.º 24
0
 /// <summary>
 /// 从Reader里边读取数据
 /// </summary>
 /// <typeparam name="T">类型</typeparam>
 /// <param name="reader">reader</param>
 /// <returns></returns>
 protected List <T> LoadFromReaderList(IDataReader reader)
 {
     return(CacheReader.LoadFormReaderList <T>(reader));
 }
Ejemplo n.º 25
0
 /// <summary>
 /// 从Reader里边读取数据
 /// </summary>
 /// <typeparam name="T">类型</typeparam>
 /// <param name="reader">reader</param>
 /// <returns></returns>
 protected T LoadFromReader(IDataReader reader)
 {
     return(CacheReader.LoadFormReader <T>(reader, CurEntityInfo));;
 }
Ejemplo n.º 26
0
        /// <summary>
        /// Loads a TTModel file from a given SQLite3 DB filepath.
        /// </summary>
        public static TTModel FromDb(FileInfo file, Action <bool, string> loggingFunction = null)
        {
            if (loggingFunction == null)
            {
                loggingFunction = ModelModifiers.NoOp;
            }

            string  connectionString = "Data Source=" + file + ";";
            TTModel model            = new TTModel();

            model.Source = file.FullName;

            // Spawn a DB connection to do the raw queries.
            using (SqliteConnection db = new SqliteConnection(connectionString))
            {
                db.Open();

                // Load Mesh Groups
                string query = "select * from meshes order by mesh asc;";
                using (SqliteCommand cmd = new SqliteCommand(query, db))
                {
                    using (CacheReader reader = new CacheReader(cmd.ExecuteReader()))
                    {
                        while (reader.NextRow())
                        {
                            int meshNum = reader.GetInt32("mesh");

                            // Spawn mesh groups as needed.
                            while (model.MeshGroups.Count <= meshNum)
                            {
                                model.MeshGroups.Add(new TTMeshGroup());
                            }

                            model.MeshGroups[meshNum].Name = reader.GetString("name");
                        }
                    }
                }

                // Load Mesh Parts
                query = "select * from parts order by mesh asc, part asc;";
                using (SqliteCommand cmd = new SqliteCommand(query, db))
                {
                    using (CacheReader reader = new CacheReader(cmd.ExecuteReader()))
                    {
                        while (reader.NextRow())
                        {
                            int meshNum = reader.GetInt32("mesh");
                            int partNum = reader.GetInt32("part");

                            // Spawn mesh groups if needed.
                            while (model.MeshGroups.Count <= meshNum)
                            {
                                model.MeshGroups.Add(new TTMeshGroup());
                            }

                            // Spawn parts as needed.
                            while (model.MeshGroups[meshNum].Parts.Count <= partNum)
                            {
                                model.MeshGroups[meshNum].Parts.Add(new TTMeshPart());
                            }

                            model.MeshGroups[meshNum].Parts[partNum].Name = reader.GetString("name");
                        }
                    }
                }

                // Load Bones
                query = "select * from bones where mesh >= 0 order by mesh asc, bone_id asc;";
                using (SqliteCommand cmd = new SqliteCommand(query, db))
                {
                    using (CacheReader reader = new CacheReader(cmd.ExecuteReader()))
                    {
                        while (reader.NextRow())
                        {
                            int meshId = reader.GetInt32("mesh");
                            model.MeshGroups[meshId].Bones.Add(reader.GetString("name"));
                        }
                    }
                }
            }

            // Loop for each part, to populate their internal data structures.
            for (int mId = 0; mId < model.MeshGroups.Count; mId++)
            {
                TTMeshGroup m = model.MeshGroups[mId];
                for (int pId = 0; pId < m.Parts.Count; pId++)
                {
                    TTMeshPart p = m.Parts[pId];
                    WhereClause where = new WhereClause();
                    WhereClause mWhere = new WhereClause();
                    mWhere.Column = "mesh";
                    mWhere.Value  = mId;
                    WhereClause pWhere = new WhereClause();
                    pWhere.Column = "part";
                    pWhere.Value  = pId;

                    where.Inner.Add(mWhere);
                    where.Inner.Add(pWhere);

                    // Load Vertices
                    // The reader handles coalescing the null types for us.
                    p.Vertices = BuildListFromTable(connectionString, "vertices", where, (reader) =>
                    {
                        TTVertex vertex = new TTVertex();

                        // Positions
                        vertex.Position.X = reader.GetFloat("position_x");
                        vertex.Position.Y = reader.GetFloat("position_y");
                        vertex.Position.Z = reader.GetFloat("position_z");

                        // Normals
                        vertex.Normal.X = reader.GetFloat("normal_x");
                        vertex.Normal.Y = reader.GetFloat("normal_y");
                        vertex.Normal.Z = reader.GetFloat("normal_z");

                        // Vertex Colors - Vertex color is RGBA
                        vertex.VertexColor[0] = (byte)Math.Round(reader.GetFloat("color_r") * 255);
                        vertex.VertexColor[1] = (byte)Math.Round(reader.GetFloat("color_g") * 255);
                        vertex.VertexColor[2] = (byte)Math.Round(reader.GetFloat("color_b") * 255);
                        vertex.VertexColor[3] = (byte)Math.Round(reader.GetFloat("color_a") * 255);

                        // UV Coordinates
                        vertex.UV1.X = reader.GetFloat("uv_1_u");
                        vertex.UV1.Y = reader.GetFloat("uv_1_v");
                        vertex.UV2.X = reader.GetFloat("uv_2_u");
                        vertex.UV2.Y = reader.GetFloat("uv_2_v");

                        // Bone Ids
                        vertex.BoneIds[0] = (byte)reader.GetByte("bone_1_id");
                        vertex.BoneIds[1] = (byte)reader.GetByte("bone_2_id");
                        vertex.BoneIds[2] = (byte)reader.GetByte("bone_3_id");
                        vertex.BoneIds[3] = (byte)reader.GetByte("bone_4_id");

                        // Weights
                        vertex.Weights[0] = (byte)Math.Round(reader.GetFloat("bone_1_weight") * 255);
                        vertex.Weights[1] = (byte)Math.Round(reader.GetFloat("bone_2_weight") * 255);
                        vertex.Weights[2] = (byte)Math.Round(reader.GetFloat("bone_3_weight") * 255);
                        vertex.Weights[3] = (byte)Math.Round(reader.GetFloat("bone_4_weight") * 255);

                        return(vertex);
                    });

                    p.TriangleIndices = BuildListFromTable(connectionString, "indices", where, (reader) =>
                    {
                        try
                        {
                            return(reader.GetInt32("vertex_id"));
                        }
                        catch (Exception ex)
                        {
                            throw ex;
                        }
                    });
                }
            }

            // Spawn a DB connection to do the raw queries.
            using (SqliteConnection db = new SqliteConnection(connectionString))
            {
                db.Open();

                // Load Shape Verts
                string query = "select * from shape_vertices order by shape asc, mesh asc, part asc, vertex_id asc;";
                using (SqliteCommand cmd = new SqliteCommand(query, db))
                {
                    using (CacheReader reader = new CacheReader(cmd.ExecuteReader()))
                    {
                        while (reader.NextRow())
                        {
                            string shapeName = reader.GetString("shape");
                            int    meshNum   = reader.GetInt32("mesh");
                            int    partNum   = reader.GetInt32("part");
                            int    vertexId  = reader.GetInt32("vertex_id");

                            TTMeshPart part = model.MeshGroups[meshNum].Parts[partNum];

                            // Copy the original vertex and update position.
                            TTVertex vertex = (TTVertex)part.Vertices[vertexId].Clone();
                            vertex.Position.X = reader.GetFloat("position_x");
                            vertex.Position.Y = reader.GetFloat("position_y");
                            vertex.Position.Z = reader.GetFloat("position_z");

                            TTVertex repVert = part.Vertices[vertexId];
                            if (repVert.Position.Equals(vertex.Position))
                            {
                                // Skip morphology which doesn't actually change anything.
                                continue;
                            }

                            if (!part.ShapeParts.ContainsKey(shapeName))
                            {
                                TTShapePart shpPt = new TTShapePart();
                                shpPt.Name = shapeName;
                                part.ShapeParts.Add(shapeName, shpPt);
                            }

                            part.ShapeParts[shapeName].VertexReplacements.Add(vertexId, part.ShapeParts[shapeName].Vertices.Count);
                            part.ShapeParts[shapeName].Vertices.Add(vertex);
                        }
                    }
                }
            }

            // Convert the model to FFXIV's internal weirdness.
            ModelModifiers.MakeImportReady(model, loggingFunction);
            return(model);
        }