public static string PrettyPrintField(DBRecord record, int fieldIdx) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); DBColumnInfo columnInfo = record.ownerTable.columns[fieldIdx]; sb.Append(columnInfo.columnIdenfier); sb.Append(" ("); sb.Append(columnInfo.columnType); sb.Append(")="); sb.Append(PrettyPrintFieldValue(record, fieldIdx)); return(sb.ToString()); }
public static string PrettyPrintRecord(DBRecord record) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); sb.Append("ID="); sb.Append(record.identifier); for (int i = 0; i < record.ownerTable.columns.Count; i++) { sb.Append(", "); sb.Append(PrettyPrintField(record, i)); } return(sb.ToString()); }
private void ParseWholeText(JsonElement baseElement) { if (baseElement.TryGetProperty("name", out JsonElement nameProp)) { identifier = nameProp.GetString(); } else { Logger.Debug?.WriteLine("[RookDB] database table has no name property!"); identifier = "_unnamed_" + new Random().Next().ToString() + "_"; } if (!baseElement.TryGetProperty("columns", out _)) { Logger.Critical?.WriteLine("[RookDB] Database table has no column information. Cannot load without schema."); return; } if (!baseElement.TryGetProperty("lines", out _)) { Logger.Critical?.WriteLine("[RookDB] Database table has no records (not even a node), an error must have occured during export/write. Cannot load without schema."); return; } List <DBColumnInfo> columnsInfos = ParseColumns(baseElement.GetProperty("columns")); foreach (DBColumnInfo col in columnsInfos) { col.ownerTable = this; columns.Add(col); } foreach (JsonElement recordElement in baseElement.GetProperty("lines").EnumerateArray()) { DBRecord rec = ParseRecord(recordElement, columns, ownerDB.embeddedSchemas); if (records.ContainsKey(rec.identifier)) { Logger.Critical?.WriteLine("[RookDB] Record has duplicated unique identifier, ignoring current record. UID=" + rec.identifier); continue; } rec.ownerTable = this; records.Add(rec.identifier, rec); } Logger.Debug?.WriteLine("[RookDB] Loaded table with " + columns.Count + " columns."); }
public static string PrettyPrintFieldValue(DBRecord record, int fieldIdx) { string rtnString = ""; switch (record.ownerTable.columns[fieldIdx].columnType) { case ColumnType.Flags: string[] flags = (string[])record.values[fieldIdx]; for (int i = 0; i < flags.Length; i++) { if (i > 0) { rtnString += " + "; } rtnString += flags[i]; } return(rtnString); case ColumnType.List: return("{ListData}"); case ColumnType.Color: byte[] colArr = (byte[])record.values[fieldIdx]; rtnString += $"r{colArr[0]} g{colArr[1]} b{colArr[2]}"; if (colArr.Length == 4) { rtnString += " a{colArr[3]}"; } return(rtnString); case ColumnType.Reference: return("{ " + (string)record.values[fieldIdx] + " }"); default: return(record.values[fieldIdx].ToString()); } }
internal static DBRecord ParseRecord(JsonElement baseElement, List <DBColumnInfo> columns, Dictionary <string, List <DBColumnInfo> > listSchemas) { string recordIdent = null; List <object> values = new List <object>(); foreach (DBColumnInfo column in columns) { switch (column.columnType) { case ColumnType.UniqueIdentifier: if (baseElement.TryGetProperty(column.columnIdenfier, out JsonElement uidChild)) { recordIdent = uidChild.GetString(); values.Add(recordIdent); } else { throw new Exception("[RookDB] Cannot have a UniqueIdentifier with no value! (JSON property not found via column name.)"); } break; case ColumnType.Boolean: if (baseElement.TryGetProperty(column.columnIdenfier, out JsonElement boolChild)) { values.Add(boolChild.GetBoolean()); } else { values.Add(RookDB.GetDefaultFieldValue(column)); } break; case ColumnType.Color: if (baseElement.TryGetProperty(column.columnIdenfier, out JsonElement colorChild)) { //read int, force to 6 digit wide hex representation, parse pairs of characters as bytes (r/g/b values). string cHex = colorChild.GetInt32().ToString("X6"); values.Add(new byte[] { Convert.ToByte(cHex.Substring(0, 2), 16), Convert.ToByte(cHex.Substring(2, 2), 16), Convert.ToByte(cHex.Substring(4, 2), 16) }); } else { values.Add(RookDB.GetDefaultFieldValue(column)); } break; case ColumnType.Enumeration: if (baseElement.TryGetProperty(column.columnIdenfier, out JsonElement enumChild) || enumChild.GetInt32() >= column.columnMeta.Length) { values.Add(column.columnMeta[enumChild.GetInt32()]); } else { values.Add(RookDB.GetDefaultFieldValue(column)); } break; case ColumnType.Flags: if (baseElement.TryGetProperty(column.columnIdenfier, out JsonElement flagsChild)) { List <string> claimed = new List <string>(); uint flagData = flagsChild.GetUInt32(); for (int shiftCount = 0; shiftCount < 32 && shiftCount < column.columnMeta.Length; shiftCount++) { if ((flagData & (1 << shiftCount)) != 0) { claimed.Add(column.columnMeta[shiftCount]); } } values.Add(claimed.ToArray()); } else { values.Add(RookDB.GetDefaultFieldValue(column)); } break; case ColumnType.Float: if (baseElement.TryGetProperty(column.columnIdenfier, out JsonElement floatChild)) { values.Add(floatChild.GetSingle()); } else { values.Add(RookDB.GetDefaultFieldValue(column)); } break; case ColumnType.Integer: if (baseElement.TryGetProperty(column.columnIdenfier, out JsonElement intChild)) { values.Add(intChild.GetInt32()); } else { values.Add(RookDB.GetDefaultFieldValue(column)); } break; case ColumnType.List: if (baseElement.TryGetProperty(column.columnIdenfier, out JsonElement listElement)) { if (!listSchemas.ContainsKey(column.ownerTable.identifier + "@" + column.columnIdenfier)) { Logger.Info.WriteLine("[RookDB] Attempted to parse list with missing schema. Check database is valid, this should not happen. Ignoring field."); values.Add(RookDB.GetDefaultFieldValue(column)); break; } DBTable listTable = new DBTable(listSchemas[column.ownerTable.identifier + "@" + column.columnIdenfier], "EmbeddedList"); foreach (JsonElement field in listElement.EnumerateArray()) { DBRecord record = ParseRecord(field, listTable.columns, listSchemas); record.ownerTable = listTable; listTable.records.Add(record.identifier, record); } values.Add(listTable); } else { values.Add(RookDB.GetDefaultFieldValue(column)); } break; case ColumnType.Reference: if (baseElement.TryGetProperty(column.columnIdenfier, out JsonElement refChild)) { values.Add(column.columnMeta[0] + "/" + refChild.GetString()); } else { values.Add(RookDB.GetDefaultFieldValue(column)); } break; case ColumnType.Text: if (baseElement.TryGetProperty(column.columnIdenfier, out JsonElement textChild)) { values.Add(textChild.GetString()); } else { values.Add(RookDB.GetDefaultFieldValue(column)); } break; } } if (recordIdent == null) { for (int i = 0; i < columns.Count; i++) { if (columns[i].columnType == ColumnType.Text) { recordIdent = (string)values[i]; break; } } if (recordIdent == null) { //if its still null, we have a serious problem here, we cant even make up a uid. throw new Exception("[RookDB] Cannot load database entry, it has no unique identity and no text fields to assume uid from."); } else { Logger.Verbose?.WriteLine("[RookDB] Record loaded without unique identifier, generated name=" + recordIdent); } } return(new DBRecord(recordIdent, values.ToArray())); }
private static void WriteRecord(DBRecord record, Utf8JsonWriter writer) { writer.WriteStartObject(); List <DBColumnInfo> columns = record.ownerTable.columns; for (int colIdx = 0; colIdx < columns.Count; colIdx++) { DBColumnInfo column = columns[colIdx]; switch (column.columnType) { case ColumnType.Boolean: writer.WriteBoolean(column.columnIdenfier, (bool)record.values[colIdx]); break; case ColumnType.Color: /* Probably my least favourite encoding of all time (I didnt design this! This is from castleDB spec) * Colours can only be RGB, alpha channel is not supported unfortunately. * Encoding works by taking each colour as 8bits (RGB24 format), converting each channel individually into a 2 digit hex number (0's needed for padding). * The 3 hex values are appended (RRGGBB) and converted to a single base10 integer. * This base10 int is what is written to disk. */ byte[] colArr = (byte[])record.values[colIdx]; string hexStr = Convert.ToString(colArr[0], 16); hexStr += Convert.ToString(colArr[1], 16); hexStr += Convert.ToString(colArr[2], 16); int compiledInt = Convert.ToInt32(hexStr, 16); writer.WriteNumber(column.columnIdenfier, compiledInt); break; case ColumnType.Enumeration: for (int i = 0; i < column.columnMeta.Length; i++) { if (column.columnMeta[i] == (string)record.values[colIdx]) { writer.WriteNumber(column.columnIdenfier, i); break; } } break; case ColumnType.Flags: int bitArray = 0; List <string> recordFlags = new List <string>((string[])record.values[colIdx]); for (int i = 0; i < column.columnMeta.Length && i < 32; i++) { if (recordFlags.Contains(column.columnMeta[i])) { bitArray = bitArray | (1 << i); } } writer.WriteNumber(column.columnIdenfier, bitArray); break; case ColumnType.Float: writer.WriteNumber(column.columnIdenfier, (float)record.values[colIdx]); break; case ColumnType.Integer: writer.WriteNumber(column.columnIdenfier, (int)record.values[colIdx]); break; case ColumnType.List: //TODO break; case ColumnType.Reference: string refId = (string)record.values[colIdx]; refId = refId.Remove(0, refId.IndexOf('/') + 1); writer.WriteString(column.columnIdenfier, refId); break; case ColumnType.Text: case ColumnType.UniqueIdentifier: writer.WriteString(column.columnIdenfier, (string)record.values[colIdx]); break; default: throw new Exception("*explosions* BOOOOM, this should not happen. (RookDB.WriteRecord tried to write a column with an invalid type.)"); } } writer.WriteEndObject(); }
public void AddRecord(string path, DBRecord record) { throw new NotImplementedException(); }