Ejemplo n.º 1
0
        /// <summary>
        /// 增减外键引用计数值
        /// </summary>
        internal async ValueTask AddEntityRefAsync(EntityRefModel entityRef,
                                                   ApplicationModel fromApp, Entity fromEntity, int diff)
        {
            Debug.Assert(diff != 0);
            Debug.Assert(fromEntity.Id.RaftGroupId != 0);

            var targetId = fromEntity.GetEntityId(entityRef.FKMemberIds[0]);

            if (targetId == null || targetId.IsEmpty)
            {
                return;
            }
            ulong targetModelId = entityRef.IsAggregationRef ? fromEntity.GetUInt64(entityRef.TypeMemberId) : entityRef.RefModelIds[0];
            var   targetModel   = await RuntimeContext.Current.GetModelAsync <EntityModel>(targetModelId);

            var targetAppId = IdUtil.GetAppIdFromModelId(targetModelId);
            var targetApp   = await RuntimeContext.Current.GetApplicationModelAsync(targetAppId);

            //注意编码
            uint fromTableId = KeyUtil.EncodeTableId(fromApp.StoreId, entityRef.Owner.TableId);

            var item = new RefFromItem()
            {
                TargetEntityId  = targetId,
                FromTableId     = fromTableId,
                FromRaftGroupId = fromEntity.Id.RaftGroupId
            };

            lock (this)
            {
                if (refs == null)
                {
                    item.Diff = diff;
                    refs      = new List <RefFromItem> {
                        item
                    };
                }
                else
                {
                    for (int i = 0; i < refs.Count; i++)
                    {
                        if (refs[i].TargetEntityId == targetId && refs[i].FromRaftGroupId == fromEntity.Id.RaftGroupId)
                        {
                            item.Diff = refs[i].Diff + diff;
                            refs[i]   = item;
                            return;
                        }
                    }

                    //未找到
                    item.Diff = diff;
                    refs.Add(item);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 根据模型类型及标识号获取相应的节点
        /// </summary>
        internal ModelNode FindModelNode(ModelType modelType, ulong modelId)
        {
            var appId         = IdUtil.GetAppIdFromModelId(modelId);
            var modelRootNode = FindModelRootNode(appId, modelType);

            if (modelRootNode == null)
            {
                return(null);
            }

            return(modelRootNode.FindModelNode(modelId));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 加载指定App的所有模型包,用于导出
        /// </summary>
        /// <param name="appName">eg: erp</param>
        internal static async Task LoadToAppPackage(uint appId, string appName, Server.IAppPackage pkg)
        {
            var db        = SqlStore.Default;
            var esc       = db.NameEscaper;
            var appPrefix = $"{appName}.";

            using var conn = await db.OpenConnectionAsync();

            using var cmd    = db.MakeCommand();
            cmd.Connection   = conn;
            cmd.CommandText  = $"Select meta,id,data From {esc}sys.Meta{esc} Where meta<{Meta_View_Router} And model<>10";
            using var reader = await cmd.ExecuteReaderAsync();

            while (await reader.ReadAsync())
            {
                // 根据不同类型判断是否属于当前App
                var metaType = reader.GetInt16(0);
                var id       = reader.GetString(1);
                switch (metaType)
                {
                case Meta_Application:
                {
                    if (uint.Parse(id) == appId)
                    {
                        var appModel = (ApplicationModel)DeserializeModel((byte[])reader.GetValue(2));         //TODO: use GetStream
                        pkg.Application = appModel;
                    }
                }
                break;

                case Meta_Model:
                {
                    ulong modelId = ulong.Parse(id);
                    if (IdUtil.GetAppIdFromModelId(modelId) == appId)
                    {
                        var model = (ModelBase)DeserializeModel((byte[])reader.GetValue(2));         //TODO:同上
                        model.AcceptChanges();
                        pkg.Models.Add(model);
                    }
                }
                break;

                case Meta_Code:
                {
                    ulong modelId = ulong.Parse(id);
                    if (IdUtil.GetAppIdFromModelId(modelId) == appId)
                    {
                        pkg.SourceCodes.Add(modelId, (byte[])reader.GetValue(2));
                    }
                }
                break;

                case Meta_Folder:
                {
                    var  dotIndex    = id.AsSpan().IndexOf('.');
                    uint folderAppId = uint.Parse(id.AsSpan(0, dotIndex));
                    if (folderAppId == appId)
                    {
                        var folder = (ModelFolder)DeserializeModel((byte[])reader.GetValue(2));         //TODO:同上
                        pkg.Folders.Add(folder);
                    }
                }
                break;

                case Meta_Service_Assembly:
                {
                    if (id.AsSpan().StartsWith(appPrefix))
                    {
                        pkg.ServiceAssemblies.Add(id, (byte[])reader.GetValue(2));
                    }
                }
                break;

                case Meta_View_Assembly:
                {
                    if (id.AsSpan().StartsWith(appPrefix))
                    {
                        pkg.ViewAssemblies.Add(id, (byte[])reader.GetValue(2));
                    }
                }
                break;

                default:
                    Log.Warn($"Load unknown meta type: {metaType}");
                    break;
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 执行查询并返回Entity[]
        /// </summary>
        /// <returns>返回值可能为null</returns>
        public async ValueTask <IList <Entity> > ToListAsync()
        {
            var app = await RuntimeContext.Current.GetApplicationModelAsync(IdUtil.GetAppIdFromModelId(modelId));

            var model = await RuntimeContext.Current.GetModelAsync <EntityModel>(modelId);

            var indexModel = model.SysStoreOptions.Indexes.SingleOrDefault(t => t.IndexId == indexId);

            if (indexModel == null)
            {
                throw new Exception("Index not exists.");
            }
            if (indexModel.Global)
            {
                throw new NotImplementedException();
            }

            //先判断是否需要快照读事务 //TODO:跨分区也需要
            ReadonlyTransaction txn = rootIncluder == null ? null : new ReadonlyTransaction();

            if (model.SysStoreOptions.HasPartitionKeys)
            {
                //分区表先根据PartionPredicate查询出相关分区,再依次扫描
                ulong[] parts = await GetPartitions(app.StoreId, model);

                if (parts == null || parts.Length == 0)
                {
                    return(null);
                }

                var  list    = new List <Entity>((int)(take <= 1000 ? take : 20));
                uint skipped = 0;
                uint taken   = 0;
                for (int i = 0; i < parts.Length; i++)
                {
                    var partRes = await ExecLocalIndexScanAsync(indexModel, parts[i], skip - skipped, take - taken, true);

                    if (partRes != null)
                    {
                        partRes.ForEachRow((kp, ks, vp, vs) =>
                        {
                            list.Add(EntityStoreReader.ReadEntity(model, kp, ks, vp, vs));
                        });
                        skipped += partRes.Skipped;
                        taken   += (uint)partRes.Length;
                        partRes.Dispose();
                        if (taken >= take)
                        {
                            break;
                        }
                    }
                }

                await LoadIncludesAsync(list, txn);

                return(list);
            }
            else
            {
                ulong groupId = await EntityStore.GetOrCreateGlobalTablePartition(app, indexModel.Owner, IntPtr.Zero);

                if (groupId == 0)
                {
                    return(null);
                }

                var res = await ExecLocalIndexScanAsync(indexModel, groupId, skip, take, true);

                if (res == null || res.Length == 0)
                {
                    return(null);
                }

                var list     = new Entity[res.Length];
                int rowIndex = 0;
                res.ForEachRow((kp, ks, vp, vs) =>
                {
                    list[rowIndex] = EntityStoreReader.ReadEntity(model, kp, ks, vp, vs);
                    rowIndex++;
                });
                res.Dispose();
                await LoadIncludesAsync(list, txn);

                return(list);
            }
        }