Exemple #1
0
        public IndexGet(ulong entityModelId, byte indexId)
        {
            var model = RuntimeContext.Current.GetModelAsync <EntityModel>(entityModelId).Result;

            if (model == null)
            {
                throw new Exception($"Can't get entity model of :{entityModelId}");
            }
            if (model.SysStoreOptions == null || !model.SysStoreOptions.HasIndexes)
            {
                throw new Exception($"Can't get index model of:{indexId}");
            }
            EntityIndexModel indexModel = null;

            for (int i = 0; i < model.SysStoreOptions.Indexes.Count; i++)
            {
                if (model.SysStoreOptions.Indexes[i].IndexId == indexId)
                {
                    indexModel = model.SysStoreOptions.Indexes[i];
                    break;
                }
            }
            if (indexModel == null)
            {
                throw new Exception($"Can't get index model of:{indexId}");
            }
            if (!indexModel.Unique)
            {
                throw new Exception("Only unique index can use IndexGet");
            }

            _indexModel = indexModel;
            _predicates = new KeyPredicate[_indexModel.Fields.Length];
        }
Exemple #2
0
        public IndexGet(EntityIndexModel indexModel)
        {
            if (indexModel == null)
            {
                throw new ArgumentNullException(nameof(indexModel));
            }
            if (!indexModel.Unique)
            {
                throw new Exception("Only unique index can use IndexGet");
            }

            _indexModel = indexModel;
            _predicates = new KeyPredicate[_indexModel.Fields.Length];
        }
Exemple #3
0
        /// <summary>
        /// SysStore及SqlStore通用
        /// </summary>
        private static IndexModelBase AddIndex(EntityModel entityModel, string value)
        {
            if (entityModel.StoreOptions == null)
            {
                throw new InvalidOperationException("Can't add index for DTO");
            }

            var indexInfo = JsonConvert.DeserializeObject <IndexInfo>(value);

            //Validate
            if (string.IsNullOrEmpty(indexInfo.Name))
            {
                throw new Exception("Index has no name");
            }
            if (!CodeHelper.IsValidIdentifier(indexInfo.Name))
            {
                throw new Exception("Index name not valid");
            }
            if (indexInfo.Fields == null || indexInfo.Fields.Length == 0)
            {
                throw new Exception("Index has no fields");
            }
            if (entityModel.StoreOptions.HasIndexes &&
                entityModel.StoreOptions.Indexes.Any(t => t.Name == indexInfo.Name))
            {
                throw new Exception("Index name has existed");
            }

            var fields = new FieldWithOrder[indexInfo.Fields.Length];

            for (int i = 0; i < indexInfo.Fields.Length; i++)
            {
                fields[i] = new FieldWithOrder(indexInfo.Fields[i].MID, indexInfo.Fields[i].OrderByDesc);
            }

            //根据存储类型新建索引并添加至模型内
            if (entityModel.SysStoreOptions != null)
            {
                var newIndex = new EntityIndexModel(entityModel, indexInfo.Name, indexInfo.Unique, fields, null);
                entityModel.SysStoreOptions.AddIndex(entityModel, newIndex);
                return(newIndex);
            }
            else
            {
                var newIndex = new SqlIndexModel(entityModel, indexInfo.Name, indexInfo.Unique, fields, null);
                entityModel.SqlStoreOptions.AddIndex(entityModel, newIndex);
                return(newIndex);
            }
        }
Exemple #4
0
        /// <summary>
        /// 写索引Value
        /// </summary>
        /// <returns>非惟一索引且没有覆盖字段返回IntPtr.Zero</returns>
        internal unsafe static IntPtr WriteIndexData(Entity entity, EntityIndexModel indexModel, out int dataSize)
        {
            if (!(indexModel.Unique || indexModel.HasStoringFields))
            {
                dataSize = 0;
                return(IntPtr.Zero);
            }

            int *varSizes  = null;
            int  totalSize = indexModel.Unique ? 2 + 16 : 0;

            if (indexModel.HasStoringFields)
            {
                int *vars = stackalloc int[indexModel.StoringFields.Length];
                for (int i = 0; i < indexModel.StoringFields.Length; i++)
                {
                    totalSize += CalcMemberSize(ref entity.GetMember(indexModel.StoringFields[i]), vars + i, true);
                }
                varSizes = vars;
            }
            dataSize = totalSize;

            var w = new EntityStoreWriter(totalSize);

            //先写入惟一索引指向的EntityId
            if (indexModel.Unique)
            {
                w.WriteUInt16(IdUtil.STORE_FIELD_ID_OF_ENTITY_ID);
                w.WriteGuid(entity.Id.Data);
            }
            //再写入StoringFields
            if (indexModel.HasStoringFields)
            {
                for (int i = 0; i < indexModel.StoringFields.Length; i++)
                {
                    w.WriteMember(ref entity.GetMember(indexModel.StoringFields[i]), varSizes + i, true, false); //TODO:考虑不写入Null
                }
            }

            return(w.nativeStringPtr);
        }
Exemple #5
0
        internal unsafe void WriteIndexKey(Entity entity, EntityIndexModel indexModel, int *varSizes)
        {
            var   id    = entity.Id.Data;
            byte *idptr = (byte *)&id;

            //写入EntityId's RaftGroupId
            WriteSpan(new ReadOnlySpan <byte>(idptr, 6));
            //写入IndexId
            dataPtr[index++] = indexModel.IndexId;
            //写入各成员
            for (int i = 0; i < indexModel.Fields.Length; i++)
            {
                //注意MemberId写入排序标记
                WriteMember(ref entity.GetMember(indexModel.Fields[i].MemberId), varSizes + i, true,
                            indexModel.Fields[i].OrderByDesc);
            }
            //非惟一索引写入EntityId的第二部分
            if (!indexModel.Unique)
            {
                WriteSpan(new ReadOnlySpan <byte>(idptr + 6, 10));
            }
        }
        internal unsafe void WriteKeyRange(ulong groupId, EntityIndexModel model,
                                           byte *bk, byte *ek, int *varSizes)
        {
            EntityId.WriteRaftGroupId(bk, groupId);
            EntityId.WriteRaftGroupId(ek, groupId);
            bk[KeyUtil.INDEXCF_INDEXID_POS] = ek[KeyUtil.INDEXCF_INDEXID_POS] = model.IndexId;

            if (predicates == null || !predicates[0].HasValue) //short path for no predicate
            {
                ek[KeyUtil.INDEXCF_INDEXID_POS] = (byte)(model.IndexId + 1);
                return;
            }

            var bw = new EntityStoreWriter(bk, KeyUtil.INDEXCF_PREFIX_SIZE);
            var ew = new EntityStoreWriter(ek, KeyUtil.INDEXCF_PREFIX_SIZE);

            for (int i = 0; i < predicates.Length; i++)
            {
                if (!predicates[i].HasValue)
                {
                    break;                          //没有指定谓词跳出
                }
                var m = predicates[i].Value.Value;

                switch (predicates[i].Value.Type)
                {
                case KeyPredicateType.Equal:
                {
                    //注意写入索引键的排序标记
                    bw.WriteMember(ref m, varSizes, true, model.Fields[i].OrderByDesc);
                    ew.WriteMember(ref m, varSizes, true, model.Fields[i].OrderByDesc);
                }
                break;

                default:
                    throw new NotImplementedException();
                }
            }
        }
 private IActionResult CreateIndexResult(EntityIndexModel model) => View(model);
Exemple #8
0
        static TestHelper()
        {
            SysAppModel = new ApplicationModel("appbox", Consts.SYS, Consts.SYS_APP_ID);

            AdminPermissionModel     = new PermissionModel(Consts.SYS_PERMISSION_ADMIN_ID, "Admin");
            DeveloperPermissionModel = new PermissionModel(Consts.SYS_PERMISSION_DEVELOPER_ID, "Developer");

            OrderStatusModel = new EnumModel(SYS_ENUM_MODEL_ID | (1 << IdUtil.MODELID_SEQ_OFFSET), "OrderStatus");
            OrderStatusModel.Items.Add(new EnumModelItem("New", 0));
            OrderStatusModel.Items.Add(new EnumModelItem("Paid", 1));

            EmploeeModel = new EntityModel(Consts.SYS_EMPLOEE_MODEL_ID, Consts.EMPLOEE, EntityStoreType.StoreWithMvcc);
            var name = new DataFieldModel(EmploeeModel, Consts.NAME, EntityFieldType.String);

            EmploeeModel.AddSysMember(name, Consts.EMPLOEE_NAME_ID);
            var account = new DataFieldModel(EmploeeModel, Consts.ACCOUNT, EntityFieldType.String);

            account.AllowNull = true;
            EmploeeModel.AddSysMember(account, Consts.EMPLOEE_ACCOUNT_ID);
            var password = new DataFieldModel(EmploeeModel, Consts.PASSWORD, EntityFieldType.Binary);

            password.AllowNull = true;
            EmploeeModel.AddSysMember(password, Consts.EMPLOEE_PASSWORD_ID);

            //Add indexes
            var ui_account_pass = new EntityIndexModel(EmploeeModel, "UI_Account_Password", true,
                                                       new FieldWithOrder[] { new FieldWithOrder(Consts.EMPLOEE_ACCOUNT_ID) },
                                                       new ushort[] { Consts.EMPLOEE_PASSWORD_ID });

            EmploeeModel.SysStoreOptions.AddSysIndex(EmploeeModel, ui_account_pass, Consts.EMPLOEE_UI_ACCOUNT_ID);

            //测试用分区表
            VehicleStateModel = new EntityModel(((ulong)Consts.SYS_APP_ID << 32) | 18, "VehicleState", EntityStoreType.StoreWithMvcc);
            var vid = new DataFieldModel(VehicleStateModel, "VehicleId", EntityFieldType.Int32);

            VehicleStateModel.AddMember(vid);
            var lng = new DataFieldModel(VehicleStateModel, "Lng", EntityFieldType.Float);

            VehicleStateModel.AddMember(lng);
            var lat = new DataFieldModel(VehicleStateModel, "Lat", EntityFieldType.Float);

            VehicleStateModel.AddMember(lat);
            var pks = new PartitionKey[1];

            pks[0] = new PartitionKey()
            {
                MemberId = vid.MemberId, OrderByDesc = false
            };
            VehicleStateModel.SysStoreOptions.SetPartitionKeys(VehicleStateModel, pks);

            //测试树状结构
            ulong orgUnitModelId = ((ulong)Consts.SYS_APP_ID << 32) | 19;

            OrgUnitModel = new EntityModel(orgUnitModelId, "OrgUnit", EntityStoreType.StoreWithMvcc);
            var ouName = new DataFieldModel(OrgUnitModel, "Name", EntityFieldType.String);

            OrgUnitModel.AddSysMember(ouName, 1 << IdUtil.MEMBERID_SEQ_OFFSET);
            var parentId = new DataFieldModel(OrgUnitModel, "ParentId", EntityFieldType.EntityId, true);

            parentId.AllowNull = true;
            OrgUnitModel.AddSysMember(parentId, 2 << IdUtil.MEMBERID_SEQ_OFFSET);
            var parent = new EntityRefModel(OrgUnitModel, "Parent", orgUnitModelId, new ushort[] { parentId.MemberId });

            parent.AllowNull = true;
            OrgUnitModel.AddSysMember(parent, 3 << IdUtil.MEMBERID_SEQ_OFFSET);
            var childs = new EntitySetModel(OrgUnitModel, "Childs", orgUnitModelId, parent.MemberId);

            OrgUnitModel.AddSysMember(childs, 4 << IdUtil.MEMBERID_SEQ_OFFSET);

            //----以下测试映射至SqlStore的实体---
            SqlStoreModel = new DataStoreModel(DataStoreKind.Sql, "appbox.Store.PostgreSQL;appbox.Store.PgSqlStore", "DemoDB");

            ulong cityModelId = ((ulong)Consts.SYS_APP_ID << 32) | 25;

            CityModel = new EntityModel(cityModelId, "City", new SqlStoreOptions(SqlStoreModel.Id));
            var cityCode = new DataFieldModel(CityModel, "Code", EntityFieldType.Int32);

            CityModel.AddMember(cityCode);
            var cityName = new DataFieldModel(CityModel, "Name", EntityFieldType.String);

            CityModel.AddMember(cityName);
            var cityPerson = new DataFieldModel(CityModel, "Persons", EntityFieldType.Int32);

            CityModel.AddMember(cityPerson);
            var cityPk = new List <FieldWithOrder>();

            cityPk.Add(new FieldWithOrder {
                MemberId = cityCode.MemberId, OrderByDesc = false
            });
            CityModel.SqlStoreOptions.SetPrimaryKeys(CityModel, cityPk);

            ulong customerModelId = ((ulong)Consts.SYS_APP_ID << 32) | 26;

            CustomerModel = new EntityModel(customerModelId, "Customer", new SqlStoreOptions(SqlStoreModel.Id));
            var customerId = new DataFieldModel(CustomerModel, "Id", EntityFieldType.Int32);

            CustomerModel.AddMember(customerId);
            var customerName = new DataFieldModel(CustomerModel, "Name", EntityFieldType.String);

            CustomerModel.AddMember(customerName);
            var customerCityId = new DataFieldModel(CustomerModel, "CityId", EntityFieldType.Int32, true);

            CustomerModel.AddMember(customerCityId);
            var customerCity = new EntityRefModel(CustomerModel, "City", cityModelId, new ushort[] { customerCityId.MemberId });

            CustomerModel.AddMember(customerCity);
            var customerPk = new List <FieldWithOrder>();

            customerPk.Add(new FieldWithOrder {
                MemberId = customerId.MemberId, OrderByDesc = false
            });
            CustomerModel.SqlStoreOptions.SetPrimaryKeys(CustomerModel, customerPk);

            ulong orderModelId = ((ulong)Consts.SYS_APP_ID << 32) | 27;

            OrderModel = new EntityModel(orderModelId, "Order", new SqlStoreOptions(SqlStoreModel.Id));
            var orderId = new DataFieldModel(OrderModel, "Id", EntityFieldType.Int32);

            OrderModel.AddMember(orderId);
            var orderCustomerId = new DataFieldModel(OrderModel, "CustomerId", EntityFieldType.Int32, true);

            OrderModel.AddMember(orderCustomerId);
            var orderCustomer = new EntityRefModel(OrderModel, "Customer", customerModelId, new ushort[] { orderCustomerId.MemberId });

            OrderModel.AddMember(orderCustomer);
            var orderPk = new List <FieldWithOrder>();

            orderPk.Add(new FieldWithOrder {
                MemberId = orderId.MemberId, OrderByDesc = false
            });
            OrderModel.SqlStoreOptions.SetPrimaryKeys(OrderModel, orderPk);
        }
Exemple #9
0
        /// <summary>
        /// 执行本地索引扫描,分区表与非分区表通用
        /// </summary>
        private async ValueTask <IScanResponse> ExecLocalIndexScanAsync(
            EntityIndexModel indexModel, ulong groupId, uint pskip, uint ptake, bool toIndexTarget)
        {
            //TODO:***将不能编入Key的谓词作为Filter条件
            //开始处理NativeApi所需参数
            IntPtr bkPtr;
            IntPtr ekPtr;
            int    bkSize    = KeyUtil.INDEXCF_PREFIX_SIZE;
            int    ekSize    = KeyUtil.INDEXCF_PREFIX_SIZE;
            IntPtr filterPtr = IntPtr.Zero;

            unsafe
            {
                int *varSizes = stackalloc int[indexModel.Fields.Length];
                if (_keys != null)
                {
                    bkSize = ekSize = _keys.CalcKeySize(varSizes);
                }

                byte *bk = stackalloc byte[bkSize];
                bkPtr = new IntPtr(bk);
                byte *ek = stackalloc byte[ekSize];
                ekPtr = new IntPtr(ek);

                if (_keys == null)
                {
                    KeyUtil.WriteIndexKeyPrefix(bk, groupId, indexModel.IndexId);
                    ekPtr  = IntPtr.Zero;
                    ekSize = 0;
                }
                else
                {
                    _keys.WriteKeyRange(groupId, indexModel, bk, ek, varSizes);
                    if (_keys.IsOnlyEqual()) //只有相等性判断使用前缀匹配
                    {
                        ekPtr  = IntPtr.Zero;
                        ekSize = 0;
                    }
                }
            }

            if (!Expression.IsNull(filter))
            {
                filterPtr = ModelStore.SerializeModel(filter, out _);
            }

            var req = new ClrScanRequire
            {
                RaftGroupId   = groupId,
                BeginKeyPtr   = bkPtr,
                BeginKeySize  = new IntPtr(bkSize),
                EndKeyPtr     = ekPtr,
                EndKeySize    = new IntPtr(ekSize),
                FilterPtr     = filterPtr,
                Skip          = pskip,
                Take          = ptake,
                DataCF        = KeyUtil.INDEXCF_INDEX,
                ToIndexTarget = toIndexTarget
            };
            IntPtr reqPtr;

            unsafe { reqPtr = new IntPtr(&req); }
            return(await StoreApi.Api.ReadIndexByScanAsync(reqPtr));
        }