internal void EnsureClientTypeVersion() { if (ClientTypeVersion != 0) { return; } EnsureKnownLastPersistedVersion(); var props = _clientType.GetProperties(); var fields = new List <TableFieldInfo>(props.Length); foreach (var pi in props) { fields.Add(TableFieldInfo.Build(Name, pi, _tableInfoResolver.FieldHandlerFactory, ClientType)); } var tvi = new TableVersionInfo(fields.ToArray()); if (LastPersistedVersion == 0) { _tableVersions.TryAdd(1, tvi); ClientTypeVersion = 1; } else { var last = _tableVersions.GetOrAdd(LastPersistedVersion, v => _tableInfoResolver.LoadTableVersionInfo(_id, v, Name)); if (TableVersionInfo.Equal(last, tvi)) { ClientTypeVersion = LastPersistedVersion; } else { _tableVersions.TryAdd(LastPersistedVersion + 1, tvi); ClientTypeVersion = LastPersistedVersion + 1; } } }
internal static bool Equal(TableFieldInfo a, UnresolvedTableFieldInfo b) { if (a.Name != b.Name) { return(false); } var ha = a.Handler; if (ha.Name != b._handlerName) { return(false); } var ca = ha.Configuration; var cb = b._configuration; if (ca == cb) { return(true); } if (ca == null || cb == null) { return(false); } if (ca.Length != cb.Length) { return(false); } if (BitArrayManipulation.CompareByteArray(ca, ca.Length, cb, cb.Length) != 0) { return(false); } return(true); }
void ValidateAdvancedEnumParameter(TableFieldInfo field, Type advEnumParamType, string methodName) { if (!field.Handler.IsCompatibleWith(advEnumParamType, FieldHandlerOptions.Orderable)) { throw new BTDBException($"Parameter type mismatch in {methodName} (expected '{field.Handler.HandledType().ToSimpleName()}' but '{advEnumParamType.ToSimpleName()}' found)."); } }
internal ReadOnlyMemory <TableFieldInfo> GetAllFields() { var res = new TableFieldInfo[PrimaryKeyFields.Length + Fields.Length]; PrimaryKeyFields.CopyTo(res); Fields.CopyTo(res.AsMemory(PrimaryKeyFields.Length)); return(res); }
internal static TableVersionInfo Load(AbstractBufferedReader reader, IFieldHandlerFactory fieldHandlerFactory, string tableName) { var fieldCount = reader.ReadVUInt32(); var fieldInfos = new TableFieldInfo[fieldCount]; for (int i = 0; i < fieldCount; i++) { fieldInfos[i] = TableFieldInfo.Load(reader, fieldHandlerFactory, tableName, FieldHandlerOptions.None); } return new TableVersionInfo(fieldInfos); }
internal static TableVersionInfo Load(ref SpanReader reader, IFieldHandlerFactory fieldHandlerFactory, string tableName) { var fieldCount = reader.ReadVUInt32(); var fieldInfos = new TableFieldInfo[fieldCount]; for (var i = 0; i < fieldCount; i++) { fieldInfos[i] = TableFieldInfo.Load(ref reader, fieldHandlerFactory, tableName, FieldHandlerOptions.None); } return(new TableVersionInfo(fieldInfos)); }
internal static TableVersionInfo Load(AbstractBufferedReader reader, IFieldHandlerFactory fieldHandlerFactory, string tableName) { var fieldCount = reader.ReadVUInt32(); var fieldInfos = new TableFieldInfo[fieldCount]; for (int i = 0; i < fieldCount; i++) { fieldInfos[i] = TableFieldInfo.Load(reader, fieldHandlerFactory, tableName); } return(new TableVersionInfo(fieldInfos)); }
public static RelationVersionInfo Load(AbstractBufferedReader reader, IFieldHandlerFactory fieldHandlerFactory, string relationName) { var pkCount = reader.ReadVUInt32(); var primaryKeys = new List <TableFieldInfo>((int)pkCount); for (var i = 0u; i < pkCount; i++) { primaryKeys.Add(TableFieldInfo.Load(reader, fieldHandlerFactory, relationName, FieldHandlerOptions.Orderable)); } var skFieldCount = reader.ReadVUInt32(); var secondaryKeyFields = new TableFieldInfo[skFieldCount]; for (var i = 0; i < skFieldCount; i++) { secondaryKeyFields[i] = TableFieldInfo.Load(reader, fieldHandlerFactory, relationName, FieldHandlerOptions.Orderable); } var skCount = reader.ReadVUInt32(); var secondaryKeys = new Dictionary <uint, SecondaryKeyInfo>((int)skCount); var secondaryKeysNames = new Dictionary <string, uint>((int)skCount); for (var i = 0; i < skCount; i++) { var skIndex = reader.ReadVUInt32(); var info = new SecondaryKeyInfo(); info.Index = reader.ReadVUInt32(); info.Name = reader.ReadString(); var cnt = reader.ReadVUInt32(); info.Fields = new List <FieldId>((int)cnt); for (var j = 0; j < cnt; j++) { var fromPrimary = reader.ReadBool(); var index = reader.ReadVUInt32(); info.Fields.Add(new FieldId(fromPrimary, index)); } secondaryKeys.Add(skIndex, info); secondaryKeysNames.Add(info.Name, skIndex); } var fieldCount = reader.ReadVUInt32(); var fieldInfos = new TableFieldInfo[fieldCount]; for (int i = 0; i < fieldCount; i++) { fieldInfos[i] = TableFieldInfo.Load(reader, fieldHandlerFactory, relationName, FieldHandlerOptions.None); } return(new RelationVersionInfo(primaryKeys, secondaryKeys, secondaryKeysNames, fieldInfos)); }
internal static bool Equal(TableVersionInfo a, TableVersionInfo b) { if (a.FieldCount != b.FieldCount) { return(false); } for (int i = 0; i < a.FieldCount; i++) { if (!TableFieldInfo.Equal(a[i], b[i])) { return(false); } } return(true); }
internal static bool Equal(TableFieldInfo a, TableFieldInfo b) { if (a.Name != b.Name) return false; var ha = a.Handler; var hb = b.Handler; if (ha == hb) return true; if (ha.Name != hb.Name) return false; var ca = ha.Configuration; var cb = hb.Configuration; if (ca == cb) return true; if (ca == null || cb == null) return false; if (ca.Length != cb.Length) return false; if (BitArrayManipulation.CompareByteArray(ca, ca.Length, cb, cb.Length) != 0) return false; return true; }
internal static bool Equal(RelationVersionInfo a, RelationVersionInfo b) { //PKs if (a._primaryKeyFields.Count != b._primaryKeyFields.Count) { return(false); } for (int i = 0; i < a._primaryKeyFields.Count; i++) { if (!TableFieldInfo.Equal(a._primaryKeyFields[i], b._primaryKeyFields[i])) { return(false); } } //SKs if (a._secondaryKeys.Count != b._secondaryKeys.Count) { return(false); } foreach (var key in a._secondaryKeys) { SecondaryKeyInfo bInfo; if (!b._secondaryKeys.TryGetValue(key.Key, out bInfo)) { return(false); } if (!SecondaryKeyInfo.Equal(key.Value, bInfo)) { return(false); } } //Fields if (a._fields.Length != b._fields.Length) { return(false); } for (int i = 0; i < a._fields.Length; i++) { if (!TableFieldInfo.Equal(a._fields[i], b._fields[i])) { return(false); } } return(true); }
internal void EnsureClientTypeVersion() { if (ClientTypeVersion != 0) { return; } EnsureKnownLastPersistedVersion(); var props = _clientType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var fields = new StructList <TableFieldInfo>(); fields.Reserve((uint)props.Length); foreach (var pi in props) { if (pi.GetCustomAttributes(typeof(NotStoredAttribute), true).Length != 0) { continue; } if (pi.GetIndexParameters().Length != 0) { continue; } fields.Add(TableFieldInfo.Build(Name, pi, _tableInfoResolver.FieldHandlerFactory, FieldHandlerOptions.None)); } var tvi = new TableVersionInfo(fields.ToArray()); if (LastPersistedVersion == 0) { _tableVersions.TryAdd(1, tvi); ClientTypeVersion = 1; } else { var last = _tableVersions.GetOrAdd(LastPersistedVersion, (ver, tableInfo) => tableInfo._tableInfoResolver.LoadTableVersionInfo(tableInfo._id, ver, tableInfo.Name), this); if (TableVersionInfo.Equal(last, tvi)) { _tableVersions[LastPersistedVersion] = tvi; // tvi was build from real types and not loaded so it is more exact ClientTypeVersion = LastPersistedVersion; } else { _tableVersions.TryAdd(LastPersistedVersion + 1, tvi); ClientTypeVersion = LastPersistedVersion + 1; } } }
public void ResolveFieldHandlers(IFieldHandlerFactory fieldHandlerFactory) { var resolvedPrimaryKeyFields = new TableFieldInfo[_primaryKeyFields.Count]; for (var i = 0; i < _primaryKeyFields.Count; i++) { resolvedPrimaryKeyFields[i] = ((UnresolvedTableFieldInfo)_primaryKeyFields[i]).Resolve(fieldHandlerFactory); } _primaryKeyFields = resolvedPrimaryKeyFields; var resolvedSecondaryKeyFields = new TableFieldInfo[_secondaryKeyFields.Count]; for (var i = 0; i < _secondaryKeyFields.Count; i++) { resolvedSecondaryKeyFields[i] = ((UnresolvedTableFieldInfo)_secondaryKeyFields[i]).Resolve(fieldHandlerFactory); } _secondaryKeyFields = resolvedSecondaryKeyFields; for (var i = 0; i < _fields.Length; i++) { _fields[i] = ((UnresolvedTableFieldInfo)_fields[i]).Resolve(fieldHandlerFactory); } }
static void SaveKeyFieldFromApartField(IILGen ilGenerator, TableFieldInfo field, MethodInfo fieldGetter, IILLocal writerLoc) { field.Handler.SpecializeSaveForType(fieldGetter.ReturnType).Save(ilGenerator, il => il.Ldloc(writerLoc), il => il.Ldarg(0).Callvirt(fieldGetter)); }
static void SaveKeyFieldFromArgument(IILGen ilGenerator, TableFieldInfo field, ushort parameterId, Type parameterType, IILLocal writerLoc) { field.Handler.SpecializeSaveForType(parameterType).Save(ilGenerator, il => il.Ldloc(writerLoc), il => il.Ldarg(parameterId)); }
internal static void FillBufferWhenNotIgnoredKeyPropositionIl(ushort advEnumParamOrder, TableFieldInfo field, IILLocal emptyBufferLoc, FieldInfo instField, IILGen ilGenerator) { //stack contains KeyProposition var ignoreLabel = ilGenerator.DefineLabel(instField + "_ignore"); var doneLabel = ilGenerator.DefineLabel(instField + "_done"); var writerLoc = ilGenerator.DeclareLocal(typeof(AbstractBufferedWriter)); ilGenerator .Dup() .LdcI4((int)KeyProposition.Ignored) .BeqS(ignoreLabel) .Newobj(() => new ByteBufferWriter()) .Stloc(writerLoc); field.Handler.Save(ilGenerator, il => il.Ldloc(writerLoc), il => il.Ldarg(advEnumParamOrder).Ldfld(instField)); var dataGetter = typeof(ByteBufferWriter).GetProperty("Data").GetGetMethod(true); ilGenerator.Ldloc(writerLoc).Callvirt(dataGetter); ilGenerator .Br(doneLabel) .Mark(ignoreLabel) .Ldloc(emptyBufferLoc) .Mark(doneLabel); }
RelationVersionInfo CreateVersionInfoByReflection() { var props = _clientType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var primaryKeys = new Dictionary <uint, TableFieldInfo>(1); //PK order->fieldInfo var secondaryKeyFields = new List <TableFieldInfo>(); var secondaryKeys = new List <Tuple <int, IList <SecondaryKeyAttribute> > >(); //positive: sec key field idx, negative: pk order, attrs var fields = new List <TableFieldInfo>(props.Length); foreach (var pi in props) { if (pi.GetCustomAttributes(typeof(NotStoredAttribute), true).Length != 0) { continue; } if (pi.GetIndexParameters().Length != 0) { continue; } var pks = pi.GetCustomAttributes(typeof(PrimaryKeyAttribute), true); PrimaryKeyAttribute actualPKAttribute = null; if (pks.Length != 0) { actualPKAttribute = (PrimaryKeyAttribute)pks[0]; var fieldInfo = TableFieldInfo.Build(Name, pi, _relationInfoResolver.FieldHandlerFactory, FieldHandlerOptions.Orderable); if (fieldInfo.Handler.NeedsCtx()) { throw new BTDBException($"Unsupported key field {fieldInfo.Name} type."); } primaryKeys.Add(actualPKAttribute.Order, fieldInfo); } var sks = pi.GetCustomAttributes(typeof(SecondaryKeyAttribute), true); var id = (int)(-actualPKAttribute?.Order ?? secondaryKeyFields.Count); List <SecondaryKeyAttribute> currentList = null; for (var i = 0; i < sks.Length; i++) { if (i == 0) { currentList = new List <SecondaryKeyAttribute>(sks.Length); secondaryKeys.Add(new Tuple <int, IList <SecondaryKeyAttribute> >(id, currentList)); if (actualPKAttribute == null) { secondaryKeyFields.Add(TableFieldInfo.Build(Name, pi, _relationInfoResolver.FieldHandlerFactory, FieldHandlerOptions.Orderable)); } } var key = (SecondaryKeyAttribute)sks[i]; if (key.Name == "Id") { throw new BTDBException("'Id' is invalid name for secondary key, it is reserved for primary key identification."); } currentList.Add(key); } if (actualPKAttribute == null) { fields.Add(TableFieldInfo.Build(Name, pi, _relationInfoResolver.FieldHandlerFactory, FieldHandlerOptions.None)); } } var prevVersion = LastPersistedVersion > 0 ? _relationVersions[LastPersistedVersion] : null; return(new RelationVersionInfo(primaryKeys, secondaryKeys, secondaryKeyFields.ToArray(), fields.ToArray(), prevVersion)); }
void WritePrimaryKeyPrefixFinishedByAdvancedEnumerator(MethodInfo method, ParameterInfo[] parameters, IILMethod reqMethod, int prefixParamCount, ushort advEnumParamOrder, Type advEnumParam, TableFieldInfo field, IILLocal emptyBufferLoc) { reqMethod.Generator.Ldarg(0); SavePKListPrefixBytes(reqMethod.Generator, method.Name, parameters, _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); }
internal TableVersionInfo(TableFieldInfo[] tableFields) { _tableFields = tableFields; }