2026-01-26 05:12:14 +01:00
{# retoor < retoor @ molodetz . nl > #}
{% extends 'page.html' %}
2026-01-25 02:47:47 +01:00
2026-01-26 05:12:14 +01:00
{% set page_title = "dataset" %}
{% set breadcrumb = [{"url": "api/index.html", "title": "API Reference"}, {"title": "dataset"}] %}
{% set prev_page = {"url": "api/wdantic.html", "title": "wdantic"} %}
{% set next_page = {"url": "api/markdown.html", "title": "markdown"} %}
{% block article %}
2026-01-25 02:47:47 +01:00
< h1 > dataset</ h1 >
< p > The < code > dataset</ code > module provides a simple ORM-like interface for SQLite databases with automatic schema management. Tables and columns are created automatically as you insert data.</ p >
< pre >< code > import "dataset" for Dataset, Table</ code ></ pre >
< h2 > Dataset Class</ h2 >
< div class = "class-header" >
< h3 > Dataset</ h3 >
< p > Database connection and table access</ p >
</ div >
< h3 > Constructors</ h3 >
< div class = "method-signature" >
< span class = "method-name" > Dataset.open</ span > (< span class = "param" > path</ span > ) → < span class = "type" > Dataset</ span >
</ div >
< p > Opens or creates a SQLite database file.</ p >
< ul class = "param-list" >
< li >< span class = "param-name" > path</ span > < span class = "param-type" > (String)</ span > - Path to the database file</ li >
</ ul >
< pre >< code > var db = Dataset.open("data.db")</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > Dataset.memory</ span > () → < span class = "type" > Dataset</ span >
</ div >
< p > Creates an in-memory database (data is lost when closed).</ p >
< pre >< code > var db = Dataset.memory()</ code ></ pre >
< h3 > Properties</ h3 >
< div class = "method-signature" >
< span class = "method-name" > db</ span > → < span class = "type" > Database</ span >
</ div >
< p > Access to the underlying SQLite database for raw queries.</ p >
< div class = "method-signature" >
< span class = "method-name" > tables</ span > → < span class = "type" > List</ span >
</ div >
< p > List of table names in the database.</ p >
< h3 > Subscript Access</ h3 >
< div class = "method-signature" >
< span class = "method-name" > [tableName]</ span > → < span class = "type" > Table</ span >
</ div >
< p > Gets a table by name. Creates the table if it does not exist on first insert.</ p >
< pre >< code > var users = db["users"]</ code ></ pre >
< h3 > Instance Methods</ h3 >
< div class = "method-signature" >
< span class = "method-name" > close</ span > ()
</ div >
< p > Closes the database connection.</ p >
< h2 > Table Class</ h2 >
< div class = "class-header" >
< h3 > Table</ h3 >
< p > CRUD operations on a database table</ p >
</ div >
< h3 > Properties</ h3 >
< div class = "method-signature" >
< span class = "method-name" > name</ span > → < span class = "type" > String</ span >
</ div >
< p > The table name.</ p >
< div class = "method-signature" >
< span class = "method-name" > columns</ span > → < span class = "type" > Map</ span >
</ div >
< p > Map of column names to SQL types.</ p >
< h3 > Instance Methods</ h3 >
< div class = "method-signature" >
< span class = "method-name" > insert</ span > (< span class = "param" > record</ span > ) → < span class = "type" > Map</ span >
</ div >
< p > Inserts a record and returns it with generated < code > uid</ code > and < code > created_at</ code > .</ p >
< ul class = "param-list" >
< li >< span class = "param-name" > record</ span > < span class = "param-type" > (Map)</ span > - Data to insert</ li >
< li >< span class = "returns" > Returns:</ span > Inserted record with uid and created_at</ li >
</ ul >
< pre >< code > var user = db["users"].insert({
"name": "Alice",
"email": "alice@example.com"
})
System.print(user["uid"]) // auto-generated UUID</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > update</ span > (< span class = "param" > record</ span > ) → < span class = "type" > Num</ span >
</ div >
< p > Updates a record by uid. Returns number of rows affected.</ p >
< ul class = "param-list" >
< li >< span class = "param-name" > record</ span > < span class = "param-type" > (Map)</ span > - Must contain < code > uid</ code > and fields to update</ li >
</ ul >
< pre >< code > db["users"].update({
"uid": "550e8400-e29b-41d4-a716-446655440000",
"name": "Alice Smith"
})</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > delete</ span > (< span class = "param" > uid</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Soft deletes a record (sets < code > deleted_at</ code > timestamp). Returns true if record was deleted.</ p >
< pre >< code > db["users"].delete("550e8400-e29b-41d4-a716-446655440000")</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > hardDelete</ span > (< span class = "param" > uid</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Permanently deletes a record from the database.</ p >
< div class = "method-signature" >
< span class = "method-name" > find</ span > (< span class = "param" > conditions</ span > ) → < span class = "type" > List</ span >
</ div >
< p > Finds records matching conditions. Returns list of records (excludes soft-deleted).</ p >
< pre >< code > var admins = db["users"].find({"role": "admin"})</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > findOne</ span > (< span class = "param" > conditions</ span > ) → < span class = "type" > Map|null</ span >
</ div >
< p > Finds first record matching conditions or null.</ p >
< pre >< code > var user = db["users"].findOne({"email": "alice@example.com"})</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > all</ span > () → < span class = "type" > List</ span >
</ div >
< p > Returns all non-deleted records.</ p >
< div class = "method-signature" >
< span class = "method-name" > count</ span > () → < span class = "type" > Num</ span >
</ div >
< p > Returns count of non-deleted records.</ p >
< h2 > Query Operators</ h2 >
< p > Use suffixes in condition keys for comparison operators:</ p >
< table >
< tr >
< th > Suffix</ th >
< th > SQL Operator</ th >
< th > Example</ th >
</ tr >
< tr >
< td >< code > __gt</ code ></ td >
< td > > </ td >
< td >< code > {"age__gt": 18}</ code ></ td >
</ tr >
< tr >
< td >< code > __lt</ code ></ td >
< td > < </ td >
< td >< code > {"price__lt": 100}</ code ></ td >
</ tr >
< tr >
< td >< code > __gte</ code ></ td >
< td > > =</ td >
< td >< code > {"score__gte": 90}</ code ></ td >
</ tr >
< tr >
< td >< code > __lte</ code ></ td >
< td > < =</ td >
< td >< code > {"score__lte": 100}</ code ></ td >
</ tr >
< tr >
< td >< code > __ne</ code ></ td >
< td > !=</ td >
< td >< code > {"status__ne": "deleted"}</ code ></ td >
</ tr >
< tr >
< td >< code > __like</ code ></ td >
< td > LIKE</ td >
< td >< code > {"name__like": "A\%"}</ code ></ td >
</ tr >
< tr >
< td >< code > __in</ code ></ td >
< td > IN</ td >
< td >< code > {"status__in": ["active", "pending"]}</ code ></ td >
</ tr >
< tr >
< td >< code > __null</ code ></ td >
< td > IS NULL / IS NOT NULL</ td >
< td >< code > {"deleted_at__null": true}</ code ></ td >
</ tr >
</ table >
< h2 > Automatic Features</ h2 >
< h3 > Auto-Generated Fields</ h3 >
< ul >
< li >< code > uid</ code > - UUID v4 primary key (auto-generated if not provided)</ li >
< li >< code > created_at</ code > - ISO timestamp (auto-generated on insert)</ li >
< li >< code > deleted_at</ code > - ISO timestamp (set by soft delete)</ li >
</ ul >
< h3 > Auto Schema</ h3 >
< ul >
< li > Tables are created automatically on first insert</ li >
< li > Columns are added automatically when new fields appear</ li >
< li > Type inference: Num → INTEGER/REAL, Bool → INTEGER, Map/List → TEXT (JSON)</ li >
</ ul >
< h3 > JSON Serialization</ h3 >
< p > Maps and Lists are automatically serialized to JSON when stored and deserialized when retrieved.</ p >
< h2 > Examples</ h2 >
< h3 > Basic CRUD</ h3 >
< pre >< code > import "dataset" for Dataset
var db = Dataset.open("app.db")
var users = db["users"]
var user = users.insert({
"name": "Alice",
"email": "alice@example.com",
"settings": {"theme": "dark", "notifications": true}
})
System.print("Created user: %(user["uid"])")
users.update({
"uid": user["uid"],
"name": "Alice Smith"
})
var found = users.findOne({"email": "alice@example.com"})
System.print("Found: %(found["name"])")
users.delete(user["uid"])
db.close()</ code ></ pre >
< h3 > Querying with Operators</ h3 >
< pre >< code > import "dataset" for Dataset
var db = Dataset.open("products.db")
var products = db["products"]
var expensive = products.find({"price__gt": 100})
var cheap = products.find({"price__lte": 10})
var search = products.find({"name__like": "\%phone\%"})
var featured = products.find({
"category__in": ["electronics", "gadgets"],
"stock__gt": 0
})
db.close()</ code ></ pre >
< h3 > Working with JSON Data</ h3 >
< pre >< code > import "dataset" for Dataset
var db = Dataset.memory()
db["posts"].insert({
"title": "First Post",
"tags": ["wren", "programming", "tutorial"],
"metadata": {
"author": "Alice",
"views": 100,
"featured": true
}
})
var post = db["posts"].findOne({"title": "First Post"})
System.print(post["tags"]) // ["wren", "programming", "tutorial"]
System.print(post["metadata"]) // {"author": "Alice", ...}</ code ></ pre >
< div class = "admonition note" >
< div class = "admonition-title" > Note</ div >
< p > Soft delete is the default behavior. Records are not permanently removed but marked with a < code > deleted_at</ code > timestamp. Use < code > hardDelete()</ code > for permanent removal. All query methods automatically exclude soft-deleted records.</ p >
</ div >
< div class = "admonition warning" >
< div class = "admonition-title" > Warning</ div >
< p > The < code > uid</ code > field is the primary key. Do not use < code > id</ code > as a field name. If you provide a < code > uid</ code > during insert, it will be used instead of auto-generating one.</ p >
</ div >
2026-01-26 05:12:14 +01:00
{% endblock %}