BijouDB 2.0.0
prior version has a bug where the first record ever created has an invalid id and thus doesn't get properly created.
See the version list below for details.
dotnet add package BijouDB --version 2.0.0
NuGet\Install-Package BijouDB -Version 2.0.0
<PackageReference Include="BijouDB" Version="2.0.0" />
paket add BijouDB --version 2.0.0
#r "nuget: BijouDB, 2.0.0"
// Install BijouDB as a Cake Addin
#addin nuget:?package=BijouDB&version=2.0.0
// Install BijouDB as a Cake Tool
#tool nuget:?package=BijouDB&version=2.0.0
BijouDB
A small C# database
Nuget: BijouDB Package
Features
DataTypes ⇒ Synonymous Wrapper
BigInteger => @bint
byte[] => @blob
bool => @bool
byte => @byte
char => @char
DateTime => @time
decimal => @decimal
float => @float
int => @int
long => @long
R : BijouDB.Record => @record<R>
sbyte => @sbyte
short => @short
string => @string
uint => @uint
ulong => @ulong
ushort => @ushort
Tuple<T1, T2> => @tuple<D1, D2>
Tuple<T1, T2, T3> => @tuple<D1, D2, D3>
Tuple<T1, T2, T3, T4> => @tuple<D1, D2, D3, D4>
Tuple<T1, T2, T3, T4, T5> => @tuple<D1, D2, D3, D4, D5>
Tuple<T1, T2, T3, T4, T5, T6> => @tuple<D1, D2, D3, D4, D5, D6>
Tuple<T1, T2, T3, T4, T5, T6, T7> => @tuple<D1, D2, D3, D4, D5, D6, D7>
Tuple<T1, T2, T3, T4, T5, T6, T7, TRest> => @tuple<D1, D2, D3, D4, D5, D6, D7, DRest>
Nullable Types:
BigInteger? => @bint.nullable
byte[]? => @blob.nullable
bool? => @bool.nullable
byte? => @byte.nullable
char? => @char.nullable
DateTime? => @time.nullable
decimal? => @decimal.nullable
float? => @float.nullable
int? => @int.nullable
long? => @long.nullable
R? : BijouDB.Record => @record<R>.nullable
sbyte? => @sbyte.nullable
short? => @short.nullable
string? => @string.nullable
uint? => @uint.nullable
ulong? => @ulong.nullable
ushort? => @ushort.nullable
Tuple<T1, T2>? => @tuple<D1, D2>.nullable
Tuple<T1, T2, T3>? => @tuple<D1, D2, D3>.nullable
Tuple<T1, T2, T3, T4>? => @tuple<D1, D2, D3, D4>.nullable
Tuple<T1, T2, T3, T4, T5>? => @tuple<D1, D2, D3, D4, D5>.nullable
Tuple<T1, T2, T3, T4, T5, T6>? => @tuple<D1, D2, D3, D4, D5, D6>.nullable
Tuple<T1, T2, T3, T4, T5, T6, T7>? => @tuple<D1, D2, D3, D4, D5, D6, D7>.nullable
Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>? => @tuple<D1, D2, D3, D4, D5, D6, D7, DRest>.nullable
Constraints
Unique
Ensures that a column has all unique values
Default
Specifies a default for any values that arent set
Check
Specifies a condition for a value to be set
NotNull is the default, use a
IDataType.nullable
to explicitly use null
PRIMARY KEY and FOREIGN KEY is replicated loosely with
References
Custom DataTypes
You can create your own data types by implementing the interface BijouDB.IDataType
public interface IDataType
{
// The logic to convert from bytes
public void Deserialize(Stream stream);
// The logic to convert to bytes
public void Serialize(Stream stream);
}
Usage
To get started simply create a new class which inherits from BijouDB.Record
.
Create a static readonly field to act as a column, specify a BijouDB datatype.
As a convention, the column should end in Column
.
Create a new property with the respectice type of the column.
The get accessor should call the column you just made's Get()
method, passing in this
as an argument.
The set accessor should call the column's Set()
method, passing in this
and value
as arguments.
Create a static contructor, its needed to instantiate the columns.
Use the SchemaBuilder to generate the columns via the Add()
method.
Do this for each of your columns and finally preceed the SchemaBuilder with _ = ~
.
This pattern automatically disposes the SchemaBuilder at the end and ensures proper init and disposal.
Example
using BijouDB;
using BijouDB.DataTypes;
public class MyRecord : Record
{
public static readonly Column<@int> AgeColumn;
public int Age { get => AgeColumn.Get(this); set => AgeColumn.Set(this, value); }
static MyRecord() => _ = ~SchemaBuilder<MyRecord>
.Add(out AgeColumn);
}
Specifying Constraints
Use the SchemaBuilder to add constraints to your columns.
Place the constraints on any column by using the Add()
method.
Provide the label for the constraint Unique:
or Default:
or Check:
followed by the value for the constraint.
The order does't matter and you don't have to provide every constraint.
using BijouDB;
using BijouDB.DataTypes;
public class MyRecord : Record
{
public static readonly Column<@int> AgeColumn;
public int Age { get => AgeColumn.Get(this); set => AgeColumn.Set(this, value); }
static MyRecord() => _ = ~SchemaBuilder<MyRecord>
// Specify that the column is NOT unique
// Specify that valid values must be 18 or larger
// Specify that the default value is 18
.Add(out AgeColumn, Unique: false, Check: value => value >= 18, Default: () => 18);
}
References
In SQL we have the notion of PRIMARY KEY
and FOREIGN KEY
to link relationships between tables.
Here we have the concept of References. Its very similar in concept.
References prevent a Record from being deleted if it has references.
You can keep the relationship but allow deleting even if referenced exist by setting the restricted
parameter to false in the Add( ... , bool restricted)
method for references, default is true.
You can create a Reference
specifying the Record
it references and the generic type of that column.
As a convention you should end the field with References
.
Create a property with the type of the referenced Record. This property should be an array []
.
Use the For()
method passing in this
.
You then use an overload for the Add()
method for References. References do NOT have contraints.
Instead you have to specifically point it to the column in the referenced Record.
using BijouDB;
using BijouDB.DataTypes;
public class Employee : Record
{
public static readonly Column<@string> NameColumn;
public string Name { get => NameColumn.Get(this); set => NameColumn.Set(this, value); }
public static readonly Column<@int> AgeColumn;
public int Age { get => AgeColumn.Get(this); set => AgeColumn.Set(this, value); }
// A Reference to 'Computer' Record
public static readonly References<Computer, @record<Employee>> ComputerReferences;
public Computer[] Computers => ComputerReferences.For(this);
static Employee() => _ = ~SchemaBuilder<Employee>
.Add(out NameColumn)
.Add(out AgeColumn, Unique: false, Check: value => value >= 18, Default: () => 18)
// Generates the Referennce, and points it to the 'EmployeeColumn' in 'Computer' Record
.Add(out ComputerReferences, () => Computer.EmployeeColumn);
}
public class Computer : Record
{
public static readonly Column<@record<Employee>> EmployeeColumn;
public Employee Employee { get => EmployeeColumn.Get(this); set => EmployeeColumn.Set(this, value); }
static Computer() => _ = ~SchemaBuilder<Computer>
.Add(out EmployeeColumn);
}
To access references of a record, call its respective property.
Employee employee = new()
{
Age = 30
};
Computer comp1 = new()
{
Employee = employee
};
foreach (Computer computer in employee.Computers)
{
// Manipulate the record here
}
Removing Records
All Records have the following methods to be removed from the database.
// Removes the Record from the database with no exception handling (you have to do so manually)
public void Remove();
// Tries the remove the Record from the database while suppressing any exceptions.
// true if successfully removed, otherwise false.
public bool TryRemove();
// Tries the remove the Record from the database.
// Exposes any Exception that might've thrown.
// true if successfully removed, otherwise false.
public bool TryRemove(out Exception? exception);
Getting Records
If you know the Type
and Id
(represented as a Guid
) use the BijouDB.Record.TryGet<R>( ... )
method.
public static bool TryGet<R>(Guid id, out R? record) { }
public static bool TryGet<R>(string id, out R? record) { }
// Example
// Get a single record via its Id
if (BijouDB.Record.TryGet("0e758669-33ee-847e-d0e8-f5e89cc2b5c2", out Employee? employee))
{
// Manipulate the record here
}
If you know only the Type
and wish to get all Records of that type you can use BijouDB.Record.GetAll<R>()
method.
public static R[] GetAll<R>() { }
// Example
// Gets all Employee records
foreach (Employee employee in BijouDB.Record.GetAll<Employee>())
{
// Manipulate the record here
}
If you know the Type
of the Record and the value to one of its columns you can call the Column's WithValue<R>( .. )
method.
public R[] WithValue<R>(D data) { }
// Example
// Gets all Employee records where the age is 19
foreach (Employee employee in Employee.AgeColumn.WithValue<Employee>(19))
{
// Manipulate the record here
}
If you know the Type and value of multiple columns then you use the previous method along side BijouDB.Record.WithValues()
to get all records matching the values you know.
public static R[] WithValues<R>(params R[][] columnMatches) { }
// Example
// Find Employees with the name 'TizzyT' and that are 30 years old
// Get all records with Name 'TizzyT'
Employee[] nameMatches = Employee.NameColumn.WithValue<Employee>("TizzyT");
// Get all records with age 30
Employee[] ageMatches = Employee.AgeColumn.WithValue<Employee>(30);
// Combine matches
foreach(Employee employee in Record.WithValues<Employee>(nameMatches, ageMatches))
{
// Manipulate record here
}
If you want to know what unique values a column has you can call the respective column's UniqueValues()
method.
This will give you an array of all unique values found in that column.
public D[] UniqueValues() { }
// Example
// Get a list of all unique ages in Employee.AgeColumn
foreach (int age in Employee.AgeColumn.UniqueValues())
{
// Manipulate the age here
}
Logging
There was very minimal effor put into logging. It is disabled by default.
To turn on logging, set BijouDB.Globals.Logging
to true
.
Operations Complexity
Getting a Record via its Id
O(1)
Getting all Records of a Type
O(1)
Getting all Records of a Type by value
O(1) - O(n)
Adding a Record
O(1)
Removing a Record
O(1)
Getting References
O(1) - O(n)
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated | |
---|---|---|---|
4.1.1.1 | 344 | 11/9/2022 | |
4.1.1 | 333 | 11/9/2022 | |
4.1.0.3 | 416 | 7/26/2022 | |
4.1.0.2 | 402 | 7/19/2022 | |
4.1.0.1 | 399 | 7/11/2022 | |
4.1.0 | 420 | 7/9/2022 | |
4.0.1.10 | 405 | 7/5/2022 | |
4.0.1.9-preview.0.0.2 | 144 | 7/4/2022 | |
4.0.1.9-preview | 169 | 7/3/2022 | |
4.0.1.8 | 406 | 6/29/2022 | |
4.0.1.7 | 399 | 6/29/2022 | |
4.0.1.6 | 419 | 6/23/2022 | |
4.0.1.5 | 411 | 6/23/2022 | |
4.0.1.4 | 432 | 6/22/2022 | |
4.0.1.3 | 424 | 6/22/2022 | |
4.0.1.2 | 409 | 6/22/2022 | |
4.0.1.1 | 403 | 6/21/2022 | |
4.0.1 | 401 | 6/20/2022 | |
4.0.0.8 | 405 | 6/20/2022 | |
4.0.0.7 | 404 | 6/20/2022 | |
4.0.0.6 | 396 | 6/19/2022 | |
4.0.0.5 | 392 | 6/19/2022 | |
4.0.0.4 | 398 | 6/19/2022 | |
4.0.0.3 | 398 | 6/19/2022 | |
4.0.0.2 | 418 | 6/19/2022 | |
4.0.0.1 | 397 | 6/18/2022 | |
4.0.0 | 392 | 6/15/2022 | |
3.2.3 | 420 | 6/4/2022 | |
3.2.2.2 | 449 | 5/30/2022 | |
3.2.1.2 | 448 | 5/29/2022 | |
3.2.1.1 | 429 | 5/29/2022 | |
3.2.1 | 466 | 5/29/2022 | |
3.2.0 | 486 | 5/27/2022 | |
3.1.0 | 461 | 5/26/2022 | |
3.0.0 | 457 | 5/22/2022 | |
2.5.1 | 477 | 5/19/2022 | |
2.5.0 | 452 | 5/18/2022 | |
2.4.0 | 449 | 5/18/2022 | |
2.3.2.1 | 453 | 5/18/2022 | |
2.3.1.1 | 458 | 5/17/2022 | |
2.3.1 | 458 | 5/17/2022 | |
2.3.0 | 453 | 5/17/2022 | |
2.2.0 | 470 | 5/16/2022 | |
2.1.0 | 477 | 5/15/2022 | |
2.0.0.1 | 459 | 5/15/2022 | |
2.0.0 | 468 | 5/15/2022 | |
1.1.1 | 506 | 5/14/2022 | |
1.1.0 | 485 | 5/14/2022 | |
1.0.0 | 498 | 5/14/2022 |