Databases
SQLite Database
According to the SQLite homepage, "SQLite is a software library that implements a self-contained, server-less, zero-configuration, transactional SQL database engine. SQLite is the most widely deployed SQL database engine in the world." SQLite lets you set up a database that resides entirely in a single file on a persistent storage device.
Needed .NET NuGet: Microsoft.Data.Sqlite. Python ships sqlite3 in the
standard library. C/C++ uses the SQLite amalgamation (link with
-lsqlite3).
The code below is a simple example that creates an SQLite database file.
- .NET
- Python
- C/C++
using Microsoft.Data.Sqlite;
var id = 1;
var dataFile = "sqltest.db";
//Create a new database file
using (var connection = new SqliteConnection($"Data Source={dataFile}")){
connection.Open();
var command = connection.CreateCommand();
//Create a new table
command.CommandText = "CREATE TABLE IF NOT EXISTS user (id INTEGER PRIMARY KEY, name TEXT)";
command.ExecuteNonQuery();
//Insert a new row
command.CommandText = "INSERT INTO user (name) VALUES ('World 1')";
command.ExecuteNonQuery();
//query the database
command.CommandText = @"SELECT name FROM user WHERE id = $id";
command.Parameters.AddWithValue("$id", id);
//print the result
using (var reader = command.ExecuteReader()){
while (reader.Read()){
var name = reader.GetString(0);
Console.WriteLine($"Hello, {name}!");
}
}
}
//delete the data file when done
FileInfo dbFile = new FileInfo(dataFile);
try{
if (dbFile.Exists){
dbFile.Delete();
}
}
catch(Exception ex){
Console.WriteLine("Unable to delete the data file"+ex.Message);
}
import os
import sqlite3
user_id = 1
data_file = "sqltest.db"
# Create a new database file
with sqlite3.connect(data_file) as connection:
cursor = connection.cursor()
# Create a new table
cursor.execute("CREATE TABLE IF NOT EXISTS user (id INTEGER PRIMARY KEY, name TEXT)")
# Insert a new row
cursor.execute("INSERT INTO user (name) VALUES ('World 1')")
# Query the database
cursor.execute("SELECT name FROM user WHERE id = :id", {"id": user_id})
# Print the result
for row in cursor.fetchall():
print(f"Hello, {row[0]}!")
# Delete the data file when done
try:
if os.path.exists(data_file):
os.remove(data_file)
except OSError as ex:
print("Unable to delete the data file" + str(ex))
// Link with -lsqlite3.
#include <cstdio>
#include <cstdlib>
#include <sqlite3.h>
int id = 1;
const char* dataFile = "sqltest.db";
sqlite3* db = nullptr;
sqlite3_open(dataFile, &db);
// Create a new table
sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS user (id INTEGER PRIMARY KEY, name TEXT)",
nullptr, nullptr, nullptr);
// Insert a new row
sqlite3_exec(db, "INSERT INTO user (name) VALUES ('World 1')",
nullptr, nullptr, nullptr);
// Query the database
sqlite3_stmt* stmt = nullptr;
sqlite3_prepare_v2(db, "SELECT name FROM user WHERE id = ?", -1, &stmt, nullptr);
sqlite3_bind_int(stmt, 1, id);
while (sqlite3_step(stmt) == SQLITE_ROW) {
const unsigned char* name = sqlite3_column_text(stmt, 0);
std::printf("Hello, %s!\n", name);
}
sqlite3_finalize(stmt);
sqlite3_close(db);
// Delete the data file when done
std::remove(dataFile);
More Info
Further details on SQLite can be found at the official SQLite website http://www.sqlite.org/
LiteDB Database
Often applications need a way to store unstructured or semi-structured data. Using a NonSQL database could be a solution.
Needed NuGet: LiteDB. LiteDB is a .NET library and has no direct Python or C/C++ port.
The code below is a simple example that creates an LiteDB database file. LiteDB offers several features that makes it useful for an embedded device.
- .NET
- Python
- C/C++
using LiteDB;
var dataFile = "SensorData.db";
// Open database (or create if doesn't exist)
using (var db = new LiteDatabase(dataFile)){
// Get a collection (or create, if doesn't exist)
var col = db.GetCollection<Sensor>("sensors");
// Create a new sensor instance
var sensor = new Sensor {
Name = "MEMS12",
ConfigValues = new string[] { "0x00", "0xAA" },
IsActive = true
};
// Insert new sensor document (Id will be auto-incremented)
col.Insert(sensor);
// Update a document inside a collection
sensor.Name = "MEMS13";
col.Update(sensor);
// Index document using document Name property
col.EnsureIndex(x => x.Name);
// Use LINQ to query documents (filter, sort, transform)
var results = col.Query()
.Where(x => x.Name.StartsWith("M"))
.OrderBy(x => x.Name)
.Select(x => new { x.Name, NameUpper = x.Name.ToUpper() })
.Limit(10)
.ToList();
foreach(var memsSensor in results){
Console.WriteLine(memsSensor.Name);
}
// Create an index on the ConfigValues property
col.EnsureIndex(x => x.ConfigValues);
// Query by config value
var r = col.FindOne(x => x.ConfigValues.Contains("0xAA"));
Console.WriteLine(r.Name);
}
//delete the data file when done
FileInfo dbFile = new FileInfo(dataFile);
try{
if (dbFile.Exists){
dbFile.Delete();
}
}
catch(Exception ex){
Console.WriteLine("Unable to delete the data file"+ex.Message);
}
//Define Sensor class
public class Sensor{
public int Id { get; set; }
public required string Name { get; set; }
public required string[] ConfigValues { get; set; }
public bool IsActive { get; set; }
}
LiteDB is a .NET-only database. For document-style storage on Python,
use TinyDB (pip install tinydb) or
stick to sqlite3 with JSON columns.
# Example sketch using TinyDB, installed via pip.
from tinydb import TinyDB, Query
db = TinyDB("SensorData.json")
sensors = db.table("sensors")
sensors.insert({
"Name": "MEMS12",
"ConfigValues": ["0x00", "0xAA"],
"IsActive": True,
})
Sensor = Query()
for s in sensors.search(Sensor.Name.matches("M.*")):
print(s["Name"])
LiteDB is a .NET-only database. For document-style storage on C/C++,
either store JSON in a SQLite column or use an embedded document store
such as UnQLite (link with -lunqlite).
// Sketch only: use SQLite with a JSON column, or an embedded document
// store such as UnQLite. See the SQLite sample above for the simpler
// path on Endpoint.
More Info
Further details on SQLite can be found at the official SQLite website http://www.litedb.org/