private async Task CheckForConcurencyOnlyAsync(object oi, ObjectInfo objInfo, SqoTypeInfo ti, ObjectSerializer serializer)
        {
            if (SiaqodbConfigurator.OptimisticConcurrencyEnabled)
            {
                FieldSqoInfo fi = MetaHelper.FindField(ti.Fields, "tickCount");
                if (fi != null)
                {
                    if (fi.AttributeType == typeof(ulong))
                    {
                        ulong tickCount = 0;

                        if (objInfo.Oid > 0 && objInfo.Oid <= ti.Header.numberOfRecords) //update or delete
                        {
                            tickCount = (ulong)(await serializer.ReadFieldValueAsync(ti, objInfo.Oid, fi).ConfigureAwait(false));
                            if (objInfo.TickCount != 0)
                            {
                                if (tickCount != objInfo.TickCount)
                                {
                                    throw new OptimisticConcurrencyException("Another version of object with OID=" + objInfo.Oid.ToString() + " of Type:" + ti.TypeName + " is saved in database, refresh your object before save!");
                                }
                            }
                        }
                    }
                }
            }
        }
        internal async Task <bool> UpdateObjectByAsync(string[] fieldNames, object obj, SqoTypeInfo ti, Transaction transact)
        {
            ObjectInfo objInfo = MetaExtractor.GetObjectInfo(obj, ti, metaCache);
            int        i       = 0;
            ICriteria  wPrev   = null;

            foreach (string fieldName in fieldNames)
            {
                FieldSqoInfo fi = MetaHelper.FindField(ti.Fields, fieldName);
                if (fi == null)
                {
                    throw new SiaqodbException("Field:" + fieldName + " was not found as member of Type:" + ti.TypeName);
                }

                Where w = new Where(fieldName, OperationType.Equal, objInfo.AtInfo[fi]);
                w.StorageEngine     = this;
                w.ParentSqoTypeInfo = ti;
                w.ParentType.Add(w.ParentSqoTypeInfo.Type);

                if (i > 0)
                {
                    And and = new And();
                    and.Add(w, wPrev);

                    wPrev = and;
                }
                else
                {
                    wPrev = w;
                }
                i++;
            }

            List <int> oids = await wPrev.GetOIDsAsync().ConfigureAwait(false);

            if (oids.Count > 1)
            {
                throw new SiaqodbException("In database exists more than one object with value of fields specified");
            }
            else if (oids.Count == 1)
            {
                objInfo.Oid = oids[0];

                if (transact == null)
                {
                    await this.SaveObjectAsync(obj, ti, objInfo).ConfigureAwait(false);
                }
                else
                {
                    await this.SaveObjectAsync(obj, ti, objInfo, transact).ConfigureAwait(false);
                }
                return(true);
            }
            else
            {
                return(false);
            }
        }
Beispiel #3
0
        private Dictionary <FieldSqoInfo, FieldSqoInfo> JoinFieldsSqoInfo(SqoTypeInfo actualTypeinfo, SqoTypeInfo oldTypeinfo)
        {
            Dictionary <FieldSqoInfo, FieldSqoInfo> fields = new Dictionary <FieldSqoInfo, FieldSqoInfo>();

            foreach (FieldSqoInfo fi in actualTypeinfo.Fields)
            {
                FieldSqoInfo oldFi = MetaHelper.FindField(oldTypeinfo.Fields, fi.Name);
                fields[fi] = oldFi;
            }
            return(fields);
        }
Beispiel #4
0
 public IBTree GetIndex(SqoTypeInfo type, string fieldName)
 {
     if (cache.ContainsKey(type))
     {
         FieldSqoInfo fi = MetaHelper.FindField(type.Fields, fieldName);
         if (fi != null)
         {
             return(this.GetIndex(type, fi));
         }
     }
     return(null);
 }
        internal List <int> DeleteObjectBy(SqoTypeInfo ti, Dictionary <string, object> criteria)
        {
            int       i     = 0;
            ICriteria wPrev = null;

            foreach (string fieldName in criteria.Keys)
            {
                FieldSqoInfo fi = MetaHelper.FindField(ti.Fields, fieldName);
                if (fi == null)
                {
                    throw new SiaqodbException("Field:" + fieldName + " was not found as member of Type:" + ti.TypeName);
                }

                Where w = new Where(fieldName, OperationType.Equal, criteria[fieldName]);
                w.StorageEngine     = this;
                w.ParentSqoTypeInfo = ti;
                w.ParentType.Add(w.ParentSqoTypeInfo.Type);
                if (i > 0)
                {
                    And and = new And();
                    and.Add(w, wPrev);

                    wPrev = and;
                }
                else
                {
                    wPrev = w;
                }
                i++;
            }

            List <int> oids = wPrev.GetOIDs();

            ObjectSerializer serializer = SerializerFactory.GetSerializer(this.path, GetFileByType(ti), useElevatedTrust);

            lock (_syncRoot)
            {
                foreach (int oid in oids)
                {
                    this.MarkObjectAsDelete(serializer, oid, ti);

                    this.indexManager.UpdateIndexesAfterDelete(oid, ti);
                }
            }
            return(oids);
        }
Beispiel #6
0
        private async Task <IBTree> RenewIndexAsync(SqoTypeInfo ti, string fieldName)
        {
            FieldSqoInfo finfo     = MetaHelper.FindField(ti.Fields, fieldName);
            IndexInfo2   indexInfo = null;

            if (finfo != null)
            {
                string             indexName = finfo.Name + ti.TypeName;
                IList <IndexInfo2> stIndexes = await this.GetStoredIndexesAsync().ConfigureAwait(false);

                foreach (IndexInfo2 ii in stIndexes)
                {
                    if (indexName.StartsWith(ii.IndexName) || ii.IndexName.StartsWith(indexName))
                    {
                        indexInfo = ii;
                        break;
                    }
                }

                if (indexInfo != null)
                {
                    if (storedIndexes != null && storedIndexes.Contains(indexInfo))
                    {
                        storedIndexes.Remove(indexInfo);
                    }
                    await siaqodb.DeleteAsync(indexInfo);
                }
                Type            t     = typeof(BTree <>).MakeGenericType(finfo.AttributeType);
                ConstructorInfo ctor  = t.GetConstructor(new Type[] { typeof(Siaqodb) });
                IBTree          index = (IBTree)ctor.Invoke(new object[] { this.siaqodb });
                indexInfo = await this.BuildIndexAsync(finfo, ti, index);

                index.SetIndexInfo(indexInfo);
                await index.PersistAsync();

                cacheIndexes.Set(ti, finfo, index);

                return(index);
            }
            return(null);
        }
        private async Task CheckForConcurencyAsync(object oi, ObjectInfo objInfo, SqoTypeInfo ti, ObjectSerializer serializer, bool updateTickCountInDB)
        {
            if (SiaqodbConfigurator.OptimisticConcurrencyEnabled)
            {
                FieldSqoInfo fi = MetaHelper.FindField(ti.Fields, "tickCount");
                if (fi != null)
                {
                    if (fi.AttributeType == typeof(ulong))
                    {
                        ulong tickCount = 0;

                        if (objInfo.Oid > 0 && objInfo.Oid <= ti.Header.numberOfRecords) //update or delete
                        {
                            tickCount = (ulong)(await serializer.ReadFieldValueAsync(ti, objInfo.Oid, fi).ConfigureAwait(false));
                            if (objInfo.TickCount != 0)
                            {
                                if (tickCount != objInfo.TickCount)
                                {
                                    throw new OptimisticConcurrencyException("Another version of object with OID=" + objInfo.Oid.ToString() + " of Type:" + ti.TypeName + " is saved in database, refresh your object before save!");
                                }
                            }
                        }
                        tickCount          = tickCount + 1L;
                        objInfo.AtInfo[fi] = tickCount;
#if SILVERLIGHT
                        MetaHelper.CallSetValue(fi.FInfo, tickCount, oi, ti.Type);
#else
                        fi.FInfo.SetValue(oi, tickCount);
#endif

                        if (updateTickCountInDB)
                        {
                            await serializer.SaveFieldValueAsync(objInfo.Oid, "tickCount", ti, tickCount, this.rawSerializer).ConfigureAwait(false);
                        }
                    }
                }
            }
        }
        internal async Task <int> DeleteObjectByAsync(string[] fieldNames, object obj, SqoTypeInfo ti, Transaction transaction)
        {
            ObjectInfo objInfo = MetaExtractor.GetObjectInfo(obj, ti, metaCache);
            int        i       = 0;
            ICriteria  wPrev   = null;

            foreach (string fieldName in fieldNames)
            {
                FieldSqoInfo fi = MetaHelper.FindField(ti.Fields, fieldName);
                if (fi == null)
                {
                    throw new SiaqodbException("Field:" + fieldName + " was not found as member of Type:" + ti.TypeName);
                }

                Where w = new Where(fieldName, OperationType.Equal, objInfo.AtInfo[fi]);
                w.StorageEngine     = this;
                w.ParentSqoTypeInfo = ti;
                w.ParentType.Add(w.ParentSqoTypeInfo.Type);
                if (i > 0)
                {
                    And and = new And();
                    and.Add(w, wPrev);

                    wPrev = and;
                }
                else
                {
                    wPrev = w;
                }
                i++;
            }

            List <int> oids = await wPrev.GetOIDsAsync().ConfigureAwait(false);


            if (oids.Count > 1)
            {
                throw new SiaqodbException("In database exists more than one object with value of fields specified");
            }
            else if (oids.Count == 1)
            {
                objInfo.Oid = oids[0];
                //obj.OID = oids[0];
                metaCache.SetOIDToObject(obj, oids[0], ti);

                ObjectSerializer serializer = SerializerFactory.GetSerializer(this.path, GetFileByType(ti), useElevatedTrust);

                if (transaction == null)
                {
                    await CheckForConcurencyAsync(obj, objInfo, ti, serializer, true).ConfigureAwait(false);

                    await this.MarkObjectAsDeleteAsync(serializer, objInfo.Oid, ti).ConfigureAwait(false);

                    await this.indexManager.UpdateIndexesAfterDeleteAsync(objInfo, ti).ConfigureAwait(false);
                }
                else
                {
                    await this.DeleteObjectAsync(obj, ti, transaction, objInfo).ConfigureAwait(false);
                }

                return(oids[0]);
            }
            else
            {
                return(-1);
            }
        }
        internal bool UpdateObjectBy(string[] fieldNames, object obj, SqoTypeInfo ti, Transaction transact)
        {
            ObjectInfo objInfo = MetaExtractor.GetObjectInfo(obj, ti, metaCache);
            int        i       = 0;
            ICriteria  wPrev   = null;

            foreach (string fieldName in fieldNames)
            {
                FieldSqoInfo fi = MetaHelper.FindField(ti.Fields, fieldName);
                if (fi == null)
                {
                    throw new SiaqodbException("Field:" + fieldName + " was not found as member of Type:" + ti.TypeName);
                }

                Where w = new Where(fieldName, OperationType.Equal, objInfo.AtInfo[fi]);
                w.StorageEngine     = this;
                w.ParentSqoTypeInfo = ti;
                w.ParentType.Add(w.ParentSqoTypeInfo.Type);

                if (i > 0)
                {
                    And and = new And();
                    and.Add(w, wPrev);

                    wPrev = and;
                }
                else
                {
                    wPrev = w;
                }
                i++;
            }

            List <int> oids = wPrev.GetOIDs();

            if (oids.Count > 1)
            {
                throw new SiaqodbException("In database exists more than one object with value of fields specified");
            }
            else if (oids.Count == 1)
            {
                objInfo.Oid = oids[0];
                #region old code that was duplicated like on SaveObject

                /*//obj.OID = oids[0];
                 * MetaHelper.SetOIDToObject(obj, oids[0], ti.Type);
                 *
                 * lock (_syncRoot)
                 * {
                 *  ObjectSerializer serializer = SerializerFactory.GetSerializer(this.path, GetFileByType(ti), useElevatedTrust);
                 *
                 *  CheckForConcurency(obj, objInfo, ti, serializer,false);
                 *
                 *  CheckConstraints(objInfo, ti);
                 *
                 *  Dictionary<string, object> oldValuesOfIndexedFields = this.PrepareUpdateIndexes(objInfo, ti, serializer);
                 *
                 *  serializer.SerializeObject(objInfo);
                 *
                 *  this.UpdateIndexes(objInfo, ti, oldValuesOfIndexedFields);
                 * }*/
                #endregion

                if (transact == null)
                {
                    this.SaveObject(obj, ti, objInfo);
                }
                else
                {
                    this.SaveObject(obj, ti, objInfo, transact);
                }
                return(true);
            }
            else
            {
                return(false);
            }
        }