Beispiel #1
0
        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;
                }
            }
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
 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);
        }
Beispiel #5
0
 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);
 }
Beispiel #6
0
        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));
        }
Beispiel #7
0
        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));
        }
Beispiel #8
0
        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));
        }
Beispiel #9
0
 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);
 }
Beispiel #10
0
 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;
 }
Beispiel #11
0
 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);
 }
Beispiel #12
0
        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;
                }
            }
        }
Beispiel #13
0
        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);
            }
        }
Beispiel #14
0
 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));
 }
Beispiel #15
0
 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));
 }
Beispiel #16
0
        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);
        }
Beispiel #17
0
        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));
        }
Beispiel #18
0
 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);
 }
Beispiel #19
0
 internal TableVersionInfo(TableFieldInfo[] tableFields)
 {
     _tableFields = tableFields;
 }