/*
*
* File Name: EGNoSql.cs
* Initial Author: Elio Deçolli
* Purpose: Represents a NoSQL mini implementation. (At the time...)
* Last Code Cache Update: 12/20/2013
*
*/
// TODO: Maybe improve code for more performance?
// TODO2: Create a struct to hold each cell information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System****;
namespace eGamers
{
public class EGNoSqlVirtualRow
{
private Dictionary<string, byte[]> rowData;
public Dictionary<string, byte[]> RowData { get { return rowData; } }
public EGNoSqlVirtualRow(string[] cellTitle, List<byte[]> cellValues)
{
Dictionary<string, byte[]> data = new Dictionary<string, byte[]>();
if (cellTitle.Length == cellValues.Count)
{
for (int i = 0; i < cellTitle.Length; i++)
data.Add(cellTitle[i], cellValues[i]);
}
else
{
//Log.Error("Couldn't assemble row due to invalid cells information. #101");
}
rowData = data;
}
public byte[] ToBinary()
{
MemoryStream memsr = new MemoryStream();
BinaryWriter writer = new BinaryWriter(memsr);
writer.Write(rowDat*****unt);
//Header: Number of cells.
foreach (var v in rowData)
{
//Body00: Cell Name
//Body01: Cell Data Length
//Body02: Cell Data
writer.Write(v.Key);
writer.Write(v.Value.Length);
writer.Write(v.Value);
}
writer.Flush();
return memsr.ToArray();
}
public static EGNoSqlVirtualRow FromBinary(byte[] data)
{
MemoryStream memsr = new MemoryStream(data);
BinaryReader reader = new BinaryReader(memsr);
int rLen = reader.ReadInt32();
Dictionary<string, byte[]> rowData = new Dictionary<string, byte[]>();
for (int k = 0; k < rLen; k++)
{
string t = reader.ReadString();
int bLen = reader.ReadInt32();
byte[] cdata = reader.ReadBytes(bLen);
rowData.Add(t, cdata);
}
EGNoSqlVirtualRow vRow = new EGNoSqlVirtualRow(rowData.Keys.ToArray(), rowData.Values.ToList());
return vRow;
}
}
public class EGNoSqlDatabase
{
public List<EGNoSqlVirtualRow> rows = new List<EGNoSqlVirtualRow>();
string file_name;
string db_name;
public string DatabaseName { get { return db_name; } }
public EGNoSqlDatabase(MemoryStream db, string name, string file_to_save)
{
if (db.ToArray().Length > 0)
{
Log.Info("Creating EGNoSQL Database from memory data...");
db_name = name;
file_name = file_to_save;
BinaryReader reader = new BinaryReader(db);
/*int check = reader.ReadInt32();
if (check != 0xFFF12C)
return;*/
//Header: Rows Count + 2*0x00
int len1 = reader.ReadInt32();
reader.ReadByte();
reader.ReadByte();
//Body: Rows
for (int i = 0; i < len1; i++)
{
int rLen = reader.ReadInt32();
Dictionary<string, byte[]> rowData = new Dictionary<string, byte[]>();
for (int k = 0; k < rLen; k++)
{
string t = reader.ReadString();
int bLen = reader.ReadInt32();
byte[] data = reader.ReadBytes(bLen);
rowData.Add(t, data);
}
EGNoSqlVirtualRow vRow = new EGNoSqlVirtualRow(rowData.Keys.ToArray(), rowData.Values.ToList());
rows.Add(vRow);
}
}
}
public EGNoSqlDatabase(string fileToSave, string dbName)
{
file_name = fileToSave;
if (File.Exists(file_name))
{
Log.Info("Loading EGNoSQL DB: " + db_name);
if (File.ReadAllBytes(fileToSave).Length > 0)
{
MemoryStream memsr = new MemoryStream(File.ReadAllBytes(file_name));
BinaryReader reader = new BinaryReader(memsr);
int check = reader.ReadInt32();
if (check != 0xFFF12C)
return;
//Header: Rows Count + 2*0x00
int len1 = reader.ReadInt32();
reader.ReadByte();
reader.ReadByte();
//Body: Rows
for (int i = 0; i < len1; i++)
{
int rLen = reader.ReadInt32();
Dictionary<string, byte[]> rowData = new Dictionary<string, byte[]>();
for (int k = 0; k < rLen; k++)
{
string t = reader.ReadString();
int bLen = reader.ReadInt32();
byte[] data = reader.ReadBytes(bLen);
rowData.Add(t, data);
}
EGNoSqlVirtualRow vRow = new EGNoSqlVirtualRow(rowData.Keys.ToArray(), rowData.Values.ToList());
rows.Add(vRow);
Log.Info("Loaded Virtual Row #" + (i + 1).ToString());
}
}
Log.Info("EGNoSQL DB has been loaded!");
}
else
{
File.Create(file_name);
}
db_name = dbName;
}
public byte[] GetCellData(int rowIndex, string cellTitle)
{
return rows[rowIndex]****wData[cellTitle];
}
public int FindRowIndex(string cellTitle, byte[] cellvalue)
{
for (int i = 0; i < rows.Count; i++)
{
if (rows[i]****wDat*****ntainsKey(cellTitle))
{
if (rows[i]****wData[cellTitle] == cellvalue)
return i;
}
}
return -1;
}
public void RemoveRow(int rIndex)
{
rows.RemoveAt(rIndex);
}
public void UpdateRow(int rowIndex, Dictionary<string, byte[]> values)
{
foreach (var v in values)
{
rows[rowIndex]****wData[v.Key] = v.Value;
}
}
public void UpdateRow(int rowIndex, EGNoSqlVirtualRow row)
{
rows[rowIndex] = row;
}
public EGNoSqlVirtualRow FindRow(int index)
{
if (rows.Count >= index)
return rows[index];
return null;
}
public EGNoSqlVirtualRow[] FindRows(string cellTitle)
{
List<EGNoSqlVirtualRow> cRows = new List<EGNoSqlVirtualRow>();
foreach (EGNoSqlVirtualRow row in rows)
{
if (row****wDat*****ntainsKey(cellTitle))
{
Log.Info("EGNoSQL: Found 1 match for current row query.");
cRows.Add(row);
}
}
if (cRows.Count > 0)
return cRows.ToArray();
Log.Error("EGNoSQL: Cannot find row within the current database.");
return null;
}
public void AddRow(EGNoSqlVirtualRow row)
{
rows.Add(row);
}
public int RowCount { get { return rows.Count; } }
public List<byte[]> FindCellData(string cellTitle)
{
List<byte[]> celldatas = new List<byte[]>();
foreach (EGNoSqlVirtualRow row in rows)
{
if (row****wDat*****ntainsKey(cellTitle))
{
Log.Info("EGNoSQL: Found 1 match for current cell query.");
celldatas.Add(row****wData[cellTitle]);
}
}
if (celldatas.Count > 0)
return celldatas;
Log.Error("EGNoSQL: Cannot find cell within the current row segment.");
return null;
}
static bool FileInUse(string path)
{
try
{
using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate))
{
fs.Close();
}
return false;
}
catch (IOException ex)
{
return true;
}
}
public void SaveToFile()
{
Log.Info("Updating EGNoSQL DB: " + db_name);
List<byte[]> array_segment = new List<byte[]>();
foreach (var v in rows)
{
array_segment.Add(v.ToBinary());
}
MemoryStream memsr = new MemoryStream();
BinaryWriter writer = new BinaryWriter(memsr);
writer.Write(0xFFF12C);
writer.Write(array_segmen*****unt);
writer.Write(new byte());
writer.Write(new byte());
foreach (var v in array_segment)
{
writer.Write(v);
}
writer.Flush();
check:
if (!FileInUse(file_name))
File.WriteAllBytes(file_name, memsr.ToArray());
else goto check;
Log.Info("EGNoSQL DB has been updated!");
}
public byte[] ToArray()
{
List<byte[]> array_segment = new List<byte[]>();
foreach (var v in rows)
{
array_segment.Add(v.ToBinary());
}
MemoryStream memsr = new MemoryStream();
BinaryWriter writer = new BinaryWriter(memsr);
writer.Write(0xFFF12C);
writer.Write(array_segmen*****unt);
writer.Write(new byte());
writer.Write(new byte());
foreach (var v in array_segment)
{
writer.Write(v);
}
writer.Flush();
return memsr.ToArray();
}
}
}