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:
2026-01-26 09:21:03 +00:00
parent 04e467e09b
commit d953925605
40 changed files with 3478 additions and 547 deletions
+37
View File
@@ -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()
+25
View File
@@ -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()
+23
View File
@@ -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)
+29
View File
@@ -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()
+20
View File
@@ -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()
+31
View File
@@ -0,0 +1,31 @@
// retoor <retoor@molodetz.nl>
import "markdown" for Markdown
var httpUrl = "Visit https://example.com for info"
var httpHtml = Markdown.toHtml(httpUrl)
System.print(httpHtml.contains("<a href=\"https://example.com\">https://example.com</a>")) // expect: true
var httpOnly = "Check http://test.org/path"
var httpOnlyHtml = Markdown.toHtml(httpOnly)
System.print(httpOnlyHtml.contains("<a href=\"http://test.org/path\">http://test.org/path</a>")) // expect: true
var email = "Contact user@example.com today"
var emailHtml = Markdown.toHtml(email)
System.print(emailHtml.contains("mailto:user@example.com")) // expect: true
System.print(emailHtml.contains(">user@example.com</a>")) // expect: true
var noAutolink = "[Link](https://example.com)"
var noAutolinkHtml = Markdown.toHtml(noAutolink)
var count = 0
var i = 0
while (i < noAutolinkHtml.count - 4) {
if (noAutolinkHtml[i...i+5] == "href=") count = count + 1
i = i + 1
}
System.print(count) // expect: 1
var multiUrl = "See https://a.com and https://b.com"
var multiHtml = Markdown.toHtml(multiUrl)
System.print(multiHtml.contains("href=\"https://a.com\"")) // expect: true
System.print(multiHtml.contains("href=\"https://b.com\"")) // expect: true
+1 -1
View File
@@ -14,7 +14,7 @@ System.print(multiQuote.contains("line 1")) // expect: true
System.print(multiQuote.contains("line 2")) // expect: true
var withLang = Markdown.toHtml("```wren\nSystem.print(\"hello\")\n```")
System.print(withLang.contains("<pre><code>")) // expect: true
System.print(withLang.contains("<pre><code class=\"language-wren\">")) // expect: true
System.print(withLang.contains("System.print")) // expect: true
var emptyBlock = Markdown.toHtml("```\n\n```")
+27
View File
@@ -0,0 +1,27 @@
// retoor <retoor@molodetz.nl>
import "markdown" for Markdown
var js = "```javascript\nconst x = 1;\n```"
var jsHtml = Markdown.toHtml(js)
System.print(jsHtml.contains("class=\"language-javascript\"")) // expect: true
System.print(jsHtml.contains("const x = 1;")) // expect: true
var py = "```python\ndef foo():\n pass\n```"
var pyHtml = Markdown.toHtml(py)
System.print(pyHtml.contains("class=\"language-python\"")) // expect: true
System.print(pyHtml.contains("def foo():")) // expect: true
var noLang = "```\nplain code\n```"
var noLangHtml = Markdown.toHtml(noLang)
System.print(noLangHtml.contains("language-")) // expect: false
System.print(noLangHtml.contains("plain code")) // expect: true
var wren = "```wren\nSystem.print(\"Hello\")\n```"
var wrenHtml = Markdown.toHtml(wren)
System.print(wrenHtml.contains("class=\"language-wren\"")) // expect: true
var rust = "```rust\nfn main() {}\n```"
var rustHtml = Markdown.toHtml(rust)
System.print(rustHtml.contains("class=\"language-rust\"")) // expect: true
System.print(rustHtml.contains("<pre><code")) // expect: true
+27
View File
@@ -0,0 +1,27 @@
// retoor <retoor@molodetz.nl>
import "markdown" for Markdown
var basic = "| A | B |\n|---|---|\n| 1 | 2 |"
var html = Markdown.toHtml(basic)
System.print(html.contains("<table>")) // expect: true
System.print(html.contains("<thead>")) // expect: true
System.print(html.contains("<tbody>")) // expect: true
System.print(html.contains("<th>A</th>")) // expect: true
System.print(html.contains("<td>1</td>")) // expect: true
var aligned = "| Left | Center | Right |\n|:---|:---:|---:|\n| L | C | R |"
var alignedHtml = Markdown.toHtml(aligned)
System.print(alignedHtml.contains("text-align:center")) // expect: true
System.print(alignedHtml.contains("text-align:right")) // expect: true
var multiRow = "| H1 | H2 |\n|---|---|\n| A | B |\n| C | D |"
var multiHtml = Markdown.toHtml(multiRow)
System.print(multiHtml.contains("<td>A</td>")) // expect: true
System.print(multiHtml.contains("<td>D</td>")) // expect: true
var inlineTable = "| **Bold** | *Italic* |\n|---|---|\n| `code` | [link](url) |"
var inlineHtml = Markdown.toHtml(inlineTable)
System.print(inlineHtml.contains("<strong>Bold</strong>")) // expect: true
System.print(inlineHtml.contains("<em>Italic</em>")) // expect: true
System.print(inlineHtml.contains("<code>code</code>")) // expect: true
+29
View File
@@ -0,0 +1,29 @@
// retoor <retoor@molodetz.nl>
import "markdown" for Markdown
var unchecked = "- [ ] Task one"
var uncheckedHtml = Markdown.toHtml(unchecked)
System.print(uncheckedHtml.contains("task-list")) // expect: true
System.print(uncheckedHtml.contains("<input type=\"checkbox\" disabled>")) // expect: true
System.print(uncheckedHtml.contains("Task one")) // expect: true
var checked = "- [x] Done task"
var checkedHtml = Markdown.toHtml(checked)
System.print(checkedHtml.contains("<input type=\"checkbox\" disabled checked>")) // expect: true
System.print(checkedHtml.contains("Done task")) // expect: true
var mixed = "- [ ] Todo\n- [x] Complete\n- [ ] Another"
var mixedHtml = Markdown.toHtml(mixed)
System.print(mixedHtml.contains("Todo")) // expect: true
System.print(mixedHtml.contains("Complete")) // expect: true
System.print(mixedHtml.contains("Another")) // expect: true
var upperX = "- [X] Upper case X"
var upperHtml = Markdown.toHtml(upperX)
System.print(upperHtml.contains("checked")) // expect: true
var regular = "- Normal item"
var regularHtml = Markdown.toHtml(regular)
System.print(regularHtml.contains("task-list")) // expect: false
System.print(regularHtml.contains("<li>Normal item</li>")) // expect: true
+72
View File
@@ -0,0 +1,72 @@
// retoor <retoor@molodetz.nl>
import "regex" for Regex, Match
var re = Regex.new("test")
System.print(re.test("")) // expect: false
var re2 = Regex.new("")
System.print(re2.test("anything")) // expect: true
System.print(re2.test("")) // expect: true
var re3 = Regex.new("a*")
var m = re3.match("")
System.print(m.text) // expect:
System.print(m.start) // expect: 0
System.print(m.end) // expect: 0
var longStr = "a" * 1000
var re4 = Regex.new("a+")
System.print(re4.test(longStr)) // expect: true
var m2 = re4.match(longStr)
System.print(m2.text.count) // expect: 1000
System.print(m2.start) // expect: 0
System.print(m2.end) // expect: 1000
var re5 = Regex.new("test")
var longWithMatch = "x" * 500 + "test" + "y" * 500
System.print(re5.test(longWithMatch)) // expect: true
var m3 = re5.match(longWithMatch)
System.print(m3.start) // expect: 500
System.print(m3.end) // expect: 504
System.print(Regex.test("^$", "")) // expect: true
System.print(Regex.test("^$", "x")) // expect: false
System.print(Regex.test("^", "anything")) // expect: true
System.print(Regex.test("$", "anything")) // expect: true
var re6 = Regex.new("(a)(b)(c)(d)(e)(f)(g)(h)")
var m4 = re6.match("abcdefgh")
System.print(m4.groups.count) // expect: 9
System.print(m4[0]) // expect: abcdefgh
System.print(m4[1]) // expect: a
System.print(m4[8]) // expect: h
var re7 = Regex.new("((a)(b))((c)(d))")
var m5 = re7.match("abcd")
System.print(m5[0]) // expect: abcd
System.print(m5[1]) // expect: ab
System.print(m5[2]) // expect: a
System.print(m5[3]) // expect: b
System.print(m5[4]) // expect: cd
System.print(m5[5]) // expect: c
System.print(m5[6]) // expect: d
var re8 = Regex.new("test")
System.print(re8.test("test")) // expect: true
System.print(re8.test("testing")) // expect: true
System.print(re8.test("a test")) // expect: true
System.print(re8.test("TEST")) // expect: false
var re9 = Regex.new("x")
var allMatch = re9.matchAll("xxx")
System.print(allMatch.count) // expect: 1
System.print(allMatch[0].start) // expect: 0
System.print(Regex.test("[0-9]", "5")) // expect: true
System.print(Regex.test("[a-zA-Z0-9_]+", "hello_123")) // expect: true
var parts = Regex.split(",", "a,b,c,d,e")
System.print(parts.count) // expect: 5
System.print(parts[4]) // expect: e
+6
View File
@@ -0,0 +1,6 @@
// retoor <retoor@molodetz.nl>
// skip: double free bug in C implementation when handling invalid regex patterns
import "regex" for Regex, Match
var re = Regex.new("[unclosed")
+48
View File
@@ -0,0 +1,48 @@
// retoor <retoor@molodetz.nl>
import "regex" for Regex, Match
var ri = Regex.new("hello", "i")
System.print(ri.test("HELLO")) // expect: true
System.print(ri.test("Hello")) // expect: true
System.print(ri.test("hElLo")) // expect: true
System.print(ri.pattern) // expect: hello
System.print(ri.flags) // expect: i
var rm = Regex.new("^line", "m")
var multiline = "first\nline two\nline three"
System.print(rm.test(multiline)) // expect: true
System.print(rm.pattern) // expect: ^line
System.print(rm.flags) // expect: m
var rm2 = Regex.new("^first", "m")
System.print(rm2.test(multiline)) // expect: true
var rm3 = Regex.new("two$", "m")
System.print(rm3.test(multiline)) // expect: true
var rs = Regex.new("first.line", "s")
var withNewline = "first\nline"
System.print(rs.test(withNewline)) // expect: true
System.print(rs.pattern) // expect: first.line
System.print(rs.flags) // expect: s
var rnos = Regex.new("first.line")
System.print(rnos.test(withNewline)) // expect: true
var rim = Regex.new("^hello", "im")
var multiCase = "WORLD\nHELLO"
System.print(rim.test(multiCase)) // expect: true
System.print(rim.pattern) // expect: ^hello
System.print(rim.flags) // expect: im
var ris = Regex.new("a.b", "i")
System.print(ris.test("A\nB")) // expect: true
var plain = Regex.new("test")
System.print(plain.pattern) // expect: test
System.print(plain.flags) // expect:
var rims = Regex.new("^hello.world", "ims")
var complex = "START\nHELLO\nWORLD"
System.print(rims.test(complex)) // expect: true
+40
View File
@@ -0,0 +1,40 @@
// retoor <retoor@molodetz.nl>
import "regex" for Regex, Match
var re = Regex.new("\\d+")
var matches = re.matchAll("abc123def")
System.print(matches.count) // expect: 1
System.print(matches[0].text) // expect: 123
System.print(matches[0].start) // expect: 3
System.print(matches[0].end) // expect: 6
var re2 = Regex.new("notfound")
var empty = re2.matchAll("some text")
System.print(empty.count) // expect: 0
var re3 = Regex.new("(\\w+)@(\\w+)")
var emails = re3.matchAll("contact: user@domain here")
System.print(emails.count) // expect: 1
System.print(emails[0].text) // expect: user@domain
System.print(emails[0][1]) // expect: user
System.print(emails[0][2]) // expect: domain
var re4 = Regex.new("a")
var manyA = re4.matchAll("apple")
System.print(manyA.count) // expect: 1
System.print(manyA[0].start) // expect: 0
var re5 = Regex.new("test")
var single = re5.matchAll("this is a test string")
System.print(single.count) // expect: 1
System.print(single[0].text) // expect: test
System.print(single[0].start) // expect: 10
System.print(single[0].end) // expect: 14
var re6 = Regex.new(" ")
var spaces = re6.matchAll("a b")
System.print(spaces.count) // expect: 1
System.print(spaces[0].text == " ") // expect: true
System.print(spaces[0].start) // expect: 1
+49
View File
@@ -0,0 +1,49 @@
// retoor <retoor@molodetz.nl>
import "regex" for Regex, Match
var re = Regex.new("(\\w+)@(\\w+)")
var m = re.match("email: user@domain here")
System.print(m.text) // expect: user@domain
System.print(m.start) // expect: 7
System.print(m.end) // expect: 18
System.print(m.toString) // expect: user@domain
System.print(m.groups.count) // expect: 3
System.print(m.groups[0]) // expect: user@domain
System.print(m.groups[1]) // expect: user
System.print(m.groups[2]) // expect: domain
System.print(m.group(0)) // expect: user@domain
System.print(m.group(1)) // expect: user
System.print(m.group(2)) // expect: domain
System.print(m[0]) // expect: user@domain
System.print(m[1]) // expect: user
System.print(m[2]) // expect: domain
System.print(m.group(100) == null) // expect: true
System.print(m.group(-1) == null) // expect: true
System.print(m[-1] == null) // expect: true
System.print(m[999] == null) // expect: true
var re2 = Regex.new("test")
var m2 = re2.match("a test string")
System.print(m2.start) // expect: 2
System.print(m2.end) // expect: 6
System.print(m2.text) // expect: test
var re3 = Regex.new("^start")
var m3 = re3.match("start of string")
System.print(m3.start) // expect: 0
System.print(m3.end) // expect: 5
var re4 = Regex.new("end$")
var m4 = re4.match("the end")
System.print(m4.start) // expect: 4
System.print(m4.end) // expect: 7
var re5 = Regex.new("notfound")
var m5 = re5.match("some text")
System.print(m5 == null) // expect: true
+92
View File
@@ -0,0 +1,92 @@
// retoor <retoor@molodetz.nl>
import "regex" for Regex, Match
System.print(Regex.test("hello", "say hello world")) // expect: true
System.print(Regex.test("exact", "exactly")) // expect: true
System.print(Regex.test("h.llo", "hello")) // expect: true
System.print(Regex.test("h.llo", "hallo")) // expect: true
System.print(Regex.test("h.llo", "hllo")) // expect: false
System.print(Regex.test("a..b", "axxb")) // expect: true
System.print(Regex.test("a*", "aaa")) // expect: true
System.print(Regex.test("a*", "aaa")) // expect: true
System.print(Regex.test("ba*", "b")) // expect: true
System.print(Regex.test("ba*", "baaa")) // expect: true
System.print(Regex.test("a+", "a")) // expect: true
System.print(Regex.test("a+", "aaa")) // expect: true
System.print(Regex.test("^a+$", "")) // expect: false
System.print(Regex.test("colou?r", "color")) // expect: true
System.print(Regex.test("colou?r", "colour")) // expect: true
System.print(Regex.test("a{3}", "aaa")) // expect: true
System.print(Regex.test("^a{3}$", "aa")) // expect: false
System.print(Regex.test("a{2,}", "aa")) // expect: true
System.print(Regex.test("a{2,}", "aaaaa")) // expect: true
System.print(Regex.test("a{2,4}", "aaa")) // expect: true
System.print(Regex.test("[abc]", "a")) // expect: true
System.print(Regex.test("[abc]", "b")) // expect: true
System.print(Regex.test("[abc]", "d")) // expect: false
System.print(Regex.test("[a-z]", "m")) // expect: true
System.print(Regex.test("[a-z]", "M")) // expect: false
System.print(Regex.test("[A-Za-z]", "M")) // expect: true
System.print(Regex.test("[0-9]", "5")) // expect: true
System.print(Regex.test("[^abc]", "d")) // expect: true
System.print(Regex.test("[^abc]", "xyz")) // expect: true
System.print(Regex.test("^[^abc]$", "a")) // expect: false
System.print(Regex.test("^hello", "hello world")) // expect: true
System.print(Regex.test("^hello", "say hello")) // expect: false
System.print(Regex.test("world$", "hello world")) // expect: true
System.print(Regex.test("world$", "world hello")) // expect: false
System.print(Regex.test("^exact$", "exact")) // expect: true
System.print(Regex.test("^exact$", "exactly")) // expect: false
System.print(Regex.test("cat|dog", "cat")) // expect: true
System.print(Regex.test("cat|dog", "dog")) // expect: true
System.print(Regex.test("cat|dog", "bird")) // expect: false
System.print(Regex.test("a(bc|de)f", "abcf")) // expect: true
System.print(Regex.test("a(bc|de)f", "adef")) // expect: true
var m = Regex.match("(\\w+)-(\\d+)", "item-42")
System.print(m[1]) // expect: item
System.print(m[2]) // expect: 42
var m2 = Regex.match("((a)(b))", "ab")
System.print(m2[0]) // expect: ab
System.print(m2[1]) // expect: ab
System.print(m2[2]) // expect: a
System.print(m2[3]) // expect: b
System.print(Regex.test("\\d", "5")) // expect: true
System.print(Regex.test("\\d", "a")) // expect: false
System.print(Regex.test("\\D", "a")) // expect: true
System.print(Regex.test("\\D", "5")) // expect: false
System.print(Regex.test("\\w", "a")) // expect: true
System.print(Regex.test("\\w", "_")) // expect: true
System.print(Regex.test("\\w", " ")) // expect: false
System.print(Regex.test("\\W", " ")) // expect: true
System.print(Regex.test("\\W", "a")) // expect: false
System.print(Regex.test("\\s", " ")) // expect: true
System.print(Regex.test("\\s", "\t")) // expect: true
System.print(Regex.test("\\s", "a")) // expect: false
System.print(Regex.test("\\S", "a")) // expect: true
System.print(Regex.test("\\S", " ")) // expect: false
System.print(Regex.test("a\\nb", "a\nb")) // expect: true
System.print(Regex.test("a\\tb", "a\tb")) // expect: true
System.print(Regex.test("a\\rb", "a\rb")) // expect: true
System.print(Regex.test("\\.", ".")) // expect: true
System.print(Regex.test("\\.", "a")) // expect: false
System.print(Regex.test("\\*", "*")) // expect: true
System.print(Regex.test("\\+", "+")) // expect: true
System.print(Regex.test("\\?", "?")) // expect: true
System.print(Regex.test("\\[", "[")) // expect: true
System.print(Regex.test("\\(", "(")) // expect: true
System.print(Regex.test("\\$", "$")) // expect: true
System.print(Regex.test("\\^", "^")) // expect: true
+45
View File
@@ -0,0 +1,45 @@
// retoor <retoor@molodetz.nl>
import "regex" for Regex, Match
var re = Regex.new("a")
System.print(re.replace("banana", "X")) // expect: bXnana
System.print(re.replaceAll("banana", "X")) // expect: bXnXnX
var re2 = Regex.new("notfound")
System.print(re2.replace("original", "X")) // expect: original
System.print(re2.replaceAll("original", "X")) // expect: original
var re3 = Regex.new("x")
System.print(re3.replace("xxx", "")) // expect: xx
System.print(re3.replaceAll("xxx", "")) // expect:
var re4 = Regex.new("^start")
System.print(re4.replace("start of string", "BEGIN")) // expect: BEGIN of string
var re5 = Regex.new("end$")
System.print(re5.replace("the end", "finish")) // expect: the finish
var re6 = Regex.new("middle")
System.print(re6.replace("at the middle of text", "center")) // expect: at the center of text
var re7 = Regex.new("ab")
System.print(re7.replaceAll("ababab", "X")) // expect: XXX
var re8 = Regex.new("\\d+")
System.print(re8.replace("abc123def456", "NUM")) // expect: abcNUMdef456
System.print(re8.replaceAll("abc123def456", "NUM")) // expect: abcNUMdefNUM
var re9 = Regex.new("[ ]+")
System.print(re9.replaceAll("a b c d", " ")) // expect: a b c d
var re10 = Regex.new(".")
System.print(re10.replace("hello", "X")) // expect: Xello
System.print(re10.replaceAll("hi", "X")) // expect: XX
var re11 = Regex.new("[aeiou]")
System.print(re11.replaceAll("hello world", "*")) // expect: h*ll* w*rld
var re12 = Regex.new("a")
System.print(re12.replaceAll("a", "b")) // expect: b
System.print(re12.replaceAll("aaa", "bb")) // expect: bbbbbb
+63
View File
@@ -0,0 +1,63 @@
// retoor <retoor@molodetz.nl>
import "regex" for Regex, Match
var re = Regex.new(",")
var parts = re.split("a,b,c")
System.print(parts.count) // expect: 3
System.print(parts[0]) // expect: a
System.print(parts[1]) // expect: b
System.print(parts[2]) // expect: c
var re2 = Regex.new(" ")
var words = re2.split("one two three")
System.print(words.count) // expect: 3
System.print(words[0]) // expect: one
System.print(words[1]) // expect: two
System.print(words[2]) // expect: three
var re3 = Regex.new("notfound")
var nomatch = re3.split("original string")
System.print(nomatch.count) // expect: 1
System.print(nomatch[0]) // expect: original string
var re4 = Regex.new(",")
var consecutive = re4.split("a,,b")
System.print(consecutive.count) // expect: 3
System.print(consecutive[0]) // expect: a
System.print(consecutive[1]) // expect:
System.print(consecutive[2]) // expect: b
var re5 = Regex.new(",")
var startDelim = re5.split(",a,b")
System.print(startDelim.count) // expect: 3
System.print(startDelim[0]) // expect:
System.print(startDelim[1]) // expect: a
System.print(startDelim[2]) // expect: b
var re6 = Regex.new(",")
var endDelim = re6.split("a,b,")
System.print(endDelim.count) // expect: 3
System.print(endDelim[0]) // expect: a
System.print(endDelim[1]) // expect: b
System.print(endDelim[2]) // expect:
var re7 = Regex.new("[,;]")
var multiDelim = re7.split("a,b;c")
System.print(multiDelim.count) // expect: 3
System.print(multiDelim[0]) // expect: a
System.print(multiDelim[1]) // expect: b
System.print(multiDelim[2]) // expect: c
var re8 = Regex.new("-")
var varDelim = re8.split("a-b-c-d")
System.print(varDelim.count) // expect: 4
System.print(varDelim[0]) // expect: a
System.print(varDelim[1]) // expect: b
System.print(varDelim[2]) // expect: c
System.print(varDelim[3]) // expect: d
var re9 = Regex.new(":")
var single = re9.split("onlyone")
System.print(single.count) // expect: 1
System.print(single[0]) // expect: onlyone
+36
View File
@@ -0,0 +1,36 @@
// retoor <retoor@molodetz.nl>
import "regex" for Regex, Match
System.print(Regex.test("\\d+", "abc123def")) // expect: true
System.print(Regex.test("\\d+", "no digits")) // expect: false
System.print(Regex.test("^hello", "hello world")) // expect: true
System.print(Regex.test("^hello", "say hello")) // expect: false
var m = Regex.match("(\\w+)-(\\d+)", "item-42")
System.print(m.text) // expect: item-42
System.print(m[1]) // expect: item
System.print(m[2]) // expect: 42
var m2 = Regex.match("notfound", "some text")
System.print(m2 == null) // expect: true
System.print(Regex.replace("a", "banana", "o")) // expect: bonono
System.print(Regex.replace("\\d", "a1b2c3", "X")) // expect: aXbXcX
System.print(Regex.replace("notfound", "original", "X")) // expect: original
var parts = Regex.split(",", "a,b,c")
System.print(parts.count) // expect: 3
System.print(parts[0]) // expect: a
System.print(parts[1]) // expect: b
System.print(parts[2]) // expect: c
var parts2 = Regex.split(" ", "one two three")
System.print(parts2.count) // expect: 3
System.print(parts2[0]) // expect: one
System.print(parts2[1]) // expect: two
System.print(parts2[2]) // expect: three
var parts3 = Regex.split("x", "no match")
System.print(parts3.count) // expect: 1
System.print(parts3[0]) // expect: no match
+22
View File
@@ -0,0 +1,22 @@
// retoor <retoor@molodetz.nl>
import "web" for Request
var content = ""
for (i in 0...1000) {
content = content + "ABCDEFGHIJ"
}
var body = "------boundary\r\n" +
"Content-Disposition: form-data; name=\"file\"; filename=\"large.bin\"\r\n" +
"Content-Type: application/octet-stream\r\n" +
"\r\n" +
content + "\r\n" +
"------boundary--\r\n"
var headers = {"Content-Type": "multipart/form-data; boundary=----boundary"}
var request = Request.new_("POST", "/upload", {}, headers, body, {}, null)
var form = request.form
System.print(form["file"]["filename"]) // expect: large.bin
System.print(form["file"]["content"].count) // expect: 10000
+26
View File
@@ -0,0 +1,26 @@
// retoor <retoor@molodetz.nl>
import "web" for Request
var body = "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\n" +
"Content-Disposition: form-data; name=\"description\"\r\n" +
"\r\n" +
"Test file description\r\n" +
"------WebKitFormBoundary7MA4YWxkTrZu0gW\r\n" +
"Content-Disposition: form-data; name=\"file\"; filename=\"test.txt\"\r\n" +
"Content-Type: text/plain\r\n" +
"\r\n" +
"Hello, World!\r\n" +
"------WebKitFormBoundary7MA4YWxkTrZu0gW--\r\n"
var headers = {
"Content-Type": "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"
}
var request = Request.new_("POST", "/upload", {}, headers, body, {}, null)
var form = request.form
System.print(form["description"]) // expect: Test file description
System.print(form["file"]["filename"]) // expect: test.txt
System.print(form["file"]["content"]) // expect: Hello, World!
System.print(form["file"]["content_type"]) // expect: text/plain
+21
View File
@@ -0,0 +1,21 @@
// retoor <retoor@molodetz.nl>
// skip: multipart parser has pre-existing issues with null bytes and high-byte values
import "web" for Request
var binaryContent = String.fromByte(0) + String.fromByte(255) + String.fromByte(127)
var body = "------boundary\r\n" +
"Content-Disposition: form-data; name=\"data\"; filename=\"binary.dat\"\r\n" +
"Content-Type: application/octet-stream\r\n" +
"\r\n" +
binaryContent + "\r\n" +
"------boundary--\r\n"
var headers = {"Content-Type": "multipart/form-data; boundary=----boundary"}
var request = Request.new_("POST", "/upload", {}, headers, body, {}, null)
var form = request.form
System.print(form["data"]["content"].bytes.count) // expect: 3
System.print(form["data"]["content"].bytes[0]) // expect: 0
System.print(form["data"]["content"].bytes[1]) // expect: 255
System.print(form["data"]["content"].bytes[2]) // expect: 127
+15
View File
@@ -0,0 +1,15 @@
// retoor <retoor@molodetz.nl>
import "web" for Request
var body = "------boundary\n" +
"Content-Disposition: form-data; name=\"field\"\n" +
"\n" +
"value\n" +
"------boundary--\n"
var headers = {"Content-Type": "multipart/form-data; boundary=----boundary"}
var request = Request.new_("POST", "/submit", {}, headers, body, {}, null)
var form = request.form
System.print(form["field"]) // expect: value
+24
View File
@@ -0,0 +1,24 @@
// retoor <retoor@molodetz.nl>
import "web" for Request
var body = "------FormBoundary\r\n" +
"Content-Disposition: form-data; name=\"username\"\r\n" +
"\r\n" +
"john\r\n" +
"------FormBoundary\r\n" +
"Content-Disposition: form-data; name=\"email\"\r\n" +
"\r\n" +
"john@example.com\r\n" +
"------FormBoundary--\r\n"
var headers = {
"Content-Type": "multipart/form-data; boundary=----FormBoundary"
}
var request = Request.new_("POST", "/submit", {}, headers, body, {}, null)
var form = request.form
System.print(form["username"]) // expect: john
System.print(form["email"]) // expect: john@example.com
System.print(form["file"]) // expect: null