public RelationEnumerator(IInternalObjectDBTransaction tr, RelationInfo relationInfo, byte[] keyBytes, IRelationModificationCounter modificationCounter, int loaderIndex) { _transaction = tr; ItemLoader = relationInfo.ItemLoaderInfos[loaderIndex]; _keyValueTr = _transaction.KeyValueDBTransaction; _prevProtectionCounter = _keyValueTr.CursorMovedCounter; KeyBytes = keyBytes; _modificationCounter = modificationCounter; _pos = 0; _seekNeeded = true; _prevModificationCounter = _modificationCounter.ModificationCounter; }
public RelationEnumerator(IInternalObjectDBTransaction tr, RelationInfo relationInfo, ByteBuffer keyBytes) { RelationInfo = relationInfo; _tr = tr; _keyValueTr = _tr.KeyValueDBTransaction; _keyValueTrProtector = _tr.TransactionProtector; _prevProtectionCounter = _keyValueTrProtector.ProtectionCounter; KeyBytes = keyBytes; _keyValueTr.SetKeyPrefix(KeyBytes); _pos = 0; _seekNeeded = true; _prevModificationCounter = relationInfo.ModificationCounter; }
public RelationEnumerator(IInternalObjectDBTransaction tr, RelationInfo relationInfo, ByteBuffer keyBytes, IRelationModificationCounter modificationCounter, int loaderIndex) { RelationInfo = relationInfo; Transaction = tr; ItemLoader = relationInfo.ItemLoaderInfos[loaderIndex]; _keyValueTr = Transaction.KeyValueDBTransaction; _keyValueTrProtector = Transaction.TransactionProtector; _prevProtectionCounter = _keyValueTrProtector.ProtectionCounter; KeyBytes = keyBytes; _modificationCounter = modificationCounter; _keyValueTrProtector.Start(); _keyValueTr.SetKeyPrefix(KeyBytes); _pos = 0; _seekNeeded = true; _prevModificationCounter = _modificationCounter.ModificationCounter; }
IDictionary <string, FieldBuilder> DefineProperties(RelationInfo relationInfo, IILDynamicType classImpl, Type createdType) { var apartFields = new Dictionary <string, FieldBuilder>(); var methods = createdType.GetMethods(); foreach (var method in methods) { var name = method.Name; if (!name.StartsWith("get_") && !name.StartsWith("set_")) { continue; } FieldBuilder field; var propName = method.Name.Substring(4); if (!relationInfo.ApartFields.ContainsKey(propName)) { throw new BTDBException($"Invalid property name {propName}."); } if (!apartFields.TryGetValue(propName, out field)) { apartFields[propName] = field = classImpl.DefineField("_" + propName, method.ReturnType, FieldAttributes.Private); } var reqMethod = classImpl.DefineMethod(method.Name, method.ReturnType, method.GetParameters().Select(pi => pi.ParameterType).ToArray(), MethodAttributes.Virtual | MethodAttributes.Public); if (method.Name.StartsWith("get_")) { reqMethod.Generator.Ldarg(0).Ldfld(field).Ret(); } else if (method.Name.StartsWith("set_")) { reqMethod.Generator.Ldarg(0).Ldarg(1).Stfld(field).Ret(); } classImpl.DefineMethodOverride(reqMethod, method); } return(apartFields); }
internal RelationInfo CreateByName(IInternalObjectDBTransaction tr, string name, Type interfaceType, RelationBuilder builder) { name = string.Intern(name); if (!_name2Id.TryGetValue(name, out var id)) { id = _freeId++; _name2Id[name] = id; var nameWriter = new SpanWriter(); nameWriter.WriteBlock(ObjectDB.RelationNamesPrefix); nameWriter.WriteString(name); var idWriter = new SpanWriter(); idWriter.WriteVUInt32(id); tr.KeyValueDBTransaction.CreateOrUpdateKeyValue(nameWriter.GetSpan(), idWriter.GetSpan()); } if (_id2Relation.TryGetValue(id, out var relation)) { throw new BTDBException($"Relation with name '{name}' was already initialized"); } relation = new RelationInfo(id, name, builder, tr); _id2Relation[id] = relation; return(relation); }
public RelationPrimaryKeyEnumerator(IInternalObjectDBTransaction tr, RelationInfo relationInfo, ByteBuffer keyBytes, IRelationModificationCounter modificationCounter, int loaderIndex) : base(tr, relationInfo, keyBytes, modificationCounter, loaderIndex) { _skipBytes = relationInfo.Prefix.Length; }
static Func <IObjectDBTransaction, T1> BuildRelationCreatorInstance <T1>(Type classImplType, string relationName, RelationInfo relationInfo) { var methodBuilder = ILBuilder.Instance.NewMethod("RelationFactory" + relationName, typeof(Func <IObjectDBTransaction, T1>), typeof(RelationInfo)); var ilGenerator = methodBuilder.Generator; ilGenerator .Ldarg(1) .Ldarg(0) .Newobj(classImplType.GetConstructor(new[] { typeof(IObjectDBTransaction), typeof(RelationInfo) })) .Castclass(typeof(T1)) .Ret(); return((Func <IObjectDBTransaction, T1>)methodBuilder.Create(relationInfo)); }
public RelationBuilder(RelationInfo relationInfo) { _relationInfo = relationInfo; }
public RelationDBManipulator(IObjectDBTransaction transation, RelationInfo relationInfo) { _transaction = (IInternalObjectDBTransaction)transation; _relationInfo = relationInfo; }
public RelationPrimaryKeyEnumerator(IInternalObjectDBTransaction tr, RelationInfo relationInfo, ByteBuffer keyBytes, RelationDBManipulator <T> manipulator) : base(tr, relationInfo, keyBytes, manipulator) { _skipBytes = relationInfo.Prefix.Length; }
public Func <IObjectDBTransaction, T> Build(string relationName, Type relationDBManipulatorType) { var interfaceType = typeof(T); var classImpl = ILBuilder.Instance.NewType("Relation" + relationName, relationDBManipulatorType, new[] { interfaceType }); var constructorMethod = classImpl.DefineConstructor(new[] { typeof(IObjectDBTransaction), typeof(RelationInfo) }); var il = constructorMethod.Generator; // super.ctor(transaction, relationInfo); il.Ldarg(0).Ldarg(1).Ldarg(2).Call(relationDBManipulatorType.GetConstructor(new[] { typeof(IObjectDBTransaction), typeof(RelationInfo) })) .Ret(); GenerateApartFieldsProperties(classImpl, interfaceType); var methods = RelationInfo.GetMethods(interfaceType); foreach (var method in methods) { if (method.Name.StartsWith("get_") || method.Name.StartsWith("set_")) { continue; } var reqMethod = classImpl.DefineMethod("_R_" + method.Name, method.ReturnType, method.GetParameters().Select(pi => pi.ParameterType).ToArray(), MethodAttributes.Virtual | MethodAttributes.Public); if (method.Name.StartsWith("RemoveBy")) { if (method.Name == "RemoveByIdPartial") { BuildRemoveByIdPartialMethod(method, reqMethod, relationDBManipulatorType); } else { BuildRemoveByMethod(method, reqMethod, relationDBManipulatorType); } } else if (method.Name.StartsWith("FindBy")) { BuildFindByMethod(method, reqMethod, relationDBManipulatorType); } else if (method.Name == "Contains") { BuildContainsMethod(method, reqMethod, relationDBManipulatorType); } else if (method.Name == "ListById") //list by primary key { BuildListByIdMethod(method, reqMethod); } else if (method.Name.StartsWith("ListBy", StringComparison.Ordinal)) //ListBy{Name}(tenantId, .., AdvancedEnumeratorParam) { BuildListByMethod(method, reqMethod); } else if (method.Name == "Insert") { BuildInsertMethod(method, reqMethod, relationDBManipulatorType); } else { BuildManipulatorCallWithSameParameters(method, reqMethod, relationDBManipulatorType); } reqMethod.Generator.Ret(); classImpl.DefineMethodOverride(reqMethod, method); } var classImplType = classImpl.CreateType(); return(BuildRelationCreatorInstance <T>(classImplType, relationName, _relationInfo)); }
public RelationDBManipulator(IObjectDBTransaction transation, RelationInfo relationInfo) { _transaction = (IInternalObjectDBTransaction)transation; _relationInfo = relationInfo; _modificationCounter = _transaction.GetRelationModificationCounter(relationInfo.Id); }
public Func <IObjectDBTransaction, T> Build(string relationName, Type relationDBManipulatorType) { var interfaceType = typeof(T); var classImpl = ILBuilder.Instance.NewType("Relation" + relationName, relationDBManipulatorType, new[] { interfaceType }); var constructorMethod = classImpl.DefineConstructor(new[] { typeof(IObjectDBTransaction), typeof(RelationInfo) }); var il = constructorMethod.Generator; // super.ctor(transaction, relationInfo); il.Ldarg(0).Ldarg(1).Ldarg(2).Call(relationDBManipulatorType.GetConstructor(new[] { typeof(IObjectDBTransaction), typeof(RelationInfo) })) .Ret(); GenerateApartFieldsProperties(classImpl, interfaceType); var methods = RelationInfo.GetMethods(interfaceType); foreach (var method in methods) { if (method.Name.StartsWith("get_") || method.Name.StartsWith("set_")) { continue; } var reqMethod = classImpl.DefineMethod("_R_" + method.Name, method.ReturnType, method.GetParameters().Select(pi => pi.ParameterType).ToArray(), MethodAttributes.Virtual | MethodAttributes.Public); if (method.Name.StartsWith("RemoveBy") || method.Name.StartsWith("FindBy") || method.Name == "Contains") { SaveKeyBytesAndCallMethod(reqMethod.Generator, relationDBManipulatorType, method.Name, method.GetParameters(), method.ReturnType, _relationInfo.ApartFields); } else if (method.Name == "ListById") //list by primary key { var parameters = method.GetParameters(); var advEnumParamOrder = (ushort)parameters.Length; var advEnumParam = parameters[advEnumParamOrder - 1].ParameterType; var advEnumParamType = advEnumParam.GenericTypeArguments[0]; var emptyBufferLoc = reqMethod.Generator.DeclareLocal(typeof(ByteBuffer)); var prefixParamCount = method.GetParameters().Length - 1; var field = _relationInfo.ClientRelationVersionInfo.GetPrimaryKeyFields() .Skip(_relationInfo.ApartFields.Count + prefixParamCount).First(); reqMethod.Generator .Ldarg(0); SavePKListPrefixBytes(reqMethod.Generator, method.Name, method.GetParameters(), _relationInfo.ApartFields); reqMethod.Generator .LdcI4(prefixParamCount + _relationInfo.ApartFields.Count) .Ldarg(advEnumParamOrder).Ldfld(advEnumParam.GetField("Order")) .Ldarg(advEnumParamOrder).Ldfld(advEnumParam.GetField("StartProposition")); FillBufferWhenNotIgnoredKeyPropositionIl(advEnumParamOrder, field, emptyBufferLoc, advEnumParam.GetField("Start"), reqMethod.Generator); reqMethod.Generator .Ldarg(advEnumParamOrder).Ldfld(advEnumParam.GetField("EndProposition")); FillBufferWhenNotIgnoredKeyPropositionIl(advEnumParamOrder, field, emptyBufferLoc, advEnumParam.GetField("End"), reqMethod.Generator); if (typeof(IEnumerator <>).MakeGenericType(_relationInfo.ClientType).IsAssignableFrom(method.ReturnType)) { //return new RelationAdvancedEnumerator<T>(relationManipulator, // prefixBytes, prefixFieldCount, // order, // startKeyProposition, startKeyBytes, // endKeyProposition, endKeyBytes, secondaryKeyIndex); var enumType = typeof(RelationAdvancedEnumerator <>).MakeGenericType(_relationInfo.ClientType); var advancedEnumeratorCtor = enumType.GetConstructors()[0]; reqMethod.Generator.Newobj(advancedEnumeratorCtor); } else if (typeof(IOrderedDictionaryEnumerator <,>).MakeGenericType(advEnumParamType, _relationInfo.ClientType) .IsAssignableFrom(method.ReturnType)) { reqMethod.Generator .LdcI4(1); //init key reader //return new RelationAdvancedOrderedEnumerator<T>(relationManipulator, // prefixBytes, prefixFieldCount, // order, // startKeyProposition, startKeyBytes, // endKeyProposition, endKeyBytes, secondaryKeyIndex, initKeyReader); var enumType = typeof(RelationAdvancedOrderedEnumerator <,>).MakeGenericType(advEnumParamType, _relationInfo.ClientType); var advancedEnumeratorCtor = enumType.GetConstructors()[0]; reqMethod.Generator.Newobj(advancedEnumeratorCtor); } else { throw new BTDBException("Invalid method " + method.Name); } } else if (method.Name.StartsWith("ListBy", StringComparison.Ordinal)) //ListBy{Name}(tenantId, .., AdvancedEnumeratorParam) { var parameters = method.GetParameters(); var advEnumParamOrder = (ushort)parameters.Length; var advEnumParam = parameters[advEnumParamOrder - 1].ParameterType; var advEnumParamType = advEnumParam.GenericTypeArguments[0]; var emptyBufferLoc = reqMethod.Generator.DeclareLocal(typeof(ByteBuffer)); var secondaryKeyIndex = _relationInfo.ClientRelationVersionInfo.GetSecondaryKeyIndex(method.Name.Substring(6)); var prefixParamCount = method.GetParameters().Length - 1; var field = _relationInfo.ClientRelationVersionInfo.GetSecondaryKeyFields(secondaryKeyIndex) .Skip(_relationInfo.ApartFields.Count + prefixParamCount).First(); reqMethod.Generator .Ldarg(0); SaveListPrefixBytes(secondaryKeyIndex, reqMethod.Generator, method.Name, method.GetParameters(), _relationInfo.ApartFields); reqMethod.Generator .LdcI4(prefixParamCount + _relationInfo.ApartFields.Count) .Ldarg(advEnumParamOrder).Ldfld(advEnumParam.GetField("Order")) .Ldarg(advEnumParamOrder).Ldfld(advEnumParam.GetField("StartProposition")); FillBufferWhenNotIgnoredKeyPropositionIl(advEnumParamOrder, field, emptyBufferLoc, advEnumParam.GetField("Start"), reqMethod.Generator); reqMethod.Generator .Ldarg(advEnumParamOrder).Ldfld(advEnumParam.GetField("EndProposition")); FillBufferWhenNotIgnoredKeyPropositionIl(advEnumParamOrder, field, emptyBufferLoc, advEnumParam.GetField("End"), reqMethod.Generator); reqMethod.Generator .LdcI4((int)secondaryKeyIndex); if (typeof(IEnumerator <>).MakeGenericType(_relationInfo.ClientType).IsAssignableFrom(method.ReturnType)) { //return new RelationAdvancedSecondaryKeyEnumerator<T>(relationManipulator, // prefixBytes, prefixFieldCount, // order, // startKeyProposition, startKeyBytes, // endKeyProposition, endKeyBytes, secondaryKeyIndex); var enumType = typeof(RelationAdvancedSecondaryKeyEnumerator <>).MakeGenericType(_relationInfo.ClientType); var advancedEnumeratorCtor = enumType.GetConstructors()[0]; reqMethod.Generator.Newobj(advancedEnumeratorCtor); } else if (typeof(IOrderedDictionaryEnumerator <,>).MakeGenericType(advEnumParamType, _relationInfo.ClientType) .IsAssignableFrom(method.ReturnType)) { //return new RelationAdvancedOrderedSecondaryKeyEnumerator<T>(relationManipulator, // prefixBytes, prefixFieldCount, // order, // startKeyProposition, startKeyBytes, // endKeyProposition, endKeyBytes, secondaryKeyIndex); var enumType = typeof(RelationAdvancedOrderedSecondaryKeyEnumerator <,>).MakeGenericType(advEnumParamType, _relationInfo.ClientType); var advancedEnumeratorCtor = enumType.GetConstructors()[0]; reqMethod.Generator.Newobj(advancedEnumeratorCtor); } else { throw new BTDBException("Invalid method " + method.Name); } } else if (method.Name == "Insert") { var methodInfo = relationDBManipulatorType.GetMethod(method.Name); bool returningBoolVariant; var returnType = method.ReturnType; if (returnType == typeof(void)) { returningBoolVariant = false; } else if (returnType == typeof(bool)) { returningBoolVariant = true; } else { throw new BTDBException("Method Insert should be defined with void or bool return type."); } var methodParams = method.GetParameters(); CheckParameterCount(method.Name, 1, methodParams.Length); CheckParameterType(method.Name, 0, methodInfo.GetParameters()[0].ParameterType, methodParams[0].ParameterType); reqMethod.Generator .Ldarg(0) //this .Ldarg(1) .Callvirt(methodInfo); if (!returningBoolVariant) { var returnedTrueLabel = reqMethod.Generator.DefineLabel("returnedTrueLabel"); reqMethod.Generator .Brtrue(returnedTrueLabel) .Ldstr("Trying to insert duplicate key.") .Newobj(() => new BTDBException(null)) .Throw() .Mark(returnedTrueLabel); } } else //call the same method name with the same parameters { var methodParams = method.GetParameters(); int paramCount = methodParams.Length; var methodInfo = relationDBManipulatorType.GetMethod(method.Name); if (methodInfo == null) { throw new BTDBException($"Method {method} is not supported."); } CheckReturnType(method.Name, methodInfo.ReturnType, method.ReturnType); var calledMethodParams = methodInfo.GetParameters(); CheckParameterCount(method.Name, calledMethodParams.Length, methodParams.Length); for (int i = 0; i < methodParams.Length; i++) { CheckParameterType(method.Name, i, calledMethodParams[i].ParameterType, methodParams[i].ParameterType); } for (ushort i = 0; i <= paramCount; i++) { reqMethod.Generator.Ldarg(i); } reqMethod.Generator.Callvirt(methodInfo); } reqMethod.Generator.Ret(); classImpl.DefineMethodOverride(reqMethod, method); } var classImplType = classImpl.CreateType(); return(BuildRelationCreatorInstance <T>(classImplType, relationName, _relationInfo)); }
public RelationAdvancedEnumerator( RelationDBManipulator <T> manipulator, ByteBuffer prefixBytes, uint prefixFieldCount, EnumerationOrder order, KeyProposition startKeyProposition, ByteBuffer startKeyBytes, KeyProposition endKeyProposition, ByteBuffer endKeyBytes) { _prefixFieldCount = prefixFieldCount; _manipulator = manipulator; _ascending = order == EnumerationOrder.Ascending; _tr = manipulator.Transaction; _keyValueTr = _tr.KeyValueDBTransaction; _keyValueTrProtector = _tr.TransactionProtector; _prevProtectionCounter = _keyValueTrProtector.ProtectionCounter; _keyBytes = prefixBytes; _keyValueTr.SetKeyPrefix(_keyBytes); _relationInfo = manipulator.RelationInfo; _prevModificationCounter = _relationInfo.ModificationCounter; long startIndex; long endIndex; if (endKeyProposition == KeyProposition.Ignored) { endIndex = _keyValueTr.GetKeyValueCount() - 1; } else { switch (_keyValueTr.Find(endKeyBytes)) { case FindResult.Exact: endIndex = _keyValueTr.GetKeyIndex(); if (endKeyProposition == KeyProposition.Excluded) { endIndex--; } break; case FindResult.Previous: endIndex = _keyValueTr.GetKeyIndex(); break; case FindResult.Next: endIndex = _keyValueTr.GetKeyIndex() - 1; break; case FindResult.NotFound: endIndex = -1; break; default: throw new ArgumentOutOfRangeException(); } } if (startKeyProposition == KeyProposition.Ignored) { startIndex = 0; } else { switch (_keyValueTr.Find(startKeyBytes)) { case FindResult.Exact: startIndex = _keyValueTr.GetKeyIndex(); if (startKeyProposition == KeyProposition.Excluded) { startIndex++; } break; case FindResult.Previous: startIndex = _keyValueTr.GetKeyIndex() + 1; break; case FindResult.Next: startIndex = _keyValueTr.GetKeyIndex(); break; case FindResult.NotFound: startIndex = 0; break; default: throw new ArgumentOutOfRangeException(); } } _count = (uint)Math.Max(0, endIndex - startIndex + 1); _startPos = (uint)(_ascending ? startIndex : endIndex); _pos = 0; _seekNeeded = true; _lengthOfNonDataPrefix = ObjectDB.AllRelationsPKPrefix.Length + PackUnpack.LengthVUInt(manipulator.RelationInfo.Id); }