private static void LoadTables(ref XMLEntity entity, XmlNode tables_node) { if (tables_node == null) { return; } foreach (XmlNode table_node in tables_node.ChildNodes) { TablePrefab table_prefab = new TablePrefab(); table_prefab.name = table_node.Attributes["name"].Value; table_prefab.save = bool.Parse(table_node.Attributes["save"].Value); table_prefab.sync = bool.Parse(table_node.Attributes["sync"].Value); table_prefab.desc = table_node.Attributes["desc"].Value; table_prefab.cols = int.Parse(table_node.Attributes["cols"].Value); foreach (XmlNode child_node in table_node.ChildNodes) { if (child_node.Name == "primary_key") { TablePrefab.PrimaryKeyPrefab primary_key = new TablePrefab.PrimaryKeyPrefab(); primary_key.type = Enum.Parse <VarType>(child_node.Attributes["type"].Value); primary_key.name = child_node.Attributes["name"].Value; primary_key.desc = child_node.Attributes["desc"].Value; table_prefab.primary_key = primary_key; } else if (child_node.Name == "column") { TablePrefab.ColumnPrefab column = new TablePrefab.ColumnPrefab(); column.index = int.Parse(child_node.Attributes["index"].Value); column.type = Enum.Parse <VarType>(child_node.Attributes["type"].Value); column.name = child_node.Attributes["name"].Value; column.desc = child_node.Attributes["desc"].Value; table_prefab.columns.Add(column.index, column); } } if (table_prefab.columns.Count != table_prefab.cols || table_prefab.columns.Keys.ToList()[0] != 0 || table_prefab.columns.Keys.ToList()[table_prefab.cols - 1] != (table_prefab.cols - 1)) { throw new Exception($"{entity.type} table {table_prefab.name} columns config failed"); } entity.SelfTables.Add(table_prefab); } }
private async Task <Entity> GetCacheEntity(Nuid entity_id) { try { IRedisDatabase db = GetCache(entity_id); ITransaction query_trans = db.Database.CreateTransaction(); string type = await GetCacheType(entity_id); EntityTransaction trans = new EntityTransaction(entity_id, type); EntityPrefab entity_prefab = Prefabs.GetEntity(trans.Type); if (entity_prefab == null) { throw new Exception($"Prefabs.GetEntity cant found {trans.Type}"); } string field_key = CacheUtils.BuildFields(trans.Id); trans.Fields = query_trans.HashGetAllAsync(field_key); foreach (Table table in trans.Entity.GetTables()) { TablePrefab table_prefab = entity_prefab.tables[table.GetName()]; string table_key = CacheUtils.BuildTable(trans.Id, table.GetName()); Task <HashEntry[]> key_values = query_trans.HashGetAllAsync(table_key); trans.AddTableTrans(table.GetName(), key_values); } bool redis_execute = await query_trans.ExecuteAsync(); if (!redis_execute) { throw new Exception("query_trans ExecuteAsync ERROR!!"); } return(await BuildCacheEntity(trans)); } catch (Exception ex) { _Logger.LogError(ex, "GetCacheEntities Failed"); } return(null); }
private async Task CallbackTable(Nuid id, string table_name, TableEvent table_event, NList args) { string entity_type = Global.NULL_STRING; Entity entity = EntityManager.Get(id); if (entity != null) { entity_type = entity.Type; } else { entity_type = await GetCacheType(id); } EntityPrefab entity_prefab = Prefabs.GetEntity(entity_type); if (entity_prefab == null) { return; } if (entity_prefab.ancestors != null && entity_prefab.ancestors.Count > 0) { for (int i = entity_prefab.ancestors.Count - 1; i >= 0; i--) { string parent_type = entity_prefab.ancestors[i]; await NModule.CallbackTable(this, id, parent_type, table_name, table_event, args); } } await NModule.CallbackTable(this, id, entity_type, table_name, table_event, args); TablePrefab table_prefab = entity_prefab.tables[table_name]; if (table_prefab != null && table_prefab.sync) { NList msg = NList.New().Add(id).Add(table_name).Add((int)table_event).Append(args); await SyncTable(id, msg); } }
private async Task PushPersistTables(Entity entity) { EntityPrefab entity_prefab = Prefabs.GetEntity(entity.Type); if (entity_prefab == null) { return; } var database = _IMongoClient.GetDatabase(PersistUtils.ENTITY_DB); Table[] tables = entity.GetTables(); foreach (Table table in tables) { var collection = database.GetCollection <BsonDocument>(table.Name); TablePrefab table_prefab = entity_prefab.tables[table.Name]; if (table_prefab == null) { continue; } if (!table_prefab.save) { continue; } NList rows = table.GetRows(); for (int i = 0; i < rows.Count; i++) { long row = rows.Get <long>(i); NList row_value = table.GetRow(row); Dictionary <string, object> models = new Dictionary <string, object>(); models.Add(Global.MARK_ORIGIN, entity.Id.Origin); models.Add(Global.MARK_UNIQUE, entity.Id.Unique); models.Add(Global.MARK_ROW, row); for (int col = 0; col < table_prefab.cols; col++) { TablePrefab.ColumnPrefab column = table_prefab.columns[col]; switch (column.type) { case VarType.Bool: models.Add(column.name, row_value.Get <bool>(col)); break; case VarType.Int: models.Add(column.name, row_value.Get <int>(col)); break; case VarType.Float: models.Add(column.name, row_value.Get <float>(col)); break; case VarType.Long: models.Add(column.name, row_value.Get <long>(col)); break; case VarType.Time: models.Add(column.name, row_value.Get <DateTime>(col)); break; case VarType.Nuid: models.Add(column.name, BsonDocument.Parse(JsonUtils.ToJson(row_value.Get <Nuid>(col)))); break; case VarType.String: models.Add(column.name, row_value.Get <string>(col)); break; case VarType.List: models.Add(column.name, BsonDocument.Parse(JsonUtils.ToJson(row_value.Get <NList>(col)))); break; } } await collection.InsertOneAsync(new BsonDocument(models)); } } }
private async Task SavePersistEntities() { IReadOnlyList <Entity> entities = null; if (NodeType == Abstractions.NodeType.Grain) { entities = EntityManager.GetEntities(); } else if (NodeType == Abstractions.NodeType.Cache) { entities = await GetCacheEntities(); } if (entities == null || entities.Count == 0) { return; } EntityList entity_list = new EntityList(); entity_list.entities = new List <EntityChild>(); entity_list.origin = Identity; entity_list.node = NodeType; var database = _IMongoClient.GetDatabase(PersistUtils.ENTITY_DB); foreach (Entity entity in entities) { EntityPrefab entity_prefab = Prefabs.GetEntity(entity.Type); if (entity_prefab == null) { continue; } Dictionary <string, object> entity_models = new Dictionary <string, object>(); entity_models.Add(Global.MARK_UNIQUE, entity.Id.Unique); Field[] fields = entity.GetFields(); foreach (Field field in fields) { FieldPrefab field_prefab = entity_prefab.fields[field.Name]; if (field_prefab == null) { continue; } if (!field_prefab.save) { continue; } switch (field_prefab.type) { case VarType.Bool: { entity_models.Add(field_prefab.name, field.Get <bool>()); } break; case VarType.Int: { entity_models.Add(field_prefab.name, field.Get <int>()); } break; case VarType.Float: { entity_models.Add(field_prefab.name, field.Get <float>()); } break; case VarType.Long: { entity_models.Add(field_prefab.name, field.Get <long>()); } break; case VarType.Nuid: { BsonDocument document = BsonDocument.Parse(JsonUtils.ToJson(field.Get <Nuid>())); entity_models.Add(field_prefab.name, document); } break; case VarType.String: { entity_models.Add(field_prefab.name, field.Get <string>()); } break; case VarType.List: { BsonDocument document = BsonDocument.Parse(JsonUtils.ToJson(field.Get <NList>())); entity_models.Add(field_prefab.name, document); } break; default: break; } } Table[] tables = entity.GetTables(); foreach (Table base_table in tables) { BsonArray table_model = new BsonArray(); TablePrefab table_prefab = entity_prefab.tables[base_table.GetName()]; switch (table_prefab.primary_key.type) { case VarType.Bool: { UpdateTableKeyValue <bool>(); } break; case VarType.Int: { UpdateTableKeyValue <int>(); } break; case VarType.Long: { UpdateTableKeyValue <long>(); } break; case VarType.Float: { UpdateTableKeyValue <float>(); } break; case VarType.String: { UpdateTableKeyValue <string>(); } break; case VarType.Nuid: { UpdateTableKeyValue <Nuid>(); } break; default: break; } void UpdateTableKeyValue <TPrimaryKey>() { Table <TPrimaryKey> table = base_table as Table <TPrimaryKey>; foreach (TPrimaryKey key in table.GetPrimaryKeys()) { Dictionary <string, object> key_value_models = new Dictionary <string, object>(); key_value_models.Add(nameof(TablePrefab.primary_key), key); NList key_value = table.GetKeyValue(key); for (int col = 0; col < table_prefab.cols; col++) { TablePrefab.ColumnPrefab col_prefab = table_prefab.columns[col]; switch (col_prefab.type) { case VarType.Bool: { bool col_value = key_value.Get <bool>(col); key_value_models.Add(col_prefab.name, col_value); } break; case VarType.Int: { int col_value = key_value.Get <int>(col); key_value_models.Add(col_prefab.name, col_value); } break; case VarType.Long: { long col_value = key_value.Get <long>(col); key_value_models.Add(col_prefab.name, col_value); } break; case VarType.Float: { float col_value = key_value.Get <float>(col); key_value_models.Add(col_prefab.name, col_value); } break; case VarType.String: { string col_value = key_value.Get <string>(col); key_value_models.Add(col_prefab.name, col_value); } break; case VarType.Nuid: { Nuid col_value = key_value.Get <Nuid>(col); key_value_models.Add(col_prefab.name, BsonDocument.Parse(JsonUtils.ToJson(col_value))); } break; case VarType.List: { NList col_value = key_value.Get <NList>(col); key_value_models.Add(col_prefab.name, BsonDocument.Parse(JsonUtils.ToJson(col_value))); } break; default: break; } } table_model.Add(new BsonDocument(key_value_models)); } } entity_models.Add(base_table.GetName(), table_model); } entity_list.entities.Add(new EntityChild() { unique = entity.Id.Unique, type = entity.Type, entity = new BsonDocument(entity_models) }); } var collection = database.GetCollection <EntityList>(PersistUtils.ENTITIES); var filter = Builders <EntityList> .Filter.And(Builders <EntityList> .Filter.Eq(n => n.origin, Identity)); EntityList found = await collection.FindOneAndReplaceAsync(filter, entity_list); if (found == null) { await collection.InsertOneAsync(entity_list); } }
private async Task <NList> GetCacheKeys(Nuid id, string table_name) { if (!await CacheExist(id)) { return(NList.Empty); } IRedisDatabase db = GetCache(id); string key = CacheUtils.BuildTable(id, table_name); string type = await GetCacheType(id); EntityPrefab entity_prefab = Prefabs.GetEntity(type); if (entity_prefab == null) { return(NList.Empty); } TablePrefab table_prefab = entity_prefab.tables[table_name]; if (table_prefab == null) { return(NList.Empty); } NList rows = NList.New(); foreach (string hash_key in await db.HashKeysAsync(key)) { switch (table_prefab.primary_key.type) { case VarType.Bool: { bool row = bool.Parse(hash_key); rows.Add(row); } break; case VarType.Int: { int row = int.Parse(hash_key); rows.Add(row); } break; case VarType.Long: { long row = long.Parse(hash_key); rows.Add(row); } break; case VarType.Nuid: { Nuid row = Nuid.Parse(hash_key); rows.Add(row); } break; case VarType.String: { string row = hash_key; rows.Add(row); } break; default: break; } } return(rows.Count > 0 ? rows : NList.Empty); }
private async Task SetCacheEntities(IReadOnlyList <Entity> entities) { IRedisDatabase db = GetCache(); ITransaction trans = db.Database.CreateTransaction(); { string key = CacheUtils.BuildEntities(Nuid.New(Identity, Identity)); HashEntry[] hashFields = new HashEntry[entities.Count]; for (int i = 0; i < entities.Count; i++) { hashFields[i] = new HashEntry(entities[i].Id.Unique, entities[i].Type); } Task _ = trans.HashSetAsync(key, hashFields); } { foreach (Entity entity in entities) { EntityPrefab entity_prefab = Prefabs.GetEntity(entity.Type); if (entity_prefab == null) { continue; } string fields_key = CacheUtils.BuildFields(entity.Id); Field[] fields = entity.GetFields(); List <HashEntry> cache_fields = new List <HashEntry>(); for (int i = 0; i < fields.Length; i++) { FieldPrefab field_prefab = entity_prefab.fields[fields[i].Name]; if (field_prefab == null) { continue; } string field_value = ""; switch (field_prefab.type) { case VarType.Bool: field_value = JsonUtils.ToJson(fields[i].Get <bool>()); break; case VarType.Int: field_value = JsonUtils.ToJson(fields[i].Get <int>()); break; case VarType.Long: field_value = JsonUtils.ToJson(fields[i].Get <long>()); break; case VarType.Float: field_value = JsonUtils.ToJson(fields[i].Get <float>()); break; case VarType.String: field_value = JsonUtils.ToJson(fields[i].Get <string>()); break; case VarType.Nuid: field_value = JsonUtils.ToJson(fields[i].Get <Nuid>()); break; case VarType.List: field_value = JsonUtils.ToJson(fields[i].Get <NList>()); break; default: break; } cache_fields.Add(new HashEntry(fields[i].Name, field_value)); } Task _ = trans.HashSetAsync(fields_key, cache_fields.ToArray()); Table[] tables = entity.GetTables(); foreach (Table table in tables) { string table_key = CacheUtils.BuildTable(entity.Id, table.GetName()); TablePrefab table_prefab = entity_prefab.tables[table.GetName()]; if (table_prefab == null) { continue; } List <HashEntry> cache_key_values = new List <HashEntry>(); void SetCacheKeyValue <TPrimaryKey>() { Table <TPrimaryKey> t = table as Table <TPrimaryKey>; IReadOnlyList <TPrimaryKey> keys = t.GetPrimaryKeys(); foreach (TPrimaryKey key in keys) { string json = JsonUtils.ToJson(t.GetKeyValue(key)); cache_key_values.Add(new HashEntry(key.ToString(), json)); } } switch (table_prefab.primary_key.type) { case VarType.Bool: SetCacheKeyValue <bool>(); break; case VarType.Int: SetCacheKeyValue <int>(); break; case VarType.Long: SetCacheKeyValue <long>(); break; case VarType.Float: SetCacheKeyValue <float>(); break; case VarType.String: SetCacheKeyValue <string>(); break; case VarType.Nuid: SetCacheKeyValue <Nuid>(); break; default: break; } Task __ = trans.HashSetAsync(table_key, cache_key_values.ToArray()); } } bool redis_execute = await trans.ExecuteAsync(); if (!redis_execute) { throw new Exception("trans ExecuteAsync ERROR!!"); } } }
async Task <Entity> BuildCacheEntity(EntityTransaction trans) { EntityPrefab entity_prefab = Prefabs.GetEntity(trans.Type); if (entity_prefab == null) { throw new Exception($"Prefabs.GetEntity cant found {trans.Type}"); } HashEntry[] fields = await trans.Fields; foreach (HashEntry entry in fields) { FieldPrefab field_prefab = entity_prefab.fields[entry.Name]; if (field_prefab == null) { continue; } switch (field_prefab.type) { case VarType.Bool: { SetFieldValue <bool>(entry.Name, entry.Value, ref trans.Entity); } break; case VarType.Int: { SetFieldValue <int>(entry.Name, entry.Value, ref trans.Entity); } break; case VarType.Float: { SetFieldValue <float>(entry.Name, entry.Value, ref trans.Entity); } break; case VarType.Long: { SetFieldValue <long>(entry.Name, entry.Value, ref trans.Entity); } break; case VarType.String: { SetFieldValue <string>(entry.Name, entry.Value, ref trans.Entity); } break; case VarType.Nuid: { SetFieldValue <Nuid>(entry.Name, entry.Value, ref trans.Entity); } break; case VarType.List: { SetFieldValue <NList>(entry.Name, entry.Value, ref trans.Entity); } break; default: break; } void SetFieldValue <T>(string field_name, RedisValue field_value, ref Entity entity) { T value = JsonUtils.ToObject <T>(field_value); Field field = entity.GetField(field_name); if (field == null) { return; } NList res = NList.Empty; field.TrySet(value, out res); } } foreach (KeyValuePair <string, Task <HashEntry[]> > table_task in trans.Tables) { TablePrefab table_prefab = entity_prefab.tables[table_task.Key]; if (table_prefab == null) { continue; } Table table_trans = trans.Entity.GetTable(table_task.Key); if (table_trans == null) { continue; } HashEntry[] table_key_values = await table_task.Value; switch (table_prefab.primary_key.type) { case VarType.Bool: { Table <bool> table = table_trans as Table <bool>; foreach (HashEntry entry in table_key_values) { bool key = bool.Parse(entry.Name); NList key_value = JsonUtils.ToObject <NList>(entry.Value); table.TrySetKeyValue(key, key_value, out _); } } break; case VarType.Int: { Table <int> table = table_trans as Table <int>; foreach (HashEntry entry in table_key_values) { int key = int.Parse(entry.Name); NList key_value = JsonUtils.ToObject <NList>(entry.Value); table.TrySetKeyValue(key, key_value, out _); } } break; case VarType.Long: { Table <long> table = table_trans as Table <long>; foreach (HashEntry entry in table_key_values) { long key = long.Parse(entry.Name); NList key_value = JsonUtils.ToObject <NList>(entry.Value); table.TrySetKeyValue(key, key_value, out _); } } break; case VarType.String: { Table <string> table = table_trans as Table <string>; foreach (HashEntry entry in table_key_values) { string key = entry.Name; NList key_value = JsonUtils.ToObject <NList>(entry.Value); table.TrySetKeyValue(key, key_value, out _); } } break; case VarType.Nuid: { Table <Nuid> table = table_trans as Table <Nuid>; foreach (HashEntry entry in table_key_values) { Nuid key = Nuid.Parse(entry.Name); NList key_value = JsonUtils.ToObject <NList>(entry.Value); table.TrySetKeyValue(key, key_value, out _); } } break; default: break; } } return(trans.Entity); }
private async Task <IReadOnlyList <Entity> > GetCacheEntities() { Nuid id = Nuid.New(Identity, Identity); IRedisDatabase db = GetCache(id); string entites_key = CacheUtils.BuildEntities(id); List <Entity> sorts = new List <Entity>(); List <EntityTransaction> entity_trans = new List <EntityTransaction>(); try { HashEntry[] entities = await db.Database.HashGetAllAsync(entites_key); foreach (HashEntry member in entities) { long child_id = long.Parse(member.Name); string type = member.Value; Nuid entity_id = Nuid.New(child_id, Identity); EntityTransaction trans = new EntityTransaction(entity_id, type); if (trans.Entity == null) { continue; } entity_trans.Add(trans); } ITransaction query_trans = db.Database.CreateTransaction(); foreach (EntityTransaction trans in entity_trans) { EntityPrefab entity_prefab = Prefabs.GetEntity(trans.Type); if (entity_prefab == null) { throw new Exception($"Prefabs.GetEntity cant found {trans.Type}"); } string field_key = CacheUtils.BuildFields(trans.Id); trans.Fields = query_trans.HashGetAllAsync(field_key); foreach (Table table in trans.Entity.GetTables()) { TablePrefab table_prefab = entity_prefab.tables[table.GetName()]; string table_key = CacheUtils.BuildTable(trans.Id, table.GetName()); Task <HashEntry[]> key_values = query_trans.HashGetAllAsync(table_key); trans.AddTableTrans(table.GetName(), key_values); } } bool redis_execute = await query_trans.ExecuteAsync(); if (!redis_execute) { throw new Exception("query_trans ExecuteAsync ERROR!!"); } foreach (EntityTransaction trans in entity_trans) { Entity entity = await BuildCacheEntity(trans); sorts.Add(entity); } } catch (Exception ex) { _Logger.LogError(ex, "GetCacheEntities Failed"); } entity_trans.Clear(); sorts.Sort((x, y) => { EntityPrefab entity_x = Prefabs.GetEntity(x.Type); EntityPrefab entity_y = Prefabs.GetEntity(y.Type); return(entity_y.priority - entity_x.priority); }); return(sorts); }