Add three new example scripts demonstrating the fswatch, sysinfo, and udp modules with file watching, system metrics, and UDP echo server/client patterns. Reorder the manual API sidebar navigation to list modules alphabetically, removing deprecated entries like websocket, tls, net, json, regex, jinja, os, signal, subprocess, sqlite, and timer while adding argparse, dataset, fswatch, and html.
408 lines
18 KiB
HTML
408 lines
18 KiB
HTML
<!DOCTYPE html>
|
|
<!-- retoor <retoor@molodetz.nl> -->
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>dataset - Wren-CLI Manual</title>
|
|
<link rel="stylesheet" href="../css/style.css">
|
|
</head>
|
|
<body>
|
|
<button class="mobile-menu-toggle">Menu</button>
|
|
<div class="container">
|
|
<aside class="sidebar">
|
|
<div class="sidebar-header">
|
|
<h1><a href="../index.html">Wren-CLI</a></h1>
|
|
<div class="version">v0.4.0</div>
|
|
</div>
|
|
<nav class="sidebar-nav">
|
|
<div class="section">
|
|
<span class="section-title">Getting Started</span>
|
|
<ul>
|
|
<li><a href="../getting-started/index.html">Overview</a></li>
|
|
<li><a href="../getting-started/installation.html">Installation</a></li>
|
|
<li><a href="../getting-started/first-script.html">First Script</a></li>
|
|
<li><a href="../getting-started/repl.html">Using the REPL</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="section">
|
|
<span class="section-title">Language</span>
|
|
<ul>
|
|
<li><a href="../language/index.html">Syntax Overview</a></li>
|
|
<li><a href="../language/classes.html">Classes</a></li>
|
|
<li><a href="../language/methods.html">Methods</a></li>
|
|
<li><a href="../language/control-flow.html">Control Flow</a></li>
|
|
<li><a href="../language/fibers.html">Fibers</a></li>
|
|
<li><a href="../language/modules.html">Modules</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="section">
|
|
<span class="section-title">API Reference</span>
|
|
<ul>
|
|
<li><a href="index.html">Overview</a></li>
|
|
<li><a href="string.html">String</a></li>
|
|
<li><a href="number.html">Num</a></li>
|
|
<li><a href="argparse.html">argparse</a></li>
|
|
<li><a href="base64.html">base64</a></li>
|
|
<li><a href="crypto.html">crypto</a></li>
|
|
<li><a href="dataset.html" class="active">dataset</a></li>
|
|
<li><a href="datetime.html">datetime</a></li>
|
|
<li><a href="dns.html">dns</a></li>
|
|
<li><a href="env.html">env</a></li>
|
|
<li><a href="fswatch.html">fswatch</a></li>
|
|
<li><a href="html.html">html</a></li>
|
|
<li><a href="http.html">http</a></li>
|
|
<li><a href="io.html">io</a></li>
|
|
<li><a href="jinja.html">jinja</a></li>
|
|
<li><a href="json.html">json</a></li>
|
|
<li><a href="markdown.html">markdown</a></li>
|
|
<li><a href="math.html">math</a></li>
|
|
<li><a href="net.html">net</a></li>
|
|
<li><a href="os.html">os</a></li>
|
|
<li><a href="pathlib.html">pathlib</a></li>
|
|
<li><a href="regex.html">regex</a></li>
|
|
<li><a href="scheduler.html">scheduler</a></li>
|
|
<li><a href="signal.html">signal</a></li>
|
|
<li><a href="sqlite.html">sqlite</a></li>
|
|
<li><a href="subprocess.html">subprocess</a></li>
|
|
<li><a href="sysinfo.html">sysinfo</a></li>
|
|
<li><a href="tempfile.html">tempfile</a></li>
|
|
<li><a href="timer.html">timer</a></li>
|
|
<li><a href="tls.html">tls</a></li>
|
|
<li><a href="udp.html">udp</a></li>
|
|
<li><a href="uuid.html">uuid</a></li>
|
|
<li><a href="wdantic.html">wdantic</a></li>
|
|
<li><a href="web.html">web</a></li>
|
|
<li><a href="websocket.html">websocket</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="section">
|
|
<span class="section-title">Tutorials</span>
|
|
<ul>
|
|
<li><a href="../tutorials/index.html">Tutorial List</a></li>
|
|
<li><a href="../tutorials/http-client.html">HTTP Client</a></li>
|
|
<li><a href="../tutorials/websocket-chat.html">WebSocket Chat</a></li>
|
|
<li><a href="../tutorials/database-app.html">Database App</a></li>
|
|
<li><a href="../tutorials/template-rendering.html">Templates</a></li>
|
|
<li><a href="../tutorials/cli-tool.html">CLI Tool</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="section">
|
|
<span class="section-title">How-To Guides</span>
|
|
<ul>
|
|
<li><a href="../howto/index.html">How-To List</a></li>
|
|
<li><a href="../howto/http-requests.html">HTTP Requests</a></li>
|
|
<li><a href="../howto/json-parsing.html">JSON Parsing</a></li>
|
|
<li><a href="../howto/regex-patterns.html">Regex Patterns</a></li>
|
|
<li><a href="../howto/file-operations.html">File Operations</a></li>
|
|
<li><a href="../howto/async-operations.html">Async Operations</a></li>
|
|
<li><a href="../howto/error-handling.html">Error Handling</a></li>
|
|
</ul>
|
|
</div>
|
|
</nav>
|
|
</aside>
|
|
<main class="content">
|
|
<nav class="breadcrumb">
|
|
<a href="../index.html">Home</a>
|
|
<span class="separator">/</span>
|
|
<a href="index.html">API Reference</a>
|
|
<span class="separator">/</span>
|
|
<span>dataset</span>
|
|
</nav>
|
|
|
|
<article>
|
|
<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>
|
|
</article>
|
|
|
|
<footer class="page-footer">
|
|
<a href="wdantic.html" class="prev">wdantic</a>
|
|
<a href="markdown.html" class="next">markdown</a>
|
|
</footer>
|
|
</main>
|
|
</div>
|
|
<script src="../js/main.js"></script>
|
|
</body>
|
|
</html>
|