public async ValueTask <OperationResult> InsertAsync(DbTable table, IMyMemory myMemory, DataSynchronizationPeriod synchronizationPeriod, DateTime now) { var entity = myMemory.ParseDynamicEntity(); if (string.IsNullOrEmpty(entity.PartitionKey)) { return(OperationResult.PartitionKeyIsNull); } if (string.IsNullOrEmpty(entity.RowKey)) { return(OperationResult.RowKeyIsNull); } if (table.HasRecord(entity)) { return(OperationResult.RecordExists); } var(result, dbPartition, dbRow) = table.Insert(entity, now); if (result != OperationResult.Ok) { return(result); } _dataSynchronizer.SynchronizeUpdate(table, new[] { dbRow }); await _persistenceHandler.SynchronizePartitionAsync(table, dbPartition.PartitionKey, synchronizationPeriod); return(OperationResult.Ok); }
public void RestoreRecord(IMyNoSqlDbEntity entityInfo, IMyMemory data) { if (!_rows.ContainsKey(entityInfo.RowKey)) { _rows.Add(entityInfo.RowKey, DbRow.RestoreSnapshot(entityInfo, data)); } }
public static DbRow ToDbRow(this IMyMemory myMemory) { var fields = myMemory.ParseFirstLevelOfJson().ToList(); var entityInfo = fields.GetEntityInfo(); return(DbRow.CreateNew(entityInfo, fields)); }
private static void ThrowException(this IMyMemory byteArray, int position) { var i = position - 10; if (i < 0) { i = 0; } var str = Encoding.UTF8.GetString(byteArray.Slice(i, position - i).Span); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(str); Console.ResetColor(); throw new Exception("Invalid Json at position: " + str); }
public async ValueTask <OperationResult> MergeAsync(DbTable table, IMyMemory myMemory, DataSynchronizationPeriod synchronizationPeriod, DateTime now) { var entity = myMemory.ParseDynamicEntity(); var(result, partition, dbRow) = table.Merge(entity, now); if (result != OperationResult.Ok) { return(result); } _dataSynchronizer.SynchronizeUpdate(table, new[] { dbRow }); await _persistenceHandler.SynchronizePartitionAsync(table, partition.PartitionKey, synchronizationPeriod); return(OperationResult.Ok); }
public DbPartition InitPartitionFromSnapshot(IMyMemory data) { DbPartition partition = null; ReaderWriterLockSlim.EnterWriteLock(); try { var initData = new ReadOnlyMemory <byte>(data.AsArray()); foreach (var dbRowMemory in new[] { initData }.SplitJsonArrayToObjects()) { var jsonFields = dbRowMemory.ParseFirstLevelOfJson(); var entityInfo = jsonFields.GetEntityInfo(); if (!_partitions.ContainsKey(entityInfo.PartitionKey)) { partition = DbPartition.Create(entityInfo.PartitionKey); _partitions.Add(entityInfo.PartitionKey, partition); } if (partition == null) { partition = _partitions[entityInfo.PartitionKey]; } var dbRow = DbRow.RestoreSnapshot(entityInfo, dbRowMemory); partition.InsertOrReplace(dbRow); } } finally { ReaderWriterLockSlim.ExitWriteLock(); } return(partition); }
public static DynamicEntity ParseDynamicEntity( this IMyMemory inData) { var result = new Dictionary <string, IJsonFirstLine>(); var expectedToken = ExpectedToken.OpenBracket; var subObjectLevel = 0; var subObjectString = false; var keyStartIndex = 0; var keyEndIndex = 0; var valueStartIndex = 0; var skipItems = 0; foreach (var(b, index) in inData.Enumerate()) { if (skipItems > 0) { skipItems--; continue; } if (expectedToken == ExpectedToken.EndOfFile) { break; } switch (expectedToken) { case ExpectedToken.OpenBracket: if (b.IsSpace()) { continue; } if (b != OpenBracket) { inData.ThrowException(index); } expectedToken = ExpectedToken.OpenKey; break; case ExpectedToken.OpenKey: if (b == CloseBracket) { expectedToken = ExpectedToken.EndOfFile; break; } if (b.IsSpace()) { continue; } if (b != DoubleQuote) { inData.ThrowException(index); } keyStartIndex = index; expectedToken = ExpectedToken.CloseKey; break; case ExpectedToken.CloseKey: switch (b) { case EscSymbol: skipItems++; break; case DoubleQuote: keyEndIndex = index + 1; expectedToken = ExpectedToken.DoubleColumn; break; } break; case ExpectedToken.DoubleColumn: if (b.IsSpace()) { continue; } if (b != DoubleColumn) { inData.ThrowException(index); } expectedToken = ExpectedToken.OpenValue; break; case ExpectedToken.OpenValue: if (b.IsSpace()) { continue; } valueStartIndex = index; switch (b) { case OpenArray: expectedToken = ExpectedToken.CloseArray; break; case DoubleQuote: expectedToken = ExpectedToken.CloseStringValue; break; case OpenBracket: subObjectLevel = 0; subObjectString = false; expectedToken = ExpectedToken.CloseObject; break; default: { if (StartOfDigit.ContainsKey((char)b) || b.IsStartOfBool()) { expectedToken = ExpectedToken.CloseNumberOrBoolValue; } else { inData.ThrowException(index); } break; } } break; case ExpectedToken.CloseStringValue: switch (b) { case EscSymbol: skipItems++; break; case DoubleQuote: var item = new MyJsonFirstLevelFieldData( inData.Slice(keyStartIndex, keyEndIndex - keyStartIndex), inData.Slice(valueStartIndex, index + 1 - valueStartIndex)); result.Add(item.Name, item); expectedToken = ExpectedToken.Comma; break; } break; case ExpectedToken.CloseNumberOrBoolValue: if (b == Comma || b == CloseBracket || b.IsSpace()) { var item = new MyJsonFirstLevelFieldData( inData.Slice(keyStartIndex, keyEndIndex - keyStartIndex), inData.Slice(valueStartIndex, index - valueStartIndex)); result.Add(item.Name, item); if (b == CloseBracket) { expectedToken = ExpectedToken.EndOfFile; } else { expectedToken = b == Comma ? ExpectedToken.OpenKey : ExpectedToken.Comma; } } break; case ExpectedToken.Comma: if (b.IsSpace()) { continue; } if (b == CloseBracket) { expectedToken = ExpectedToken.EndOfFile; continue; } if (b != Comma) { inData.ThrowException(index); } expectedToken = ExpectedToken.OpenKey; continue; case ExpectedToken.CloseObject: if (subObjectString) { switch (b) { case EscSymbol: skipItems++; continue; case DoubleQuote: subObjectString = false; break; } } else { switch (b) { case DoubleQuote: subObjectString = true; continue; case OpenBracket: subObjectLevel++; continue; case CloseBracket when subObjectLevel == 0: var item = new MyJsonFirstLevelFieldData( inData.Slice(keyStartIndex, keyEndIndex - keyStartIndex), inData.Slice(valueStartIndex, index + 1 - valueStartIndex)); result.Add(item.Name, item); expectedToken = ExpectedToken.Comma; break; case CloseBracket: subObjectLevel--; break; } } break; case ExpectedToken.CloseArray: if (subObjectString) { switch (b) { case EscSymbol: skipItems++; continue; case DoubleQuote: subObjectString = false; break; } } else { switch (b) { case DoubleQuote: subObjectString = true; continue; case OpenArray: subObjectLevel++; continue; case CloseArray when subObjectLevel == 0: var item = new MyJsonFirstLevelFieldData( inData.Slice(keyStartIndex, keyEndIndex - keyStartIndex), inData.Slice(valueStartIndex, index + 1 - valueStartIndex)); result.Add(item.Name, item); expectedToken = ExpectedToken.Comma; break; case CloseArray: subObjectLevel--; break; } } break; } } if (expectedToken != ExpectedToken.EndOfFile) { throw new Exception("Invalid Json"); } return(new DynamicEntity(result)); }
public static DbRow ToDbRow(this IMyMemory myMemory) { var entity = myMemory.ParseDynamicEntity(); return(DbRow.CreateNew(entity, DateTime.UtcNow)); }
public static DbRow RestoreSnapshot(IMyNoSqlDbEntity techData, IMyMemory data) { return(new DbRow(techData.PartitionKey, techData.RowKey, techData.TimeStamp, techData.Expires, data.AsArray())); }