Created
October 8, 2021 20:51
-
-
Save DreamVB/7d38d898948a3ca5c3a01ef1016ec388 to your computer and use it in GitHub Desktop.
A small Text formated Single Table Database
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
TextDB db = new TextDB(); | |
private void NewDatabase() | |
{ | |
List<string> values = new List<string>(); | |
TextDB.FieldDef fd; | |
List<TextDB.FieldDef> elms = new List<TextDB.FieldDef>(); | |
fd.Name = "Name"; | |
fd.Length = 10; | |
elms.Add(fd); | |
fd.Name = "Age"; | |
fd.Length = 10; | |
elms.Add(fd); | |
fd.Name = "Sex"; | |
fd.Length = 1; | |
elms.Add(fd); | |
fd.Name = "Working"; | |
fd.Length = 10; | |
elms.Add(fd); | |
//Add table | |
db.NewTable(elms); | |
//Record 1 | |
values.Add("John"); | |
values.Add("20"); | |
values.Add("M"); | |
values.Add("Yes"); | |
db.AddRecord(values); | |
values = new List<string>(); | |
//Record 2 | |
values.Add("paula"); | |
values.Add("29"); | |
values.Add("F"); | |
values.Add("No"); | |
db.AddRecord(values); | |
//Save db | |
db.SaveDb(@"c:\out\test.txt"); | |
//Clear up | |
elms = new List<TextDB.FieldDef>(); | |
} | |
private void ShowNamesInDb() | |
{ | |
//Load db | |
db.LoadDb(@"c:\out\test.txt"); | |
//Display person Name | |
for (int r = 0; r < db.RecordCount; r++) | |
{ | |
MessageBox.Show(db.GetFeildValue(r, "Name")); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// DreamVB.TextDB Beta 1 | |
// This is a small single table database that allows you to add fields and set there widths | |
// This is a project I been working on while trying to learn about databases | |
// Next version I hope to allow the working with more than one table here are some of the things you can do | |
// Features | |
// All the database data resides in memory so it faster | |
// Add records | |
// Edit and read record values by using a index or a field name | |
// Delete records | |
// Remove all records | |
// Delete fields by using a index or a field name | |
// Append new fields all all records data aligns with new appends | |
// Sort the database by a field only works in ascending order for now | |
// Locate a record by searching by a field once found the record index is returned. | |
// Can read and write felid value of Integer, Double, String | |
// Update allows you to update the current file you opened with OpenDb | |
// SaveDb allows you to save to a different filename | |
// Any comments and suggestions are welcome please email me at [email protected] | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.IO; | |
namespace DreamVB.TextDB | |
{ | |
public class TextDB | |
{ | |
public struct FieldDef | |
{ | |
public string Name; | |
public int Length; | |
} | |
private List<FieldDef> Fields; | |
private List<List<string>> _Records; | |
private string dbFilename { get; set; } | |
private const string IndexRangeError = "Index Out Of Range"; | |
private int FieldIndex(string fldName) | |
{ | |
int idx = -1; | |
for (int x = 0; x < FieldCount; x++) | |
{ | |
if (Fields[x].Name.Equals(fldName, StringComparison.OrdinalIgnoreCase)) | |
{ | |
idx = x; | |
break; | |
} | |
} | |
return idx; | |
} | |
private string _FixValueSize(string data, int RealLength, int ExpectedLength) | |
{ | |
//Check of string length of greater then the expected length | |
if (RealLength > ExpectedLength) | |
{ | |
//Just extract the string to the expected length | |
return data.Substring(0, ExpectedLength); | |
} | |
else | |
{ | |
//Return data | |
return data; | |
} | |
} | |
private string StringPadRight(string S, int padsize) | |
{ | |
//Get the amount we need to pad | |
int max = (padsize - S.Length); | |
//Return the S with padded to right with spaces | |
return S + new String(' ', max); | |
} | |
private List<string> Get_FieldValues(string sLine) | |
{ | |
List<string> val = new List<string>(); | |
int pos = 0; | |
string sVal = string.Empty; | |
for (int x = 0; x < FieldCount; x++) | |
{ | |
//Get value | |
sVal = sLine.Substring(pos, Fields[x].Length); | |
//Add to value list and trim the padding spaces | |
val.Add(sVal.TrimEnd()); | |
//Get next value position | |
pos = (pos + Fields[x].Length); | |
sVal = string.Empty; | |
} | |
return val; | |
} | |
public TextDB() | |
{ | |
Fields = new List<FieldDef>(); | |
_Records = new List<List<string>>(); | |
} | |
public int RecordCount | |
{ | |
get | |
{ | |
return _Records.Count(); | |
} | |
} | |
public int FieldCount | |
{ | |
get | |
{ | |
return Fields.Count(); | |
} | |
} | |
public void NewTable(List<FieldDef>FieldStruct) | |
{ | |
bool found = false; | |
Fields = new List<FieldDef>(); | |
_Records = new List<List<string>>(); | |
foreach (FieldDef fi in FieldStruct) | |
{ | |
found = FieldIndex(fi.Name) != -1; | |
//Check if field is in the Fields list | |
if (found) | |
{ | |
//Found exit with error | |
throw new Exception("Field Already Exists:\n'" + fi.Name + "'"); | |
} | |
//Add field info | |
Fields.Add(fi); | |
} | |
} | |
public void AppendField(FieldDef FieldInfo, string vDefaultValue = "") | |
{ | |
List<string> vals; | |
//Check if the field name is found in the Fields list | |
bool found = FieldIndex(FieldInfo.Name) != -1; | |
if (found) | |
{ | |
throw new Exception("Field Already Exists:\n'" + FieldInfo.Name + "'"); | |
} | |
for (int x = 0; x < RecordCount; x++) | |
{ | |
vals = _Records[x]; | |
//Check length | |
if (vDefaultValue.Length > FieldInfo.Length) | |
{ | |
throw new Exception("Value Exceeds Field Length."); | |
} | |
vals.Add(vDefaultValue); | |
_Records[x] = vals; | |
} | |
//Add the new field. | |
Fields.Add(FieldInfo); | |
} | |
public void AddRecord(List<string> values) | |
{ | |
if (values.Count() != FieldCount) | |
{ | |
throw new Exception(IndexRangeError); | |
} | |
//Add new record. | |
_Records.Add(values); | |
} | |
public string GetFeildValue(int record, int index) | |
{ | |
if (record < 0 || record > RecordCount) | |
{ | |
throw new Exception(IndexRangeError); | |
} | |
else if (index < 0 || index > FieldCount) | |
{ | |
throw new Exception(IndexRangeError); | |
} | |
else | |
{ | |
return _Records[record][index]; | |
} | |
} | |
public string GetFeildValue(int record, string fldName) | |
{ | |
//Get field index | |
int idx = FieldIndex(fldName); | |
//Return field value | |
return GetFeildValue(record, idx); | |
} | |
public int GetFieldInteger(int record, int index) | |
{ | |
string tmp = GetFeildValue(record, index); | |
try | |
{ | |
return int.Parse(tmp); | |
} | |
catch (Exception ex) | |
{ | |
throw new Exception(ex.Message); | |
} | |
} | |
public int GetFieldInteger(int record, string fldName) | |
{ | |
int idx = FieldIndex(fldName); | |
return GetFieldInteger(record, idx); | |
} | |
public void SetFieldIntegter(int record, int index, int value) | |
{ | |
SetFieldValue(record, index, value.ToString()); | |
} | |
public void SetFieldIntegter(int record, string fldName, int value) | |
{ | |
int idx = FieldIndex(fldName); | |
SetFieldValue(record, idx, value.ToString()); | |
} | |
public double GetFieldDouble(int record, int index) | |
{ | |
string tmp = GetFeildValue(record, index); | |
try | |
{ | |
return double.Parse(tmp); | |
} | |
catch (Exception ex) | |
{ | |
throw new Exception(ex.Message); | |
} | |
} | |
public double GetFieldDouble(int record, string fldName) | |
{ | |
int idx = FieldIndex(fldName); | |
return GetFieldDouble(record, idx); | |
} | |
public void SetFieldDouble(int record, int index, double value) | |
{ | |
SetFieldValue(record, index, value.ToString()); | |
} | |
public void SetFieldDouble(int record, string fldName, double value) | |
{ | |
int idx = FieldIndex(fldName); | |
SetFieldValue(record, idx, value.ToString()); | |
} | |
public void SetFieldValue(int record, int index, string value) | |
{ | |
if (record < 0 || record > RecordCount) | |
{ | |
throw new Exception(IndexRangeError); | |
} | |
else if (index < 0 || index > FieldCount) | |
{ | |
throw new Exception(IndexRangeError); | |
} | |
else if (value.Length > Fields[index].Length) | |
{ | |
throw new Exception("Value Exceeds Field Length"); | |
} | |
{ | |
_Records[record][index] = value; | |
} | |
} | |
public void SetFieldValue(int record, string fldName, string value) | |
{ | |
int idx = FieldIndex(fldName); | |
SetFieldValue(record, idx, value); | |
} | |
public string GetFieldName(int index) | |
{ | |
if (index < 0 || index > FieldCount) | |
{ | |
throw new Exception(IndexRangeError); | |
} | |
return Fields[index].Name; | |
} | |
public int GetFieldLength(int index) | |
{ | |
if (index < 0 || index > FieldCount) | |
{ | |
throw new Exception(IndexRangeError); | |
} | |
return Fields[index].Length; | |
} | |
public int GetFieldLength(string fldName) | |
{ | |
int idx = FieldIndex(fldName); | |
return GetFieldLength(idx); | |
} | |
public int FindRecord(int index, string Term) | |
{ | |
int r_idx = (-1); | |
if (index < 0 || index > FieldCount) | |
{ | |
throw new Exception(IndexRangeError); | |
} | |
//Loop though the records | |
for (int x = 0; x < RecordCount; x++) | |
{ | |
//Check the record field value is the same as Term | |
if (_Records[x][index].Equals(Term, StringComparison.OrdinalIgnoreCase)) | |
{ | |
r_idx = x; | |
break; | |
} | |
} | |
return r_idx; | |
} | |
public int FindRecord(string fldName, string Term) | |
{ | |
int idx = FieldIndex(fldName); | |
return FindRecord(idx, Term); | |
} | |
public void SortRecords(int index) | |
{ | |
if (index < 0 || index > FieldCount) | |
{ | |
throw new Exception(IndexRangeError); | |
} | |
//Loop though all the records | |
for (int i = 0; i < RecordCount; i++) | |
{ | |
for (int j = i + 1; j < RecordCount; j++) | |
{ | |
if (string.Compare(_Records[i][index], _Records[j][index], true) > 0) | |
{ | |
var k = _Records[i]; | |
_Records[i] = _Records[j]; | |
_Records[j] = k; | |
} | |
} | |
} | |
} | |
public void SortRecords(string SortField) | |
{ | |
int idx = FieldIndex(SortField); | |
SortRecords(idx); | |
} | |
public void DeleteRecord(int index) | |
{ | |
if (index < 0 || index > RecordCount) | |
{ | |
throw new Exception(IndexRangeError); | |
} | |
try | |
{ | |
//Delete the record | |
_Records.RemoveAt(index); | |
} | |
catch (Exception ex) | |
{ | |
throw new Exception(ex.Message); | |
} | |
} | |
public void DeleteAllRecords() | |
{ | |
try | |
{ | |
_Records.Clear(); | |
} | |
catch (Exception ex) | |
{ | |
throw new Exception(ex.Message); | |
} | |
} | |
public void DeleteField(int index) | |
{ | |
List<string> vals; | |
//Check for index out of range | |
if (index < 0 || index > FieldCount) | |
{ | |
throw new Exception(IndexRangeError); | |
} | |
//Sort the records | |
for (int x = 0; x < RecordCount; x++) | |
{ | |
//Get record. | |
vals = _Records[x]; | |
//Delete the value at the index level | |
vals.RemoveAt(index); | |
//Set the record | |
_Records[x] = vals; | |
} | |
//Delete the field name | |
Fields.RemoveAt(index); | |
} | |
public void DeleteField(string fldName) | |
{ | |
int idx = FieldIndex(fldName); | |
//Delete the field. | |
DeleteField(idx); | |
} | |
public void LoadDb(string Filename) | |
{ | |
string[] Lines; | |
int ln = 0; | |
string[] fldLine; | |
List<string> values; | |
List<FieldDef> elms = new List<FieldDef>(); | |
FieldDef fi; | |
bool IsFirstLine = true; | |
string sLine = string.Empty; | |
//Load the whole file. | |
_Records = new List<List<string>>(); | |
Fields = new List<FieldDef>(); | |
//Set db filename | |
dbFilename = Filename; | |
if (!File.Exists(dbFilename)) | |
{ | |
throw new FileNotFoundException("File Was Not Found:\n" + | |
Filename); | |
} | |
try | |
{ | |
Lines = File.ReadAllLines(dbFilename); | |
while (ln < Lines.Length) | |
{ | |
sLine = Lines[ln]; | |
if (sLine.Trim().Length == 0) | |
{ | |
continue; | |
} | |
else | |
{ | |
//Get very first line this is the fields description | |
if (IsFirstLine) | |
{ | |
fldLine = sLine.Split('|'); | |
//Get the field name and field length | |
foreach (string fld in fldLine) | |
{ | |
string[] fInfo = fld.Split(':'); | |
fi.Name = fInfo[0]; | |
fi.Length = Convert.ToInt32(fInfo[1]); | |
//Add the field description | |
elms.Add(fi); | |
} | |
//Add the fields. | |
NewTable(elms); | |
//Clear array | |
elms = new List<FieldDef>(); | |
Array.Clear(fldLine, 0, fldLine.Length); | |
//Set first line to false. | |
IsFirstLine = false; | |
} | |
else | |
{ | |
//Get values | |
values = Get_FieldValues(sLine); | |
//Add records | |
_Records.Add(values); | |
} | |
} | |
//INC line counter | |
ln++; | |
} | |
} | |
catch (Exception ex) | |
{ | |
throw new Exception(ex.Message); | |
} | |
//Clear lines | |
Array.Clear(Lines, 0, Lines.Length); | |
} | |
public void UpdateDb() | |
{ | |
if (dbFilename.Length.Equals(0)) | |
{ | |
return; | |
} | |
if (File.Exists(dbFilename)) | |
{ | |
SaveDb(dbFilename); | |
} | |
} | |
public void SaveDb(string Filename) | |
{ | |
StringBuilder sb = new StringBuilder(); | |
string sLine = string.Empty; | |
string fldValue = string.Empty; | |
//Add fields | |
foreach (FieldDef fi in Fields) | |
{ | |
sLine += fi.Name + ":" + fi.Length.ToString() + "|"; | |
//Add to string builder | |
} | |
//Trim last | | |
sLine = sLine.TrimEnd('|'); | |
sb.AppendLine(sLine); | |
//Clear string | |
sLine = string.Empty; | |
//Append records. | |
for (int x = 0; x < RecordCount; x++) | |
{ | |
for (int y = 0; y < FieldCount; y++) | |
{ | |
//Get field value | |
fldValue = _Records[x][y]; | |
fldValue = _FixValueSize(fldValue, fldValue.Length, Fields[y].Length); | |
fldValue = StringPadRight(fldValue, Fields[y].Length); | |
//Set the line to be added to the string collection. | |
sLine += fldValue; | |
} | |
//Append to string builder | |
sb.AppendLine(sLine); | |
//Clear string | |
sLine = string.Empty; | |
} | |
try | |
{ | |
//Write string builder to file. | |
File.WriteAllText(Filename, sb.ToString()); | |
//Clear the string builder object | |
sb.Clear(); | |
} | |
catch (Exception ex) | |
{ | |
throw new Exception(ex.Message); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment