docs: add dataset ORM tutorial page and update navigation with GFM documentation
Add new Dataset ORM tutorial page covering CRUD operations, query operators, schema evolution, and JSON field handling. Update navigation.yaml to include the new tutorial in the tutorials section. Enhance markdown module documentation with GitHub Flavored Markdown support details including tables, task lists, and language identifier attributes for syntax highlighting. Update tutorial index page and pagination links to reflect the new tutorial order. Refactor dataset.wren module source to introduce Sql and QueryBuilder classes with soft-delete support and identifier validation.
This commit is contained in:
Vendored
+37
@@ -0,0 +1,37 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "dataset" for Dataset
|
||||
|
||||
var ds = Dataset.memory()
|
||||
var products = ds["products"]
|
||||
|
||||
for (i in 1..50) {
|
||||
products.insert({
|
||||
"name": "Product %(i)",
|
||||
"price": i * 10,
|
||||
"category": i % 3 == 0 ? "A" : (i % 3 == 1 ? "B" : "C"),
|
||||
"active": i % 2 == 0
|
||||
})
|
||||
}
|
||||
|
||||
System.print(products.count()) // expect: 50
|
||||
|
||||
var expensive = products.find({"price__gte": 400})
|
||||
System.print(expensive.count) // expect: 11
|
||||
|
||||
var categoryA = products.find({"category": "A"})
|
||||
System.print(categoryA.count) // expect: 16
|
||||
|
||||
var combined = products.find({"price__gte": 200, "price__lte": 300, "category": "B"})
|
||||
System.print(combined.count) // expect: 3
|
||||
|
||||
var inList = products.find({"name__in": ["Product 1", "Product 10", "Product 50"]})
|
||||
System.print(inList.count) // expect: 3
|
||||
|
||||
var like = products.find({"name__like": "Product 1\%"})
|
||||
System.print(like.count) // expect: 11
|
||||
|
||||
var notEqual = products.find({"category__ne": "A", "active": true})
|
||||
System.print(notEqual.count) // expect: 17
|
||||
|
||||
ds.close()
|
||||
Vendored
+25
@@ -0,0 +1,25 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "dataset" for Dataset
|
||||
|
||||
var ds = Dataset.memory()
|
||||
|
||||
var fiber = Fiber.new {
|
||||
var table = ds["users; DROP TABLE users; --"]
|
||||
}
|
||||
fiber.try()
|
||||
System.print(fiber.error != null) // expect: true
|
||||
|
||||
var users = ds["users"]
|
||||
users.insert({"name": "Alice"})
|
||||
|
||||
var fiber2 = Fiber.new {
|
||||
users.insert({"field; DROP TABLE": "value"})
|
||||
}
|
||||
fiber2.try()
|
||||
System.print(fiber2.error != null) // expect: true
|
||||
|
||||
var all = users.all()
|
||||
System.print(all.count) // expect: 1
|
||||
|
||||
ds.close()
|
||||
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "dataset" for Dataset
|
||||
import "tempfile" for TempFile
|
||||
import "io" for File
|
||||
|
||||
var path = TempFile.mkstemp(".db")
|
||||
var ds = Dataset.open(path)
|
||||
|
||||
var users = ds["users"]
|
||||
users.insert({"name": "Alice"})
|
||||
|
||||
var result = users.find({"nonexistent": "value"})
|
||||
System.print(result.count) // expect: 0
|
||||
|
||||
var one = users.findOne({"missing_col": "test"})
|
||||
System.print(one == null) // expect: true
|
||||
|
||||
var all = users.all()
|
||||
System.print(all.count) // expect: 1
|
||||
|
||||
ds.close()
|
||||
File.delete(path)
|
||||
Vendored
+29
@@ -0,0 +1,29 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "dataset" for Dataset
|
||||
|
||||
var ds = Dataset.memory()
|
||||
var users = ds["users"]
|
||||
|
||||
var u1 = users.insert({"name": "Alice"})
|
||||
System.print(users.columns.containsKey("name")) // expect: true
|
||||
System.print(users.columns.containsKey("email")) // expect: false
|
||||
|
||||
var u2 = users.insert({"name": "Bob", "email": "bob@example.com"})
|
||||
System.print(users.columns.containsKey("email")) // expect: true
|
||||
|
||||
var u3 = users.insert({"name": "Charlie", "age": 30, "score": 95.5})
|
||||
System.print(users.columns.containsKey("age")) // expect: true
|
||||
System.print(users.columns.containsKey("score")) // expect: true
|
||||
|
||||
var alice = users.findOne({"name": "Alice"})
|
||||
System.print(alice["email"] == null) // expect: true
|
||||
|
||||
users.update({"uid": u1["uid"], "email": "alice@example.com", "verified": true})
|
||||
var aliceUpdated = users.findOne({"name": "Alice"})
|
||||
System.print(aliceUpdated["email"]) // expect: alice@example.com
|
||||
System.print(users.columns.containsKey("verified")) // expect: true
|
||||
|
||||
System.print(users.count()) // expect: 3
|
||||
|
||||
ds.close()
|
||||
Vendored
+20
@@ -0,0 +1,20 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "dataset" for Dataset
|
||||
|
||||
var ds = Dataset.memory()
|
||||
var users = ds["users"]
|
||||
|
||||
users.insert({"name": "Alice", "score": 100})
|
||||
users.insert({"name": "Bob'; DROP TABLE users; --", "score": 50})
|
||||
|
||||
var all = users.all()
|
||||
System.print(all.count) // expect: 2
|
||||
|
||||
var found = users.findOne({"name": "Bob'; DROP TABLE users; --"})
|
||||
System.print(found["score"]) // expect: 50
|
||||
|
||||
var afterAttack = users.all()
|
||||
System.print(afterAttack.count) // expect: 2
|
||||
|
||||
ds.close()
|
||||
Reference in New Issue
Block a user