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); } } } } }
public void ReadObject(object obj, SqoTypeInfo ti, int oid, RawdataSerializer rawSerializer) { //long position = (long)ti.Header.headerSize + (long)((long)(oid - 1) * (long)ti.Header.lengthOfRecord); long position = MetaHelper.GetSeekPosition(ti, oid); int recordLength = ti.Header.lengthOfRecord; byte[] b = new byte[recordLength]; if (oidEnd == 0 && oidStart == 0) { file.Read(position, b); } else { int recordPosition = (oid - oidStart) * recordLength; Array.Copy(preloadedBytes, recordPosition, b, 0, b.Length); } int fieldPosition = 0; byte[] oidBuff = GetFieldBytes(b, fieldPosition, 4); int oidFromFile = ByteConverter.ByteArrayToInt(oidBuff); //eventual make comparison foreach (FieldSqoInfo ai in ti.Fields) { byte[] field = GetFieldBytes(b, ai.Header.PositionInRecord, ai.Header.Length); IByteTransformer byteTransformer = ByteTransformerFactory.GetByteTransformer(this, rawSerializer, ai, ti); object fieldVal = null; try { fieldVal = byteTransformer.GetObject(field); } catch (Exception ex) { if (ti.Type != null && ti.Type.IsGenericType() && ti.Type.GetGenericTypeDefinition() == typeof(Indexes.BTreeNode <>)) { throw new IndexCorruptedException(); } // SiaqodbConfigurator.LogMessage("Field's" + ai.Name + " value of Type " + ti.TypeName + "cannot be loaded, will be set to default.", VerboseLevel.Info); //fieldVal = MetaHelper.GetDefault(ai.AttributeType); throw ex; } if (ai.AttributeTypeId == MetaExtractor.documentID) { DocumentInfo dinfo = fieldVal as DocumentInfo; if (dinfo != null) { if (SiaqodbConfigurator.DocumentSerializer == null) { throw new SiaqodbException("Document serializer is not set, use SiaqodbConfigurator.SetDocumentSerializer method to set it"); } fieldVal = SiaqodbConfigurator.DocumentSerializer.Deserialize(ai.AttributeType, dinfo.Document); //put in weak cache to be able to update the document DocumentEventArgs args = new DocumentEventArgs(); args.ParentObject = obj; args.DocumentInfoOID = dinfo.OID; args.FieldName = ai.Name; args.TypeInfo = ti; this.OnNeedCacheDocument(args); } } #if SILVERLIGHT try { //dobj.SetValue(ai.FInfo, ByteConverter.DeserializeValueType(ai.FInfo.FieldType, field)); MetaHelper.CallSetValue(ai.FInfo, fieldVal, obj, ti.Type); } catch (Exception ex) { throw new SiaqodbException("Override GetValue and SetValue methods of SqoDataObject-Silverlight limitation to private fields"); } #else ai.FInfo.SetValue(obj, fieldVal); #endif } }