mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
db, json, time, term: change optional to result (#16201)
This commit is contained in:
parent
2a7420f572
commit
992b502198
@ -4112,7 +4112,7 @@ println(user.last_name)
|
||||
println(user.age)
|
||||
// You can also decode JSON arrays:
|
||||
sfoos := '[{"x":123},{"x":456}]'
|
||||
foos := json.decode([]Foo, sfoos)?
|
||||
foos := json.decode([]Foo, sfoos)!
|
||||
println(foos[0].x)
|
||||
println(foos[1].x)
|
||||
```
|
||||
|
@ -8,8 +8,8 @@ fn main() {
|
||||
password: ''
|
||||
dbname: 'mysql'
|
||||
}
|
||||
conn.connect()?
|
||||
res := conn.query('show tables')?
|
||||
conn.connect()!
|
||||
res := conn.query('show tables')!
|
||||
for row in res.rows() {
|
||||
println(row.vals.join(', '))
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import sqlite
|
||||
|
||||
fn main() {
|
||||
db := sqlite.connect(':memory:')?
|
||||
db := sqlite.connect(':memory:')!
|
||||
db.exec("create table users (id integer primary key, name text default '');")
|
||||
|
||||
db.exec("insert into users (name) values ('Sam')")
|
||||
|
@ -79,7 +79,7 @@ Decode the info to `FrameworkBenchmarkResponse`
|
||||
fn typescript_sqlite_memory() ?FrameworkBenchmarkResponse {
|
||||
url := 'http://localhost:3000/sqlite-memory/$benchmark_loop_length'
|
||||
res := http.get(url) or { panic(err) }
|
||||
framework_benchmark_response := json.decode(FrameworkBenchmarkResponse, res.body)?
|
||||
framework_benchmark_response := json.decode(FrameworkBenchmarkResponse, res.body)!
|
||||
return framework_benchmark_response
|
||||
}
|
||||
```
|
||||
@ -91,7 +91,7 @@ Decode the info to `FrameworkBenchmarkResponse`
|
||||
fn typescript_sqlite_memory() ?FrameworkBenchmarkResponse {
|
||||
url := 'http://localhost:3000/sqlite-memory/$benchmark_loop_length'
|
||||
res := http.get(url) or { panic(err) }
|
||||
framework_benchmark_response := json.decode(FrameworkBenchmarkResponse, res.body)?
|
||||
framework_benchmark_response := json.decode(FrameworkBenchmarkResponse, res.body)!
|
||||
return framework_benchmark_response
|
||||
}
|
||||
```
|
||||
@ -106,4 +106,4 @@ with the new function
|
||||
# ROADMAP
|
||||
02/09/2022
|
||||
- [ ] select bench (easy)
|
||||
- [ ] vsql (easy)
|
||||
- [ ] vsql (easy)
|
||||
|
@ -68,7 +68,7 @@ Decode the info to `FrameworkBenchmarkResponse`
|
||||
fn typescript_sqlite_memory() ?FrameworkBenchmarkResponse {
|
||||
url := 'http://localhost:3000/sqlite-memory/$benchmark_loop_length'
|
||||
res := http.get(url) or { panic(err) }
|
||||
framework_benchmark_response := json.decode(FrameworkBenchmarkResponse, res.body)?
|
||||
framework_benchmark_response := json.decode(FrameworkBenchmarkResponse, res.body)!
|
||||
return framework_benchmark_response
|
||||
}
|
||||
```
|
||||
@ -80,7 +80,7 @@ Decode the info to `FrameworkBenchmarkResponse`
|
||||
fn typescript_sqlite_memory() ?FrameworkBenchmarkResponse {
|
||||
url := 'http://localhost:3000/sqlite-memory/$benchmark_loop_length'
|
||||
res := http.get(url) or { panic(err) }
|
||||
framework_benchmark_response := json.decode(FrameworkBenchmarkResponse, res.body)?
|
||||
framework_benchmark_response := json.decode(FrameworkBenchmarkResponse, res.body)!
|
||||
return framework_benchmark_response
|
||||
}
|
||||
```
|
||||
@ -95,4 +95,4 @@ with the new function
|
||||
# ROADMAP
|
||||
02/09/2022
|
||||
- [ ] select bench (easy)
|
||||
- [ ] vsql (easy)
|
||||
- [ ] vsql (easy)
|
||||
|
@ -145,24 +145,24 @@ fn update_framework_benchmark_times() !FrameworkPlatform {
|
||||
return numbers
|
||||
}
|
||||
|
||||
fn typescript_sqlite_memory() ?FrameworkBenchmarkResponse {
|
||||
fn typescript_sqlite_memory() !FrameworkBenchmarkResponse {
|
||||
url := 'http://localhost:3000/sqlite-memory/$benchmark_loop_length'
|
||||
res := http.get(url) or { panic(err) }
|
||||
framework_benchmark_response := json.decode(FrameworkBenchmarkResponse, res.body)?
|
||||
framework_benchmark_response := json.decode(FrameworkBenchmarkResponse, res.body)!
|
||||
return framework_benchmark_response
|
||||
}
|
||||
|
||||
fn v_sqlite_memory() ?FrameworkBenchmarkResponse {
|
||||
fn v_sqlite_memory() !FrameworkBenchmarkResponse {
|
||||
url := 'http://localhost:4000/sqlite-memory/$benchmark_loop_length'
|
||||
res := http.get(url) or { panic(err) }
|
||||
framework_benchmark_response := json.decode(FrameworkBenchmarkResponse, res.body)?
|
||||
framework_benchmark_response := json.decode(FrameworkBenchmarkResponse, res.body)!
|
||||
return framework_benchmark_response
|
||||
}
|
||||
|
||||
fn v_sqlite_file() ?FrameworkBenchmarkResponse {
|
||||
fn v_sqlite_file() !FrameworkBenchmarkResponse {
|
||||
// url := 'http://localhost:3000/sqlite-memory/$benchmark_loop_length'
|
||||
// res := http.get(url) or { panic(err) }
|
||||
// framework_benchmark_response := json.decode(FrameworkBenchmarkResponse, res.body)?
|
||||
// framework_benchmark_response := json.decode(FrameworkBenchmarkResponse, res.body)!
|
||||
framework_benchmark_response := FrameworkBenchmarkResponse{
|
||||
insert: []
|
||||
@select: []
|
||||
|
@ -1,3 +1,3 @@
|
||||
chdir('examples/password')?
|
||||
chdir('examples/password')!
|
||||
assert execute('./correct.expect').exit_code == 0
|
||||
assert execute('./incorrect.expect').exit_code == 0
|
||||
|
@ -2,6 +2,6 @@ import rand
|
||||
|
||||
fn main() {
|
||||
for _ in 0 .. 10 {
|
||||
println('${rand.intn(255)?}.${rand.intn(255)?}.${rand.intn(255)?}.${rand.intn(255)?}')
|
||||
println('${rand.intn(255)!}.${rand.intn(255)!}.${rand.intn(255)!}.${rand.intn(255)!}')
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ struct JwtPayload {
|
||||
permissions string
|
||||
}
|
||||
|
||||
fn (mut app App) service_auth(username string, password string) ?string {
|
||||
fn (mut app App) service_auth(username string, password string) !string {
|
||||
mut db := databases.create_db_connection() or {
|
||||
eprintln(err)
|
||||
panic(err)
|
||||
@ -42,7 +42,7 @@ fn (mut app App) service_auth(username string, password string) ?string {
|
||||
return error('user is not active')
|
||||
}
|
||||
|
||||
db.close()?
|
||||
db.close()!
|
||||
|
||||
bcrypt.compare_hash_and_password(password.bytes(), user.password.bytes()) or {
|
||||
return error('Failed to auth user, $err')
|
||||
|
@ -2,7 +2,7 @@ module databases
|
||||
|
||||
import sqlite
|
||||
|
||||
pub fn create_db_connection() ?sqlite.DB {
|
||||
mut db := sqlite.connect('database.db')?
|
||||
pub fn create_db_connection() !sqlite.DB {
|
||||
mut db := sqlite.connect('database.db')!
|
||||
return db
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ fn main() {
|
||||
println('Employee x: $s')
|
||||
assert s == '{"name":"Peter","age":28,"salary":95000.5,"title":2}'
|
||||
//
|
||||
y := json.decode(Employee, s)?
|
||||
y := json.decode(Employee, s)!
|
||||
//
|
||||
println(y)
|
||||
assert y == x
|
||||
|
@ -38,9 +38,9 @@ struct Mount {
|
||||
size u64
|
||||
}
|
||||
|
||||
fn test_decode_u64() ? {
|
||||
fn test_decode_u64() {
|
||||
data := '{"size": 10737418240}'
|
||||
m := json.decode(Mount, data)?
|
||||
m := json.decode(Mount, data)!
|
||||
assert m.size == 10737418240
|
||||
// println(m)
|
||||
}
|
||||
@ -62,9 +62,9 @@ mut:
|
||||
comments []Comment [skip]
|
||||
}
|
||||
|
||||
fn test_skip_fields_should_be_initialised_by_json_decode() ? {
|
||||
fn test_skip_fields_should_be_initialised_by_json_decode() {
|
||||
data := '{"total_comments": 55, "id": 123}'
|
||||
mut task := json.decode(Task, data)?
|
||||
mut task := json.decode(Task, data)!
|
||||
assert task.id == 123
|
||||
assert task.total_comments == 55
|
||||
assert task.comments == []
|
||||
|
@ -4,9 +4,9 @@ struct TodoDto {
|
||||
foo int
|
||||
}
|
||||
|
||||
fn test_decode_with_encode_arg() ? {
|
||||
fn test_decode_with_encode_arg() {
|
||||
body := TodoDto{}
|
||||
ret := json.decode(TodoDto, json.encode(body))?
|
||||
ret := json.decode(TodoDto, json.encode(body))!
|
||||
println(ret)
|
||||
assert ret.foo == 0
|
||||
}
|
||||
|
@ -10,14 +10,14 @@ struct User {
|
||||
username string
|
||||
}
|
||||
|
||||
fn func<T>() ?T {
|
||||
fn func<T>() !T {
|
||||
text := '{"ok": true, "result":{"id":37467243, "username": "ciao"}}'
|
||||
a := json.decode(Result<T>, text)?
|
||||
a := json.decode(Result<T>, text)!
|
||||
return a.result
|
||||
}
|
||||
|
||||
fn test_decode_with_generic_struct() ? {
|
||||
ret := func<User>()?
|
||||
fn test_decode_with_generic_struct() {
|
||||
ret := func<User>()!
|
||||
println(ret)
|
||||
assert ret.id == 37467243
|
||||
assert ret.username == 'ciao'
|
||||
|
@ -12,8 +12,8 @@ fn test_json_decode_with_optional_arg() {
|
||||
assert true
|
||||
}
|
||||
|
||||
fn print_info() ?string {
|
||||
dbconf := json.decode(DbConfig, os.read_file('dbconf.json')?)?
|
||||
fn print_info() !string {
|
||||
dbconf := json.decode(DbConfig, os.read_file('dbconf.json')!)!
|
||||
println(dbconf)
|
||||
return '$dbconf'
|
||||
}
|
||||
|
@ -6,16 +6,16 @@ struct Some {
|
||||
t Test
|
||||
}
|
||||
|
||||
fn test_json_decode_with_sumtype() ? {
|
||||
v1 := json.decode(Some, '{"t": ["string", "string2"]}')?
|
||||
fn test_json_decode_with_sumtype() {
|
||||
v1 := json.decode(Some, '{"t": ["string", "string2"]}')!
|
||||
println(v1)
|
||||
assert v1.t == Test(['string', 'string2'])
|
||||
|
||||
v2 := json.decode(Some, '{"t": [11, 22]}')?
|
||||
v2 := json.decode(Some, '{"t": [11, 22]}')!
|
||||
println(v2)
|
||||
assert v2.t == Test([11, 22])
|
||||
|
||||
v3 := json.decode(Some, '{"t": [true, false]}')?
|
||||
v3 := json.decode(Some, '{"t": [true, false]}')!
|
||||
println(v3)
|
||||
assert v3.t == Test([true, false])
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ fn C.cJSON_free(voidptr)
|
||||
// decode tries to decode the provided JSON string, into a V structure.
|
||||
// If it can not do that, it returns an error describing the reason for
|
||||
// the parsing failure.
|
||||
pub fn decode(typ voidptr, s string) ?voidptr {
|
||||
pub fn decode(typ voidptr, s string) !voidptr {
|
||||
// compiler implementation
|
||||
return 0
|
||||
}
|
||||
|
@ -14,12 +14,12 @@ struct Employee {
|
||||
title JobTitle
|
||||
}
|
||||
|
||||
fn test_simple() ? {
|
||||
fn test_simple() {
|
||||
x := Employee{'Peter', 28, 95000.5, .worker}
|
||||
s := json.encode(x)
|
||||
// eprintln('Employee x: $s')
|
||||
assert s == '{"name":"Peter","age":28,"salary":95000.5,"title":2}'
|
||||
y := json.decode(Employee, s)?
|
||||
y := json.decode(Employee, s)!
|
||||
// eprintln('Employee y: $y')
|
||||
assert y.name == 'Peter'
|
||||
assert y.age == 28
|
||||
@ -34,9 +34,9 @@ struct Price {
|
||||
currency_id string [json: currencyId] = currency_id
|
||||
}
|
||||
|
||||
fn test_field_with_default_expr() ? {
|
||||
fn test_field_with_default_expr() {
|
||||
data := '[{"net":1},{"net":2,"currencyId":"cjson"}]'
|
||||
prices := json.decode([]Price, data)?
|
||||
prices := json.decode([]Price, data)!
|
||||
assert prices == [Price{
|
||||
net: 1
|
||||
currency_id: 'cconst'
|
||||
@ -77,7 +77,7 @@ struct SomeGame {
|
||||
other []Entity
|
||||
}
|
||||
|
||||
fn test_encode_decode_sumtype() ? {
|
||||
fn test_encode_decode_sumtype() {
|
||||
t := time.now()
|
||||
game := SomeGame{
|
||||
title: 'Super Mega Game'
|
||||
@ -97,7 +97,7 @@ fn test_encode_decode_sumtype() ? {
|
||||
|
||||
assert enc == '{"title":"Super Mega Game","player":{"name":"Monke","_type":"Human"},"other":[{"tag":"Pen","_type":"Item"},{"tag":"Cookie","_type":"Item"},1,"Stool",{"_type":"Time","value":$t.unix_time()}]}'
|
||||
|
||||
dec := json.decode(SomeGame, enc)?
|
||||
dec := json.decode(SomeGame, enc)!
|
||||
// eprintln('Decoded Game: $dec')
|
||||
|
||||
assert game.title == dec.title
|
||||
@ -106,8 +106,8 @@ fn test_encode_decode_sumtype() ? {
|
||||
assert (game.other[4] as time.Time).unix_time() == (dec.other[4] as time.Time).unix_time()
|
||||
}
|
||||
|
||||
fn bar<T>(payload string) ?Bar { // ?T doesn't work currently
|
||||
result := json.decode(T, payload)?
|
||||
fn bar<T>(payload string) !Bar { // ?T doesn't work currently
|
||||
result := json.decode(T, payload)!
|
||||
return result
|
||||
}
|
||||
|
||||
@ -135,11 +135,11 @@ struct User {
|
||||
pets string [json: 'pet_animals'; raw]
|
||||
}
|
||||
|
||||
fn test_parse_user() ? {
|
||||
fn test_parse_user() {
|
||||
s := '{"age": 10, "nums": [1,2,3], "type": 1, "lastName": "Johnson", "IsRegistered": true, "pet_animals": {"name": "Bob", "animal": "Dog"}}'
|
||||
u2 := json.decode(User2, s)?
|
||||
u2 := json.decode(User2, s)!
|
||||
// println(u2)
|
||||
u := json.decode(User, s)?
|
||||
u := json.decode(User, s)!
|
||||
// println(u)
|
||||
assert u.age == 10
|
||||
assert u.last_name == 'Johnson'
|
||||
@ -152,7 +152,7 @@ fn test_parse_user() ? {
|
||||
assert u.pets == '{"name":"Bob","animal":"Dog"}'
|
||||
}
|
||||
|
||||
fn test_encode_decode_time() ? {
|
||||
fn test_encode_decode_time() {
|
||||
user := User2{
|
||||
age: 25
|
||||
reg_date: time.new_time(year: 2020, month: 12, day: 22, hour: 7, minute: 23)
|
||||
@ -160,7 +160,7 @@ fn test_encode_decode_time() ? {
|
||||
s := json.encode(user)
|
||||
// println(s)
|
||||
assert s.contains('"reg_date":1608621780')
|
||||
user2 := json.decode(User2, s)?
|
||||
user2 := json.decode(User2, s)!
|
||||
assert user2.reg_date.str() == '2020-12-22 07:23:00'
|
||||
// println(user2)
|
||||
// println(user2.reg_date)
|
||||
@ -219,8 +219,8 @@ struct Country {
|
||||
name string
|
||||
}
|
||||
|
||||
fn test_struct_in_struct() ? {
|
||||
country := json.decode(Country, '{ "name": "UK", "cities": [{"name":"London"}, {"name":"Manchester"}]}')?
|
||||
fn test_struct_in_struct() {
|
||||
country := json.decode(Country, '{ "name": "UK", "cities": [{"name":"London"}, {"name":"Manchester"}]}')!
|
||||
assert country.name == 'UK'
|
||||
assert country.cities.len == 2
|
||||
assert country.cities[0].name == 'London'
|
||||
@ -241,14 +241,14 @@ fn test_encode_map() {
|
||||
assert out == expected
|
||||
}
|
||||
|
||||
fn test_parse_map() ? {
|
||||
fn test_parse_map() {
|
||||
expected := {
|
||||
'one': 1
|
||||
'two': 2
|
||||
'three': 3
|
||||
'four': 4
|
||||
}
|
||||
out := json.decode(map[string]int, '{"one":1,"two":2,"three":3,"four":4}')?
|
||||
out := json.decode(map[string]int, '{"one":1,"two":2,"three":3,"four":4}')!
|
||||
// println(out)
|
||||
assert out == expected
|
||||
}
|
||||
@ -259,7 +259,7 @@ struct Data {
|
||||
extra map[string]map[string]int
|
||||
}
|
||||
|
||||
fn test_nested_type() ? {
|
||||
fn test_nested_type() {
|
||||
data_expected := '{"countries":[{"cities":[{"name":"London"},{"name":"Manchester"}],"name":"UK"},{"cities":[{"name":"Donlon"},{"name":"Termanches"}],"name":"KU"}],"users":{"Foo":{"age":10,"nums":[1,2,3],"lastName":"Johnson","IsRegistered":true,"type":0,"pet_animals":"little foo"},"Boo":{"age":20,"nums":[5,3,1],"lastName":"Smith","IsRegistered":false,"type":4,"pet_animals":"little boo"}},"extra":{"2":{"n1":2,"n2":4,"n3":8,"n4":16},"3":{"n1":3,"n2":9,"n3":27,"n4":81}}}'
|
||||
data := Data{
|
||||
countries: [
|
||||
@ -308,7 +308,7 @@ fn test_nested_type() ? {
|
||||
out := json.encode(data)
|
||||
// println(out)
|
||||
assert out == data_expected
|
||||
data2 := json.decode(Data, data_expected)?
|
||||
data2 := json.decode(Data, data_expected)!
|
||||
assert data2.countries.len == data.countries.len
|
||||
for i in 0 .. 1 {
|
||||
assert data2.countries[i].name == data.countries[i].name
|
||||
@ -338,11 +338,11 @@ pub:
|
||||
data T
|
||||
}
|
||||
|
||||
fn test_generic_struct() ? {
|
||||
fn test_generic_struct() {
|
||||
foo_int := Foo<int>{'bar', 12}
|
||||
foo_enc := json.encode(foo_int)
|
||||
assert foo_enc == '{"name":"bar","data":12}'
|
||||
foo_dec := json.decode(Foo<int>, foo_enc)?
|
||||
foo_dec := json.decode(Foo<int>, foo_enc)!
|
||||
assert foo_dec.name == 'bar'
|
||||
assert foo_dec.data == 12
|
||||
}
|
||||
@ -376,8 +376,8 @@ struct Message {
|
||||
id ID
|
||||
}
|
||||
|
||||
fn test_decode_alias_struct() ? {
|
||||
msg := json.decode(Message, '{"id": "118499178790780929"}')?
|
||||
fn test_decode_alias_struct() {
|
||||
msg := json.decode(Message, '{"id": "118499178790780929"}')!
|
||||
// hacky way of comparing aliased strings
|
||||
assert msg.id.str() == '118499178790780929'
|
||||
}
|
||||
@ -394,20 +394,20 @@ struct List {
|
||||
items []string
|
||||
}
|
||||
|
||||
fn test_list() ? {
|
||||
list := json.decode(List, '{"id": 1, "items": ["1", "2"]}')?
|
||||
fn test_list() {
|
||||
list := json.decode(List, '{"id": 1, "items": ["1", "2"]}')!
|
||||
assert list.id == 1
|
||||
assert list.items == ['1', '2']
|
||||
}
|
||||
|
||||
fn test_list_no_id() ? {
|
||||
list := json.decode(List, '{"items": ["1", "2"]}')?
|
||||
fn test_list_no_id() {
|
||||
list := json.decode(List, '{"items": ["1", "2"]}')!
|
||||
assert list.id == 0
|
||||
assert list.items == ['1', '2']
|
||||
}
|
||||
|
||||
fn test_list_no_items() ? {
|
||||
list := json.decode(List, '{"id": 1}')?
|
||||
fn test_list_no_items() {
|
||||
list := json.decode(List, '{"id": 1}')!
|
||||
assert list.id == 1
|
||||
assert list.items == []
|
||||
}
|
||||
@ -418,15 +418,15 @@ struct Info {
|
||||
maps map[string]string
|
||||
}
|
||||
|
||||
fn test_decode_null_object() ? {
|
||||
info := json.decode(Info, '{"id": 22, "items": null, "maps": null}')?
|
||||
fn test_decode_null_object() {
|
||||
info := json.decode(Info, '{"id": 22, "items": null, "maps": null}')!
|
||||
assert info.id == 22
|
||||
assert '$info.items' == '[]'
|
||||
assert '$info.maps' == '{}'
|
||||
}
|
||||
|
||||
fn test_decode_missing_maps_field() ? {
|
||||
info := json.decode(Info, '{"id": 22, "items": null}')?
|
||||
fn test_decode_missing_maps_field() {
|
||||
info := json.decode(Info, '{"id": 22, "items": null}')!
|
||||
assert info.id == 22
|
||||
assert '$info.items' == '[]'
|
||||
assert '$info.maps' == '{}'
|
||||
|
@ -9,37 +9,37 @@ pub mut:
|
||||
}
|
||||
|
||||
// connect to db
|
||||
pub fn (mut conn Connection) connect(conn_str string) ?bool {
|
||||
pub fn (mut conn Connection) connect(conn_str string) !bool {
|
||||
conn_str_c := unsafe { &C.SQLCHAR(conn_str.str) }
|
||||
mut retcode := C.SQLRETURN(C.SQL_SUCCESS)
|
||||
// Allocate environment handle
|
||||
retcode = C.SQLAllocHandle(C.SQLSMALLINT(C.SQL_HANDLE_ENV), C.SQLHANDLE(C.SQL_NULL_HANDLE),
|
||||
unsafe { &C.SQLHANDLE(&conn.henv) })
|
||||
check_error(retcode, 'SQLAllocHandle(SQL_HANDLE_ENV)', C.SQLHANDLE(conn.henv), C.SQLSMALLINT(C.SQL_HANDLE_ENV))?
|
||||
check_error(retcode, 'SQLAllocHandle(SQL_HANDLE_ENV)', C.SQLHANDLE(conn.henv), C.SQLSMALLINT(C.SQL_HANDLE_ENV))!
|
||||
|
||||
// Set the ODBC version environment attribute
|
||||
retcode = C.SQLSetEnvAttr(conn.henv, C.SQLINTEGER(C.SQL_ATTR_ODBC_VERSION), &C.SQLPOINTER(C.SQL_OV_ODBC3),
|
||||
C.SQLINTEGER(0))
|
||||
check_error(retcode, 'SQLSetEnvAttr(SQL_ATTR_ODBC_VERSION)', C.SQLHANDLE(conn.henv),
|
||||
C.SQLSMALLINT(C.SQL_HANDLE_ENV))?
|
||||
C.SQLSMALLINT(C.SQL_HANDLE_ENV))!
|
||||
|
||||
// Allocate connection handle
|
||||
retcode = C.SQLAllocHandle(C.SQLSMALLINT(C.SQL_HANDLE_DBC), C.SQLHANDLE(conn.henv),
|
||||
unsafe { &C.SQLHANDLE(&conn.hdbc) })
|
||||
check_error(retcode, 'SQLAllocHandle(SQL_HANDLE_DBC)', C.SQLHANDLE(conn.hdbc), C.SQLSMALLINT(C.SQL_HANDLE_DBC))?
|
||||
check_error(retcode, 'SQLAllocHandle(SQL_HANDLE_DBC)', C.SQLHANDLE(conn.hdbc), C.SQLSMALLINT(C.SQL_HANDLE_DBC))!
|
||||
|
||||
// Set login timeout to 5 seconds
|
||||
retcode = C.SQLSetConnectAttr(conn.hdbc, C.SQLINTEGER(C.SQL_LOGIN_TIMEOUT), C.SQLPOINTER(5),
|
||||
C.SQLINTEGER(0))
|
||||
check_error(retcode, 'SQLSetConnectAttr(SQL_LOGIN_TIMEOUT)', C.SQLHANDLE(conn.hdbc),
|
||||
C.SQLSMALLINT(C.SQL_HANDLE_DBC))?
|
||||
C.SQLSMALLINT(C.SQL_HANDLE_DBC))!
|
||||
|
||||
// Connect to data source
|
||||
mut outstr := [1024]char{}
|
||||
mut outstrlen := C.SQLSMALLINT(0)
|
||||
retcode = C.SQLDriverConnect(conn.hdbc, C.SQLHWND(0), conn_str_c, C.SQLSMALLINT(C.SQL_NTS),
|
||||
&C.SQLCHAR(&outstr[0]), C.SQLSMALLINT(sizeof(outstr)), &outstrlen, C.SQLUSMALLINT(C.SQL_DRIVER_NOPROMPT))
|
||||
check_error(retcode, 'SQLDriverConnect()', C.SQLHANDLE(conn.hdbc), C.SQLSMALLINT(C.SQL_HANDLE_DBC))?
|
||||
check_error(retcode, 'SQLDriverConnect()', C.SQLHANDLE(conn.hdbc), C.SQLSMALLINT(C.SQL_HANDLE_DBC))!
|
||||
conn.conn_str = conn_str
|
||||
return true
|
||||
}
|
||||
@ -60,18 +60,18 @@ pub fn (mut conn Connection) close() {
|
||||
}
|
||||
|
||||
// query executes a sql query
|
||||
pub fn (mut conn Connection) query(q string) ?Result {
|
||||
mut hstmt := new_hstmt(conn.hdbc)?
|
||||
pub fn (mut conn Connection) query(q string) !Result {
|
||||
mut hstmt := new_hstmt(conn.hdbc)!
|
||||
defer {
|
||||
hstmt.close()
|
||||
}
|
||||
|
||||
hstmt.exec(q)?
|
||||
hstmt.exec(q)!
|
||||
|
||||
affected := hstmt.retrieve_affected_rows()?
|
||||
affected := hstmt.retrieve_affected_rows()!
|
||||
|
||||
hstmt.prepare_read()?
|
||||
raw_rows := hstmt.read_rows()?
|
||||
hstmt.prepare_read()!
|
||||
raw_rows := hstmt.read_rows()!
|
||||
|
||||
mut res := Result{
|
||||
rows: []Row{}
|
||||
@ -88,7 +88,7 @@ pub fn (mut conn Connection) query(q string) ?Result {
|
||||
}
|
||||
|
||||
// check_error checks odbc return code and extract error string if available
|
||||
fn check_error(e C.SQLRETURN, s string, h C.SQLHANDLE, t C.SQLSMALLINT) ? {
|
||||
fn check_error(e C.SQLRETURN, s string, h C.SQLHANDLE, t C.SQLSMALLINT) ! {
|
||||
if e != C.SQLRETURN(C.SQL_SUCCESS) && e != C.SQLRETURN(C.SQL_SUCCESS_WITH_INFO) {
|
||||
err_str := extract_error(s, h, t)
|
||||
return error(err_str)
|
||||
|
@ -16,12 +16,12 @@ mut:
|
||||
}
|
||||
|
||||
// new_hstmt constructs a new statement handle
|
||||
fn new_hstmt(hdbc C.SQLHDBC) ?HStmt {
|
||||
fn new_hstmt(hdbc C.SQLHDBC) !HStmt {
|
||||
mut retcode := C.SQLRETURN(C.SQL_SUCCESS)
|
||||
mut hstmt := C.SQLHSTMT(C.SQL_NULL_HSTMT)
|
||||
// Allocate statement handle
|
||||
retcode = C.SQLAllocHandle(C.SQLSMALLINT(C.SQL_HANDLE_STMT), C.SQLHANDLE(hdbc), unsafe { &C.SQLHANDLE(&hstmt) })
|
||||
check_error(retcode, 'SQLAllocHandle(SQL_HANDLE_STMT)', C.SQLHANDLE(hstmt), C.SQLSMALLINT(C.SQL_HANDLE_STMT))?
|
||||
check_error(retcode, 'SQLAllocHandle(SQL_HANDLE_STMT)', C.SQLHANDLE(hstmt), C.SQLSMALLINT(C.SQL_HANDLE_STMT))!
|
||||
|
||||
return HStmt{
|
||||
hdbc: hdbc
|
||||
@ -40,32 +40,32 @@ fn (mut h HStmt) close() {
|
||||
}
|
||||
|
||||
// exec executes a Sql statement. Result is stored in odbc driver, and not yet read.
|
||||
fn (h HStmt) exec(sql string) ? {
|
||||
fn (h HStmt) exec(sql string) ! {
|
||||
retcode := C.SQLExecDirect(h.hstmt, sql.str, C.SQLINTEGER(C.SQL_NTS))
|
||||
check_error(retcode, 'SQLExecDirect()', C.SQLHANDLE(h.hstmt), C.SQLSMALLINT(C.SQL_HANDLE_STMT))?
|
||||
check_error(retcode, 'SQLExecDirect()', C.SQLHANDLE(h.hstmt), C.SQLSMALLINT(C.SQL_HANDLE_STMT))!
|
||||
}
|
||||
|
||||
// retrieve_affected_rows returns number of rows affected/modified by the last operation. -1 if not applicable.
|
||||
fn (h HStmt) retrieve_affected_rows() ?int {
|
||||
fn (h HStmt) retrieve_affected_rows() !int {
|
||||
count_ret := C.SQLLEN(0)
|
||||
retcode := C.SQLRowCount(h.hstmt, &count_ret)
|
||||
check_error(retcode, 'SQLRowCount()', C.SQLHANDLE(h.hstmt), C.SQLSMALLINT(C.SQL_HANDLE_STMT))?
|
||||
check_error(retcode, 'SQLRowCount()', C.SQLHANDLE(h.hstmt), C.SQLSMALLINT(C.SQL_HANDLE_STMT))!
|
||||
return int(count_ret)
|
||||
}
|
||||
|
||||
fn (h HStmt) retrieve_column_count() ?int {
|
||||
fn (h HStmt) retrieve_column_count() !int {
|
||||
mut retcode := C.SQLRETURN(C.SQL_SUCCESS)
|
||||
col_count_buff := C.SQLSMALLINT(0)
|
||||
retcode = C.SQLNumResultCols(h.hstmt, &col_count_buff)
|
||||
check_error(retcode, 'SQLNumResultCols()', C.SQLHANDLE(h.hstmt), C.SQLSMALLINT(C.SQL_HANDLE_STMT))?
|
||||
check_error(retcode, 'SQLNumResultCols()', C.SQLHANDLE(h.hstmt), C.SQLSMALLINT(C.SQL_HANDLE_STMT))!
|
||||
return int(col_count_buff)
|
||||
}
|
||||
|
||||
// allocate buffers and bind them to drivers
|
||||
fn (mut h HStmt) prepare_read() ? {
|
||||
fn (mut h HStmt) prepare_read() ! {
|
||||
mut retcode := C.SQLRETURN(C.SQL_SUCCESS)
|
||||
|
||||
column_count := h.retrieve_column_count()?
|
||||
column_count := h.retrieve_column_count()!
|
||||
h.column_count = column_count // remember the count because read will need it
|
||||
|
||||
h.buffers = [][]char{len: h.column_count}
|
||||
@ -77,7 +77,7 @@ fn (mut h HStmt) prepare_read() ? {
|
||||
// find out buffer size needed to read data in this column
|
||||
retcode = C.SQLColAttribute(h.hstmt, i_col, C.SQLUSMALLINT(C.SQL_DESC_LENGTH),
|
||||
C.SQLPOINTER(0), C.SQLSMALLINT(0), C.SQLSMALLINT(0), &size_ret)
|
||||
check_error(retcode, 'SQLColAttribute()', C.SQLHANDLE(h.hstmt), C.SQLSMALLINT(C.SQL_HANDLE_STMT))?
|
||||
check_error(retcode, 'SQLColAttribute()', C.SQLHANDLE(h.hstmt), C.SQLSMALLINT(C.SQL_HANDLE_STMT))!
|
||||
|
||||
// buffer allocation is the size + 1 to include termination char, since SQL_DESC_LENGTH does not include it.
|
||||
allocate_size := size_ret + C.SQLLEN(1)
|
||||
@ -87,7 +87,7 @@ fn (mut h HStmt) prepare_read() ? {
|
||||
// bind the buffer
|
||||
retcode = C.SQLBindCol(h.hstmt, C.SQLUSMALLINT(i_col), C.SQLSMALLINT(C.SQL_C_CHAR),
|
||||
C.SQLPOINTER(&buff[0]), allocate_size, &h.indicators[i])
|
||||
check_error(retcode, 'SQLBindCol()', C.SQLHANDLE(h.hstmt), C.SQLSMALLINT(C.SQL_HANDLE_STMT))?
|
||||
check_error(retcode, 'SQLBindCol()', C.SQLHANDLE(h.hstmt), C.SQLSMALLINT(C.SQL_HANDLE_STMT))!
|
||||
|
||||
// record the buffer in HStmt
|
||||
h.buffers[i] = buff
|
||||
@ -95,7 +95,7 @@ fn (mut h HStmt) prepare_read() ? {
|
||||
}
|
||||
|
||||
// fetch all rows
|
||||
fn (h HStmt) read_rows() ?[][]string {
|
||||
fn (h HStmt) read_rows() ![][]string {
|
||||
mut retcode := C.SQLRETURN(C.SQL_SUCCESS)
|
||||
|
||||
mut res := [][]string{}
|
||||
@ -116,7 +116,7 @@ fn (h HStmt) read_rows() ?[][]string {
|
||||
}
|
||||
} else {
|
||||
if retcode != C.SQLRETURN(C.SQL_NO_DATA) {
|
||||
check_error(retcode, 'SQLFetch()', C.SQLHANDLE(h.hstmt), C.SQLSMALLINT(C.SQL_HANDLE_STMT))?
|
||||
check_error(retcode, 'SQLFetch()', C.SQLHANDLE(h.hstmt), C.SQLSMALLINT(C.SQL_HANDLE_STMT))!
|
||||
} else {
|
||||
break
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ pub mut:
|
||||
}
|
||||
|
||||
// connect - create a new connection to the MySQL server.
|
||||
pub fn (mut conn Connection) connect() ?bool {
|
||||
pub fn (mut conn Connection) connect() !bool {
|
||||
instance := C.mysql_init(conn.conn)
|
||||
conn.conn = C.mysql_real_connect(instance, conn.host.str, conn.username.str, conn.password.str,
|
||||
conn.dbname.str, conn.port, 0, conn.flag)
|
||||
@ -50,7 +50,7 @@ pub fn (mut conn Connection) connect() ?bool {
|
||||
// query - make an SQL query and receive the results.
|
||||
// `query()` cannot be used for statements that contain binary data;
|
||||
// Use `real_query()` instead.
|
||||
pub fn (conn Connection) query(q string) ?Result {
|
||||
pub fn (conn Connection) query(q string) !Result {
|
||||
if C.mysql_query(conn.conn, q.str) != 0 {
|
||||
return error_with_code(get_error_msg(conn.conn), get_errno(conn.conn))
|
||||
}
|
||||
@ -75,7 +75,7 @@ pub fn (conn Connection) use_result() {
|
||||
// (Binary data may contain the `\0` character, which `query()`
|
||||
// interprets as the end of the statement string). In addition,
|
||||
// `real_query()` is faster than `query()`.
|
||||
pub fn (mut conn Connection) real_query(q string) ?Result {
|
||||
pub fn (mut conn Connection) real_query(q string) !Result {
|
||||
if C.mysql_real_query(conn.conn, q.str, q.len) != 0 {
|
||||
return error_with_code(get_error_msg(conn.conn), get_errno(conn.conn))
|
||||
}
|
||||
@ -84,7 +84,7 @@ pub fn (mut conn Connection) real_query(q string) ?Result {
|
||||
}
|
||||
|
||||
// select_db - change the default database for database queries.
|
||||
pub fn (mut conn Connection) select_db(dbname string) ?bool {
|
||||
pub fn (mut conn Connection) select_db(dbname string) !bool {
|
||||
if C.mysql_select_db(conn.conn, dbname.str) != 0 {
|
||||
return error_with_code(get_error_msg(conn.conn), get_errno(conn.conn))
|
||||
}
|
||||
@ -94,7 +94,7 @@ pub fn (mut conn Connection) select_db(dbname string) ?bool {
|
||||
// change_user - change the mysql user for the connection.
|
||||
// Passing an empty string for the `dbname` parameter, resultsg in only changing
|
||||
// the user and not changing the default database for the connection.
|
||||
pub fn (mut conn Connection) change_user(username string, password string, dbname string) ?bool {
|
||||
pub fn (mut conn Connection) change_user(username string, password string, dbname string) !bool {
|
||||
mut ret := true
|
||||
if dbname != '' {
|
||||
ret = C.mysql_change_user(conn.conn, username.str, password.str, dbname.str)
|
||||
@ -124,7 +124,7 @@ pub fn (mut conn Connection) autocommit(mode bool) {
|
||||
// The `wildcard` parameter may contain the wildcard characters `%` or `_`.
|
||||
// If an empty string is passed, it will return all tables.
|
||||
// Calling `tables()` is similar to executing query `SHOW TABLES [LIKE wildcard]`.
|
||||
pub fn (conn &Connection) tables(wildcard string) ?[]string {
|
||||
pub fn (conn &Connection) tables(wildcard string) ![]string {
|
||||
cres := C.mysql_list_tables(conn.conn, wildcard.str)
|
||||
if isnil(cres) {
|
||||
return error_with_code(get_error_msg(conn.conn), get_errno(conn.conn))
|
||||
@ -157,7 +157,7 @@ pub fn (mut conn Connection) set_option(option_type int, val voidptr) {
|
||||
|
||||
// get_option - return the value of an option, settable by `set_option`.
|
||||
// https://dev.mysql.com/doc/c-api/5.7/en/mysql-get-option.html
|
||||
pub fn (conn &Connection) get_option(option_type int) ?voidptr {
|
||||
pub fn (conn &Connection) get_option(option_type int) !voidptr {
|
||||
ret := unsafe { nil }
|
||||
if C.mysql_get_option(conn.conn, option_type, &ret) != 0 {
|
||||
return error_with_code(get_error_msg(conn.conn), get_errno(conn.conn))
|
||||
@ -167,7 +167,7 @@ pub fn (conn &Connection) get_option(option_type int) ?voidptr {
|
||||
|
||||
// refresh - flush the tables or caches, or resets replication server
|
||||
// information. The connected user must have the `RELOAD` privilege.
|
||||
pub fn (mut conn Connection) refresh(options u32) ?bool {
|
||||
pub fn (mut conn Connection) refresh(options u32) !bool {
|
||||
if C.mysql_refresh(conn.conn, options) != 0 {
|
||||
return error_with_code(get_error_msg(conn.conn), get_errno(conn.conn))
|
||||
}
|
||||
@ -175,7 +175,7 @@ pub fn (mut conn Connection) refresh(options u32) ?bool {
|
||||
}
|
||||
|
||||
// reset - resets the connection, and clear the session state.
|
||||
pub fn (mut conn Connection) reset() ?bool {
|
||||
pub fn (mut conn Connection) reset() !bool {
|
||||
if C.mysql_reset_connection(conn.conn) != 0 {
|
||||
return error_with_code(get_error_msg(conn.conn), get_errno(conn.conn))
|
||||
}
|
||||
@ -184,7 +184,7 @@ pub fn (mut conn Connection) reset() ?bool {
|
||||
|
||||
// ping - pings a server connection, or tries to reconnect if the connection
|
||||
// has gone down.
|
||||
pub fn (mut conn Connection) ping() ?bool {
|
||||
pub fn (mut conn Connection) ping() !bool {
|
||||
if C.mysql_ping(conn.conn) != 0 {
|
||||
return error_with_code(get_error_msg(conn.conn), get_errno(conn.conn))
|
||||
}
|
||||
@ -224,7 +224,7 @@ pub fn (conn &Connection) get_server_version() u64 {
|
||||
|
||||
// dump_debug_info - instructs the server to write debugging information
|
||||
// to the error log. The connected user must have the `SUPER` privilege.
|
||||
pub fn (mut conn Connection) dump_debug_info() ?bool {
|
||||
pub fn (mut conn Connection) dump_debug_info() !bool {
|
||||
if C.mysql_dump_debug_info(conn.conn) != 0 {
|
||||
return error_with_code(get_error_msg(conn.conn), get_errno(conn.conn))
|
||||
}
|
||||
|
@ -7,20 +7,20 @@ type Prims = f32 | f64 | i16 | i64 | i8 | int | string | u16 | u32 | u64 | u8
|
||||
|
||||
// sql expr
|
||||
|
||||
pub fn (db Connection) @select(config orm.SelectConfig, data orm.QueryData, where orm.QueryData) ?[][]orm.Primitive {
|
||||
pub fn (db Connection) @select(config orm.SelectConfig, data orm.QueryData, where orm.QueryData) ![][]orm.Primitive {
|
||||
query := orm.orm_select_gen(config, '`', false, '?', 0, where)
|
||||
mut ret := [][]orm.Primitive{}
|
||||
mut stmt := db.init_stmt(query)
|
||||
stmt.prepare()?
|
||||
stmt.prepare()!
|
||||
|
||||
mysql_stmt_binder(mut stmt, where)?
|
||||
mysql_stmt_binder(mut stmt, data)?
|
||||
mysql_stmt_binder(mut stmt, where)!
|
||||
mysql_stmt_binder(mut stmt, data)!
|
||||
|
||||
if data.data.len > 0 || where.data.len > 0 {
|
||||
stmt.bind_params()?
|
||||
stmt.bind_params()!
|
||||
}
|
||||
|
||||
mut status := stmt.execute()?
|
||||
mut status := stmt.execute()!
|
||||
num_fields := stmt.get_field_count()
|
||||
metadata := stmt.gen_metadata()
|
||||
fields := stmt.fetch_fields(metadata)
|
||||
@ -99,30 +99,30 @@ pub fn (db Connection) @select(config orm.SelectConfig, data orm.QueryData, wher
|
||||
}
|
||||
}
|
||||
|
||||
stmt.bind_result_buffer()?
|
||||
stmt.store_result()?
|
||||
stmt.bind_result_buffer()!
|
||||
stmt.store_result()!
|
||||
for {
|
||||
status = stmt.fetch_stmt()?
|
||||
status = stmt.fetch_stmt()!
|
||||
|
||||
if status == 1 || status == 100 {
|
||||
break
|
||||
}
|
||||
row++
|
||||
|
||||
data_list := buffer_to_primitive(dataptr, types, field_types)?
|
||||
data_list := buffer_to_primitive(dataptr, types, field_types)!
|
||||
ret << data_list
|
||||
}
|
||||
|
||||
stmt.close()?
|
||||
stmt.close()!
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// sql stmt
|
||||
|
||||
pub fn (db Connection) insert(table string, data orm.QueryData) ? {
|
||||
pub fn (db Connection) insert(table string, data orm.QueryData) ! {
|
||||
mut converted_primitive_array := db.factory_orm_primitive_converted_from_sql(table,
|
||||
data)?
|
||||
data)!
|
||||
|
||||
converted_primitive_data := orm.QueryData{
|
||||
fields: data.fields
|
||||
@ -134,18 +134,18 @@ pub fn (db Connection) insert(table string, data orm.QueryData) ? {
|
||||
|
||||
query, converted_data := orm.orm_stmt_gen(table, '`', .insert, false, '?', 1, converted_primitive_data,
|
||||
orm.QueryData{})
|
||||
mysql_stmt_worker(db, query, converted_data, orm.QueryData{})?
|
||||
mysql_stmt_worker(db, query, converted_data, orm.QueryData{})!
|
||||
}
|
||||
|
||||
pub fn (db Connection) update(table string, data orm.QueryData, where orm.QueryData) ? {
|
||||
pub fn (db Connection) update(table string, data orm.QueryData, where orm.QueryData) ! {
|
||||
query, _ := orm.orm_stmt_gen(table, '`', .update, false, '?', 1, data, where)
|
||||
mysql_stmt_worker(db, query, data, where)?
|
||||
mysql_stmt_worker(db, query, data, where)!
|
||||
}
|
||||
|
||||
pub fn (db Connection) delete(table string, where orm.QueryData) ? {
|
||||
pub fn (db Connection) delete(table string, where orm.QueryData) ! {
|
||||
query, _ := orm.orm_stmt_gen(table, '`', .delete, false, '?', 1, orm.QueryData{},
|
||||
where)
|
||||
mysql_stmt_worker(db, query, orm.QueryData{}, where)?
|
||||
mysql_stmt_worker(db, query, orm.QueryData{}, where)!
|
||||
}
|
||||
|
||||
pub fn (db Connection) last_id() orm.Primitive {
|
||||
@ -159,31 +159,31 @@ pub fn (db Connection) last_id() orm.Primitive {
|
||||
}
|
||||
|
||||
// table
|
||||
pub fn (db Connection) create(table string, fields []orm.TableField) ? {
|
||||
pub fn (db Connection) create(table string, fields []orm.TableField) ! {
|
||||
query := orm.orm_table_gen(table, '`', true, 0, fields, mysql_type_from_v, false) or {
|
||||
return err
|
||||
}
|
||||
mysql_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})?
|
||||
mysql_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})!
|
||||
}
|
||||
|
||||
pub fn (db Connection) drop(table string) ? {
|
||||
pub fn (db Connection) drop(table string) ! {
|
||||
query := 'DROP TABLE `$table`;'
|
||||
mysql_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})?
|
||||
mysql_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})!
|
||||
}
|
||||
|
||||
fn mysql_stmt_worker(db Connection, query string, data orm.QueryData, where orm.QueryData) ? {
|
||||
fn mysql_stmt_worker(db Connection, query string, data orm.QueryData, where orm.QueryData) ! {
|
||||
mut stmt := db.init_stmt(query)
|
||||
stmt.prepare()?
|
||||
mysql_stmt_binder(mut stmt, data)?
|
||||
mysql_stmt_binder(mut stmt, where)?
|
||||
stmt.prepare()!
|
||||
mysql_stmt_binder(mut stmt, data)!
|
||||
mysql_stmt_binder(mut stmt, where)!
|
||||
if data.data.len > 0 || where.data.len > 0 {
|
||||
stmt.bind_params()?
|
||||
stmt.bind_params()!
|
||||
}
|
||||
stmt.execute()?
|
||||
stmt.close()?
|
||||
stmt.execute()!
|
||||
stmt.close()!
|
||||
}
|
||||
|
||||
fn mysql_stmt_binder(mut stmt Stmt, d orm.QueryData) ? {
|
||||
fn mysql_stmt_binder(mut stmt Stmt, d orm.QueryData) ! {
|
||||
for data in d.data {
|
||||
stmt_binder_match(mut stmt, data)
|
||||
}
|
||||
@ -237,7 +237,7 @@ fn stmt_binder_match(mut stmt Stmt, data orm.Primitive) {
|
||||
}
|
||||
}
|
||||
|
||||
fn buffer_to_primitive(data_list []&u8, types []int, field_types []FieldType) ?[]orm.Primitive {
|
||||
fn buffer_to_primitive(data_list []&u8, types []int, field_types []FieldType) ![]orm.Primitive {
|
||||
mut res := []orm.Primitive{}
|
||||
|
||||
for i, data in data_list {
|
||||
@ -287,7 +287,7 @@ fn buffer_to_primitive(data_list []&u8, types []int, field_types []FieldType) ?[
|
||||
}
|
||||
.type_datetime {
|
||||
string_time := unsafe { cstring_to_vstring(&char(data)) }
|
||||
primitive = time.parse(string_time)?
|
||||
primitive = time.parse(string_time)!
|
||||
}
|
||||
else {}
|
||||
}
|
||||
@ -302,7 +302,7 @@ fn buffer_to_primitive(data_list []&u8, types []int, field_types []FieldType) ?[
|
||||
return res
|
||||
}
|
||||
|
||||
fn mysql_type_from_v(typ int) ?string {
|
||||
fn mysql_type_from_v(typ int) !string {
|
||||
str := match typ {
|
||||
orm.type_idx['i8'], orm.type_idx['u8'] {
|
||||
'TINYINT'
|
||||
@ -341,8 +341,8 @@ fn mysql_type_from_v(typ int) ?string {
|
||||
return str
|
||||
}
|
||||
|
||||
fn (db Connection) factory_orm_primitive_converted_from_sql(table string, data orm.QueryData) ?[]orm.Primitive {
|
||||
mut map_val := db.get_table_data_type_map(table)?
|
||||
fn (db Connection) factory_orm_primitive_converted_from_sql(table string, data orm.QueryData) ![]orm.Primitive {
|
||||
mut map_val := db.get_table_data_type_map(table)!
|
||||
|
||||
// adapt v type to sql time
|
||||
mut converted_data := []orm.Primitive{}
|
||||
@ -363,11 +363,11 @@ fn (db Connection) factory_orm_primitive_converted_from_sql(table string, data o
|
||||
return converted_data
|
||||
}
|
||||
|
||||
fn (db Connection) get_table_data_type_map(table string) ?map[string]string {
|
||||
fn (db Connection) get_table_data_type_map(table string) !map[string]string {
|
||||
data_type_querys := "SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '$table'"
|
||||
mut map_val := map[string]string{}
|
||||
|
||||
results := db.query(data_type_querys)?
|
||||
results := db.query(data_type_querys)!
|
||||
db.use_result()
|
||||
|
||||
for row in results.rows() {
|
||||
|
@ -78,21 +78,21 @@ pub fn (db Connection) init_stmt(query string) Stmt {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (stmt Stmt) prepare() ? {
|
||||
pub fn (stmt Stmt) prepare() ! {
|
||||
res := C.mysql_stmt_prepare(stmt.stmt, stmt.query.str, stmt.query.len)
|
||||
if res != 0 && stmt.get_error_msg() != '' {
|
||||
return stmt.error(res)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (stmt Stmt) bind_params() ? {
|
||||
pub fn (stmt Stmt) bind_params() ! {
|
||||
res := C.mysql_stmt_bind_param(stmt.stmt, &C.MYSQL_BIND(stmt.binds.data))
|
||||
if res && stmt.get_error_msg() != '' {
|
||||
return stmt.error(1)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (stmt Stmt) execute() ?int {
|
||||
pub fn (stmt Stmt) execute() !int {
|
||||
res := C.mysql_stmt_execute(stmt.stmt)
|
||||
if res != 0 && stmt.get_error_msg() != '' {
|
||||
return stmt.error(res)
|
||||
@ -100,7 +100,7 @@ pub fn (stmt Stmt) execute() ?int {
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (stmt Stmt) next() ?int {
|
||||
pub fn (stmt Stmt) next() !int {
|
||||
res := C.mysql_stmt_next_result(stmt.stmt)
|
||||
if res > 0 && stmt.get_error_msg() != '' {
|
||||
return stmt.error(res)
|
||||
@ -116,7 +116,7 @@ pub fn (stmt Stmt) fetch_fields(res &C.MYSQL_RES) &C.MYSQL_FIELD {
|
||||
return C.mysql_fetch_fields(res)
|
||||
}
|
||||
|
||||
pub fn (stmt Stmt) fetch_stmt() ?int {
|
||||
pub fn (stmt Stmt) fetch_stmt() !int {
|
||||
res := C.mysql_stmt_fetch(stmt.stmt)
|
||||
if res !in [0, 100] && stmt.get_error_msg() != '' {
|
||||
return stmt.error(res)
|
||||
@ -124,7 +124,7 @@ pub fn (stmt Stmt) fetch_stmt() ?int {
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (stmt Stmt) close() ? {
|
||||
pub fn (stmt Stmt) close() ! {
|
||||
if !C.mysql_stmt_close(stmt.stmt) && stmt.get_error_msg() != '' {
|
||||
return stmt.error(1)
|
||||
}
|
||||
@ -222,14 +222,14 @@ pub fn (mut stmt Stmt) bind_res(fields &C.MYSQL_FIELD, dataptr []&u8, lens []u32
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut stmt Stmt) bind_result_buffer() ? {
|
||||
pub fn (mut stmt Stmt) bind_result_buffer() ! {
|
||||
res := C.mysql_stmt_bind_result(stmt.stmt, &C.MYSQL_BIND(stmt.res.data))
|
||||
if res && stmt.get_error_msg() != '' {
|
||||
return stmt.error(1)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut stmt Stmt) store_result() ? {
|
||||
pub fn (mut stmt Stmt) store_result() ! {
|
||||
res := C.mysql_stmt_store_result(stmt.stmt)
|
||||
if res != 0 && stmt.get_error_msg() != '' {
|
||||
return stmt.error(res)
|
||||
|
@ -25,7 +25,7 @@ fn http_fetch_mock(_methods []string, _config FetchConfig) ![]Response {
|
||||
config.method = method_from_str(method)
|
||||
res := fetch(FetchConfig{ ...config, url: url + lmethod })!
|
||||
// TODO
|
||||
// body := json.decode(HttpbinResponseBody,res.body)?
|
||||
// body := json.decode(HttpbinResponseBody,res.body)!
|
||||
result << res
|
||||
}
|
||||
return result
|
||||
|
@ -9,8 +9,8 @@ struct MimeType {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
mt_json := http.get('https://raw.githubusercontent.com/jshttp/mime-db/master/db.json')?
|
||||
mt_map := json.decode(map[string]MimeType, mt_json.text)?
|
||||
mt_json := http.get('https://raw.githubusercontent.com/jshttp/mime-db/master/db.json')!
|
||||
mt_map := json.decode(map[string]MimeType, mt_json.text)!
|
||||
|
||||
mut ext_to_mt_str := map[string]string{}
|
||||
for mt_str, mt in mt_map {
|
||||
@ -28,6 +28,6 @@ fn main() {
|
||||
db = $mt_map
|
||||
ext_to_mt_str = $ext_to_mt_str
|
||||
)
|
||||
')?
|
||||
')!
|
||||
execute('${@VEXE} fmt -w db.v')
|
||||
}
|
||||
|
@ -170,12 +170,12 @@ pub:
|
||||
// Every function without last_id() returns an optional, which returns an error if present
|
||||
// last_id returns the last inserted id of the db
|
||||
pub interface Connection {
|
||||
@select(config SelectConfig, data QueryData, where QueryData) ?[][]Primitive
|
||||
insert(table string, data QueryData) ?
|
||||
update(table string, data QueryData, where QueryData) ?
|
||||
delete(table string, where QueryData) ?
|
||||
create(table string, fields []TableField) ?
|
||||
drop(table string) ?
|
||||
@select(config SelectConfig, data QueryData, where QueryData) ![][]Primitive
|
||||
insert(table string, data QueryData) !
|
||||
update(table string, data QueryData, where QueryData) !
|
||||
delete(table string, where QueryData) !
|
||||
create(table string, fields []TableField) !
|
||||
drop(table string) !
|
||||
last_id() Primitive
|
||||
}
|
||||
|
||||
@ -392,7 +392,7 @@ pub fn orm_select_gen(orm SelectConfig, q string, num bool, qm string, start_pos
|
||||
// fields - See TableField
|
||||
// sql_from_v - Function which maps type indices to sql type names
|
||||
// alternative - Needed for msdb
|
||||
pub fn orm_table_gen(table string, q string, defaults bool, def_unique_len int, fields []TableField, sql_from_v fn (int) ?string, alternative bool) ?string {
|
||||
pub fn orm_table_gen(table string, q string, defaults bool, def_unique_len int, fields []TableField, sql_from_v fn (int) !string, alternative bool) !string {
|
||||
mut str := 'CREATE TABLE IF NOT EXISTS $q$table$q ('
|
||||
|
||||
if alternative {
|
||||
@ -416,7 +416,7 @@ pub fn orm_table_gen(table string, q string, defaults bool, def_unique_len int,
|
||||
mut field_name := sql_field_name(field)
|
||||
mut ctyp := sql_from_v(sql_field_type(field)) or {
|
||||
field_name = '${field_name}_id'
|
||||
sql_from_v(7)?
|
||||
sql_from_v(7)!
|
||||
}
|
||||
for attr in field.attrs {
|
||||
match attr.name {
|
||||
|
@ -256,7 +256,7 @@ fn test_orm_table_gen() {
|
||||
assert mult_unique_query == "CREATE TABLE IF NOT EXISTS 'test_table' ('id' SERIAL DEFAULT 10, 'test' TEXT, 'abc' INT64 DEFAULT 6754, /* test */UNIQUE('test', 'abc'), PRIMARY KEY('id'));"
|
||||
}
|
||||
|
||||
fn sql_type_from_v(typ int) ?string {
|
||||
fn sql_type_from_v(typ int) !string {
|
||||
return if typ in orm.nums {
|
||||
'INT'
|
||||
} else if typ in orm.num64 {
|
||||
|
@ -19,7 +19,7 @@ fn testsuite_end() {
|
||||
}
|
||||
|
||||
fn test_ensure_db_exists_and_user_table_is_ok() {
|
||||
mut db := sqlite.connect(db_path)?
|
||||
mut db := sqlite.connect(db_path)!
|
||||
assert true
|
||||
|
||||
eprintln('> drop pre-existing User table...')
|
||||
@ -30,11 +30,11 @@ fn test_ensure_db_exists_and_user_table_is_ok() {
|
||||
create table User
|
||||
} or { panic(err) }
|
||||
assert true
|
||||
db.close()?
|
||||
db.close()!
|
||||
}
|
||||
|
||||
fn test_sql_or_block_for_insert() {
|
||||
mut db := sqlite.connect(db_path)?
|
||||
mut db := sqlite.connect(db_path)!
|
||||
user := User{1, 'bilbo'}
|
||||
|
||||
eprintln('> inserting user 1 (first try)...')
|
||||
@ -53,11 +53,11 @@ fn test_sql_or_block_for_insert() {
|
||||
println('user could not be inserted, err: $err')
|
||||
}
|
||||
eprintln('LINE: ${@LINE}')
|
||||
db.close()?
|
||||
db.close()!
|
||||
}
|
||||
|
||||
fn test_sql_or_block_for_select() {
|
||||
mut db := sqlite.connect(db_path)?
|
||||
mut db := sqlite.connect(db_path)!
|
||||
|
||||
eprintln('> selecting user with id 1...')
|
||||
single := sql db {
|
||||
@ -93,7 +93,7 @@ fn test_sql_or_block_for_select() {
|
||||
|
||||
assert multiple.len == 1
|
||||
eprintln('LINE: ${@LINE}')
|
||||
db.close()?
|
||||
db.close()!
|
||||
}
|
||||
|
||||
fn test_finish() {
|
||||
|
@ -6,10 +6,10 @@ import net.conv
|
||||
|
||||
// sql expr
|
||||
|
||||
pub fn (db DB) @select(config orm.SelectConfig, data orm.QueryData, where orm.QueryData) ?[][]orm.Primitive {
|
||||
pub fn (db DB) @select(config orm.SelectConfig, data orm.QueryData, where orm.QueryData) ![][]orm.Primitive {
|
||||
query := orm.orm_select_gen(config, '"', true, '$', 1, where)
|
||||
|
||||
res := pg_stmt_worker(db, query, where, data)?
|
||||
res := pg_stmt_worker(db, query, where, data)!
|
||||
|
||||
mut ret := [][]orm.Primitive{}
|
||||
|
||||
@ -19,7 +19,7 @@ pub fn (db DB) @select(config orm.SelectConfig, data orm.QueryData, where orm.Qu
|
||||
for row in res {
|
||||
mut row_data := []orm.Primitive{}
|
||||
for i, val in row.vals {
|
||||
field := str_to_primitive(val, config.types[i])?
|
||||
field := str_to_primitive(val, config.types[i])!
|
||||
row_data << field
|
||||
}
|
||||
ret << row_data
|
||||
@ -30,20 +30,20 @@ pub fn (db DB) @select(config orm.SelectConfig, data orm.QueryData, where orm.Qu
|
||||
|
||||
// sql stmt
|
||||
|
||||
pub fn (db DB) insert(table string, data orm.QueryData) ? {
|
||||
pub fn (db DB) insert(table string, data orm.QueryData) ! {
|
||||
query, converted_data := orm.orm_stmt_gen(table, '"', .insert, true, '$', 1, data,
|
||||
orm.QueryData{})
|
||||
pg_stmt_worker(db, query, converted_data, orm.QueryData{})?
|
||||
pg_stmt_worker(db, query, converted_data, orm.QueryData{})!
|
||||
}
|
||||
|
||||
pub fn (db DB) update(table string, data orm.QueryData, where orm.QueryData) ? {
|
||||
pub fn (db DB) update(table string, data orm.QueryData, where orm.QueryData) ! {
|
||||
query, _ := orm.orm_stmt_gen(table, '"', .update, true, '$', 1, data, where)
|
||||
pg_stmt_worker(db, query, data, where)?
|
||||
pg_stmt_worker(db, query, data, where)!
|
||||
}
|
||||
|
||||
pub fn (db DB) delete(table string, where orm.QueryData) ? {
|
||||
pub fn (db DB) delete(table string, where orm.QueryData) ! {
|
||||
query, _ := orm.orm_stmt_gen(table, '"', .delete, true, '$', 1, orm.QueryData{}, where)
|
||||
pg_stmt_worker(db, query, orm.QueryData{}, where)?
|
||||
pg_stmt_worker(db, query, orm.QueryData{}, where)!
|
||||
}
|
||||
|
||||
pub fn (db DB) last_id() orm.Primitive {
|
||||
@ -54,19 +54,19 @@ pub fn (db DB) last_id() orm.Primitive {
|
||||
|
||||
// table
|
||||
|
||||
pub fn (db DB) create(table string, fields []orm.TableField) ? {
|
||||
pub fn (db DB) create(table string, fields []orm.TableField) ! {
|
||||
query := orm.orm_table_gen(table, '"', true, 0, fields, pg_type_from_v, false) or { return err }
|
||||
pg_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})?
|
||||
pg_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})!
|
||||
}
|
||||
|
||||
pub fn (db DB) drop(table string) ? {
|
||||
pub fn (db DB) drop(table string) ! {
|
||||
query := 'DROP TABLE "$table";'
|
||||
pg_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})?
|
||||
pg_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})!
|
||||
}
|
||||
|
||||
// utils
|
||||
|
||||
fn pg_stmt_worker(db DB, query string, data orm.QueryData, where orm.QueryData) ?[]Row {
|
||||
fn pg_stmt_worker(db DB, query string, data orm.QueryData, where orm.QueryData) ![]Row {
|
||||
mut param_types := []u32{}
|
||||
mut param_vals := []&char{}
|
||||
mut param_lens := []int{}
|
||||
@ -185,7 +185,7 @@ fn pg_stmt_match(mut types []u32, mut vals []&char, mut lens []int, mut formats
|
||||
}
|
||||
}
|
||||
|
||||
fn pg_type_from_v(typ int) ?string {
|
||||
fn pg_type_from_v(typ int) !string {
|
||||
str := match typ {
|
||||
orm.type_idx['i8'], orm.type_idx['i16'], orm.type_idx['u8'], orm.type_idx['u16'] {
|
||||
'SMALLINT'
|
||||
@ -224,7 +224,7 @@ fn pg_type_from_v(typ int) ?string {
|
||||
return str
|
||||
}
|
||||
|
||||
fn str_to_primitive(str string, typ int) ?orm.Primitive {
|
||||
fn str_to_primitive(str string, typ int) !orm.Primitive {
|
||||
match typ {
|
||||
// bool
|
||||
orm.type_idx['bool'] {
|
||||
@ -279,7 +279,7 @@ fn str_to_primitive(str string, typ int) ?orm.Primitive {
|
||||
}
|
||||
orm.time {
|
||||
if str.contains_any(' /:-') {
|
||||
date_time_str := time.parse(str)?
|
||||
date_time_str := time.parse(str)!
|
||||
return orm.Primitive(date_time_str)
|
||||
}
|
||||
|
||||
|
30
vlib/pg/pg.v
30
vlib/pg/pg.v
@ -76,7 +76,7 @@ fn C.PQfinish(voidptr)
|
||||
// connect makes a new connection to the database server using
|
||||
// the parameters from the `Config` structure, returning
|
||||
// a connection error when something goes wrong
|
||||
pub fn connect(config Config) ?DB {
|
||||
pub fn connect(config Config) !DB {
|
||||
conninfo := 'host=$config.host port=$config.port user=$config.user dbname=$config.dbname password=$config.password'
|
||||
conn := C.PQconnectdb(conninfo.str)
|
||||
if conn == 0 {
|
||||
@ -125,8 +125,8 @@ pub fn (db DB) close() {
|
||||
// returns an the first field in the first tuple
|
||||
// converted to an int. If no row is found or on
|
||||
// command failure, an error is returned
|
||||
pub fn (db DB) q_int(query string) ?int {
|
||||
rows := db.exec(query)?
|
||||
pub fn (db DB) q_int(query string) !int {
|
||||
rows := db.exec(query)!
|
||||
if rows.len == 0 {
|
||||
return error('q_int "$query" not found')
|
||||
}
|
||||
@ -142,8 +142,8 @@ pub fn (db DB) q_int(query string) ?int {
|
||||
// returns an the first field in the first tuple
|
||||
// as a string. If no row is found or on
|
||||
// command failure, an error is returned
|
||||
pub fn (db DB) q_string(query string) ?string {
|
||||
rows := db.exec(query)?
|
||||
pub fn (db DB) q_string(query string) !string {
|
||||
rows := db.exec(query)!
|
||||
if rows.len == 0 {
|
||||
return error('q_string "$query" not found')
|
||||
}
|
||||
@ -157,37 +157,37 @@ pub fn (db DB) q_string(query string) ?string {
|
||||
|
||||
// q_strings submit a command to the database server and
|
||||
// returns the resulting row set. Alias of `exec`
|
||||
pub fn (db DB) q_strings(query string) ?[]Row {
|
||||
pub fn (db DB) q_strings(query string) ![]Row {
|
||||
return db.exec(query)
|
||||
}
|
||||
|
||||
// exec submit a command to the database server and wait
|
||||
// for the result, returning an error on failure and a
|
||||
// row set on success
|
||||
pub fn (db DB) exec(query string) ?[]Row {
|
||||
pub fn (db DB) exec(query string) ![]Row {
|
||||
res := C.PQexec(db.conn, query.str)
|
||||
return db.handle_error_or_result(res, 'exec')
|
||||
}
|
||||
|
||||
fn rows_first_or_empty(rows []Row) ?Row {
|
||||
fn rows_first_or_empty(rows []Row) !Row {
|
||||
if rows.len == 0 {
|
||||
return error('no row')
|
||||
}
|
||||
return rows[0]
|
||||
}
|
||||
|
||||
pub fn (db DB) exec_one(query string) ?Row {
|
||||
pub fn (db DB) exec_one(query string) !Row {
|
||||
res := C.PQexec(db.conn, query.str)
|
||||
e := unsafe { C.PQerrorMessage(db.conn).vstring() }
|
||||
if e != '' {
|
||||
return error('pg exec error: "$e"')
|
||||
}
|
||||
row := rows_first_or_empty(res_to_rows(res))?
|
||||
row := rows_first_or_empty(res_to_rows(res))!
|
||||
return row
|
||||
}
|
||||
|
||||
// exec_param_many executes a query with the provided parameters
|
||||
pub fn (db DB) exec_param_many(query string, params []string) ?[]Row {
|
||||
pub fn (db DB) exec_param_many(query string, params []string) ![]Row {
|
||||
unsafe {
|
||||
mut param_vals := []&char{len: params.len}
|
||||
for i in 0 .. params.len {
|
||||
@ -200,15 +200,15 @@ pub fn (db DB) exec_param_many(query string, params []string) ?[]Row {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (db DB) exec_param2(query string, param string, param2 string) ?[]Row {
|
||||
pub fn (db DB) exec_param2(query string, param string, param2 string) ![]Row {
|
||||
return db.exec_param_many(query, [param, param2])
|
||||
}
|
||||
|
||||
pub fn (db DB) exec_param(query string, param string) ?[]Row {
|
||||
pub fn (db DB) exec_param(query string, param string) ![]Row {
|
||||
return db.exec_param_many(query, [param])
|
||||
}
|
||||
|
||||
fn (db DB) handle_error_or_result(res voidptr, elabel string) ?[]Row {
|
||||
fn (db DB) handle_error_or_result(res voidptr, elabel string) ![]Row {
|
||||
e := unsafe { C.PQerrorMessage(db.conn).vstring() }
|
||||
if e != '' {
|
||||
C.PQclear(res)
|
||||
@ -219,7 +219,7 @@ fn (db DB) handle_error_or_result(res voidptr, elabel string) ?[]Row {
|
||||
|
||||
// copy_expert execute COPY commands
|
||||
// https://www.postgresql.org/docs/9.5/libpq-copy.html
|
||||
pub fn (db DB) copy_expert(query string, mut file io.ReaderWriter) ?int {
|
||||
pub fn (db DB) copy_expert(query string, mut file io.ReaderWriter) !int {
|
||||
res := C.PQexec(db.conn, query.str)
|
||||
status := C.PQresultStatus(res)
|
||||
|
||||
|
@ -5,19 +5,19 @@ import time
|
||||
|
||||
// sql expr
|
||||
|
||||
pub fn (db DB) @select(config orm.SelectConfig, data orm.QueryData, where orm.QueryData) ?[][]orm.Primitive {
|
||||
pub fn (db DB) @select(config orm.SelectConfig, data orm.QueryData, where orm.QueryData) ![][]orm.Primitive {
|
||||
// 1. Create query and bind necessary data
|
||||
query := orm.orm_select_gen(config, '`', true, '?', 1, where)
|
||||
$if trace_sqlite ? {
|
||||
eprintln('> @select query: "$query"')
|
||||
}
|
||||
stmt := db.new_init_stmt(query)?
|
||||
stmt := db.new_init_stmt(query)!
|
||||
defer {
|
||||
stmt.finalize()
|
||||
}
|
||||
mut c := 1
|
||||
sqlite_stmt_binder(stmt, where, query, mut c)?
|
||||
sqlite_stmt_binder(stmt, data, query, mut c)?
|
||||
sqlite_stmt_binder(stmt, where, query, mut c)!
|
||||
sqlite_stmt_binder(stmt, data, query, mut c)!
|
||||
|
||||
mut ret := [][]orm.Primitive{}
|
||||
|
||||
@ -27,7 +27,7 @@ pub fn (db DB) @select(config orm.SelectConfig, data orm.QueryData, where orm.Qu
|
||||
if step !in [sqlite_row, sqlite_ok, sqlite_done] {
|
||||
return db.error_message(step, query)
|
||||
}
|
||||
count := stmt.sqlite_select_column(0, 8)?
|
||||
count := stmt.sqlite_select_column(0, 8)!
|
||||
ret << [count]
|
||||
return ret
|
||||
}
|
||||
@ -42,7 +42,7 @@ pub fn (db DB) @select(config orm.SelectConfig, data orm.QueryData, where orm.Qu
|
||||
}
|
||||
mut row := []orm.Primitive{}
|
||||
for i, typ in config.types {
|
||||
primitive := stmt.sqlite_select_column(i, typ)?
|
||||
primitive := stmt.sqlite_select_column(i, typ)!
|
||||
row << primitive
|
||||
}
|
||||
ret << row
|
||||
@ -52,20 +52,20 @@ pub fn (db DB) @select(config orm.SelectConfig, data orm.QueryData, where orm.Qu
|
||||
|
||||
// sql stmt
|
||||
|
||||
pub fn (db DB) insert(table string, data orm.QueryData) ? {
|
||||
pub fn (db DB) insert(table string, data orm.QueryData) ! {
|
||||
query, converted_data := orm.orm_stmt_gen(table, '`', .insert, true, '?', 1, data,
|
||||
orm.QueryData{})
|
||||
sqlite_stmt_worker(db, query, converted_data, orm.QueryData{})?
|
||||
sqlite_stmt_worker(db, query, converted_data, orm.QueryData{})!
|
||||
}
|
||||
|
||||
pub fn (db DB) update(table string, data orm.QueryData, where orm.QueryData) ? {
|
||||
pub fn (db DB) update(table string, data orm.QueryData, where orm.QueryData) ! {
|
||||
query, _ := orm.orm_stmt_gen(table, '`', .update, true, '?', 1, data, where)
|
||||
sqlite_stmt_worker(db, query, data, where)?
|
||||
sqlite_stmt_worker(db, query, data, where)!
|
||||
}
|
||||
|
||||
pub fn (db DB) delete(table string, where orm.QueryData) ? {
|
||||
pub fn (db DB) delete(table string, where orm.QueryData) ! {
|
||||
query, _ := orm.orm_stmt_gen(table, '`', .delete, true, '?', 1, orm.QueryData{}, where)
|
||||
sqlite_stmt_worker(db, query, orm.QueryData{}, where)?
|
||||
sqlite_stmt_worker(db, query, orm.QueryData{}, where)!
|
||||
}
|
||||
|
||||
pub fn (db DB) last_id() orm.Primitive {
|
||||
@ -75,37 +75,37 @@ pub fn (db DB) last_id() orm.Primitive {
|
||||
}
|
||||
|
||||
// table
|
||||
pub fn (db DB) create(table string, fields []orm.TableField) ? {
|
||||
pub fn (db DB) create(table string, fields []orm.TableField) ! {
|
||||
query := orm.orm_table_gen(table, '`', true, 0, fields, sqlite_type_from_v, false) or {
|
||||
return err
|
||||
}
|
||||
sqlite_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})?
|
||||
sqlite_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})!
|
||||
}
|
||||
|
||||
pub fn (db DB) drop(table string) ? {
|
||||
pub fn (db DB) drop(table string) ! {
|
||||
query := 'DROP TABLE `$table`;'
|
||||
sqlite_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})?
|
||||
sqlite_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})!
|
||||
}
|
||||
|
||||
// helper
|
||||
|
||||
// Executes query and bind prepared statement data directly
|
||||
fn sqlite_stmt_worker(db DB, query string, data orm.QueryData, where orm.QueryData) ? {
|
||||
fn sqlite_stmt_worker(db DB, query string, data orm.QueryData, where orm.QueryData) ! {
|
||||
$if trace_sqlite ? {
|
||||
eprintln('> sqlite_stmt_worker query: "$query"')
|
||||
}
|
||||
stmt := db.new_init_stmt(query)?
|
||||
stmt := db.new_init_stmt(query)!
|
||||
defer {
|
||||
stmt.finalize()
|
||||
}
|
||||
mut c := 1
|
||||
sqlite_stmt_binder(stmt, data, query, mut c)?
|
||||
sqlite_stmt_binder(stmt, where, query, mut c)?
|
||||
stmt.orm_step(query)?
|
||||
sqlite_stmt_binder(stmt, data, query, mut c)!
|
||||
sqlite_stmt_binder(stmt, where, query, mut c)!
|
||||
stmt.orm_step(query)!
|
||||
}
|
||||
|
||||
// Binds all values of d in the prepared statement
|
||||
fn sqlite_stmt_binder(stmt Stmt, d orm.QueryData, query string, mut c &int) ? {
|
||||
fn sqlite_stmt_binder(stmt Stmt, d orm.QueryData, query string, mut c &int) ! {
|
||||
for data in d.data {
|
||||
err := bind(stmt, c, data)
|
||||
|
||||
@ -143,7 +143,7 @@ fn bind(stmt Stmt, c &int, data orm.Primitive) int {
|
||||
}
|
||||
|
||||
// Selects column in result and converts it to an orm.Primitive
|
||||
fn (stmt Stmt) sqlite_select_column(idx int, typ int) ?orm.Primitive {
|
||||
fn (stmt Stmt) sqlite_select_column(idx int, typ int) !orm.Primitive {
|
||||
mut primitive := orm.Primitive(0)
|
||||
|
||||
if typ in orm.nums || typ == -1 {
|
||||
@ -165,7 +165,7 @@ fn (stmt Stmt) sqlite_select_column(idx int, typ int) ?orm.Primitive {
|
||||
}
|
||||
|
||||
// Convert type int to sql type string
|
||||
fn sqlite_type_from_v(typ int) ?string {
|
||||
fn sqlite_type_from_v(typ int) !string {
|
||||
return if typ in orm.nums || typ < 0 || typ in orm.num64 || typ == orm.time {
|
||||
'INTEGER'
|
||||
} else if typ in orm.float {
|
||||
|
@ -106,7 +106,7 @@ fn C.sqlite3_errmsg(&C.sqlite3) &char
|
||||
fn C.sqlite3_free(voidptr)
|
||||
|
||||
// connect Opens the connection with a database.
|
||||
pub fn connect(path string) ?DB {
|
||||
pub fn connect(path string) !DB {
|
||||
db := &C.sqlite3(0)
|
||||
code := C.sqlite3_open(&char(path.str), &db)
|
||||
if code != 0 {
|
||||
@ -124,7 +124,7 @@ pub fn connect(path string) ?DB {
|
||||
// close Closes the DB.
|
||||
// TODO: For all functions, determine whether the connection is
|
||||
// closed first, and determine what to do if it is
|
||||
pub fn (mut db DB) close() ?bool {
|
||||
pub fn (mut db DB) close() !bool {
|
||||
code := C.sqlite3_close(db.conn)
|
||||
if code == 0 {
|
||||
db.is_open = false
|
||||
@ -217,7 +217,7 @@ pub fn (db &DB) exec(query string) ([]Row, int) {
|
||||
// Execute a query, handle error code
|
||||
// Return the first row from the resulting table
|
||||
[manualfree]
|
||||
pub fn (db &DB) exec_one(query string) ?Row {
|
||||
pub fn (db &DB) exec_one(query string) !Row {
|
||||
rows, code := db.exec(query)
|
||||
defer {
|
||||
unsafe { rows.free() }
|
||||
|
@ -13,7 +13,7 @@ fn (db &DB) init_stmt(query string) (&C.sqlite3_stmt, int) {
|
||||
return stmt, err
|
||||
}
|
||||
|
||||
fn (db &DB) new_init_stmt(query string) ?Stmt {
|
||||
fn (db &DB) new_init_stmt(query string) !Stmt {
|
||||
stmt, err := db.init_stmt(query)
|
||||
if err != sqlite_ok {
|
||||
return db.error_message(err, query)
|
||||
@ -66,7 +66,7 @@ fn (stmt &Stmt) step() int {
|
||||
return C.sqlite3_step(stmt.stmt)
|
||||
}
|
||||
|
||||
fn (stmt &Stmt) orm_step(query string) ? {
|
||||
fn (stmt &Stmt) orm_step(query string) ! {
|
||||
res := stmt.step()
|
||||
if res != sqlite_ok && res != sqlite_done && res != sqlite_row {
|
||||
return stmt.db.error_message(res, query)
|
||||
|
@ -30,7 +30,7 @@ pub fn get_terminal_size() (int, int) {
|
||||
}
|
||||
|
||||
// get_cursor_position returns a Coord containing the current cursor position
|
||||
pub fn get_cursor_position() ?Coord {
|
||||
pub fn get_cursor_position() !Coord {
|
||||
if os.is_atty(1) <= 0 || os.getenv('TERM') == 'dumb' {
|
||||
return Coord{0, 0}
|
||||
}
|
||||
|
@ -58,8 +58,8 @@ fn test_header() {
|
||||
}
|
||||
|
||||
fn test_get_cursor_position() {
|
||||
original_position := term.get_cursor_position()?
|
||||
cursor_position_1 := term.get_cursor_position()?
|
||||
original_position := term.get_cursor_position()!
|
||||
cursor_position_1 := term.get_cursor_position()!
|
||||
assert original_position.x == cursor_position_1.x
|
||||
assert original_position.y == cursor_position_1.y
|
||||
//
|
||||
@ -67,13 +67,13 @@ fn test_get_cursor_position() {
|
||||
x: 10
|
||||
y: 11
|
||||
)
|
||||
cursor_position_2 := term.get_cursor_position()?
|
||||
cursor_position_2 := term.get_cursor_position()!
|
||||
//
|
||||
term.set_cursor_position(
|
||||
x: 5
|
||||
y: 6
|
||||
)
|
||||
cursor_position_3 := term.get_cursor_position()?
|
||||
cursor_position_3 := term.get_cursor_position()!
|
||||
//
|
||||
term.set_cursor_position(original_position)
|
||||
eprintln('original_position: $original_position')
|
||||
|
@ -69,7 +69,7 @@ pub fn get_terminal_size() (int, int) {
|
||||
}
|
||||
|
||||
// get_cursor_position returns a Coord containing the current cursor position
|
||||
pub fn get_cursor_position() ?Coord {
|
||||
pub fn get_cursor_position() !Coord {
|
||||
mut res := Coord{}
|
||||
if os.is_atty(1) > 0 && os.getenv('TERM') != 'dumb' {
|
||||
info := C.CONSOLE_SCREEN_BUFFER_INFO{}
|
||||
|
@ -47,7 +47,7 @@ pub fn (mut ctx Context) run() ? {
|
||||
ctx.fail('error: x11 backend not implemented yet')
|
||||
exit(1)
|
||||
} else {
|
||||
ctx.termios_setup()?
|
||||
ctx.termios_setup() or { panic(err) }
|
||||
ctx.termios_loop()
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ fn restore_terminal_state() {
|
||||
os.flush()
|
||||
}
|
||||
|
||||
fn (mut ctx Context) termios_setup() ? {
|
||||
fn (mut ctx Context) termios_setup() ! {
|
||||
// store the current title, so restore_terminal_state can get it back
|
||||
save_title()
|
||||
|
||||
|
@ -6,7 +6,7 @@ module time
|
||||
// parse_rfc3339 returns time from a date string in RFC 3339 datetime format.
|
||||
// See also https://ijmacd.github.io/rfc3339-iso8601/ for a visual reference of
|
||||
// the differences between ISO-8601 and RFC 3339.
|
||||
pub fn parse_rfc3339(s string) ?Time {
|
||||
pub fn parse_rfc3339(s string) !Time {
|
||||
if s == '' {
|
||||
return error_invalid_time(0)
|
||||
}
|
||||
@ -23,7 +23,7 @@ pub fn parse_rfc3339(s string) ?Time {
|
||||
|
||||
// Check if sn is date only
|
||||
if !parts[0].contains_any(' Z') && parts[0].contains('-') {
|
||||
year, month, day := parse_iso8601_date(sn)?
|
||||
year, month, day := parse_iso8601_date(sn)!
|
||||
t = new_time(Time{
|
||||
year: year
|
||||
month: month
|
||||
@ -34,7 +34,7 @@ pub fn parse_rfc3339(s string) ?Time {
|
||||
// Check if sn is time only
|
||||
if !parts[0].contains('-') && parts[0].contains(':') {
|
||||
mut hour_, mut minute_, mut second_, mut microsecond_, mut unix_offset, mut is_local_time := 0, 0, 0, 0, i64(0), true
|
||||
hour_, minute_, second_, microsecond_, unix_offset, is_local_time = parse_iso8601_time(parts[0])?
|
||||
hour_, minute_, second_, microsecond_, unix_offset, is_local_time = parse_iso8601_time(parts[0])!
|
||||
t = new_time(Time{
|
||||
hour: hour_
|
||||
minute: minute_
|
||||
@ -58,7 +58,7 @@ pub fn parse_rfc3339(s string) ?Time {
|
||||
}
|
||||
|
||||
// parse returns time from a date string in "YYYY-MM-DD HH:mm:ss" format.
|
||||
pub fn parse(s string) ?Time {
|
||||
pub fn parse(s string) !Time {
|
||||
if s == '' {
|
||||
return error_invalid_time(0)
|
||||
}
|
||||
@ -115,7 +115,7 @@ pub fn parse(s string) ?Time {
|
||||
// from UTC time and can be both +/- HH:mm
|
||||
// remarks: not all iso8601 is supported
|
||||
// also checks and support for leapseconds should be added in future PR
|
||||
pub fn parse_iso8601(s string) ?Time {
|
||||
pub fn parse_iso8601(s string) !Time {
|
||||
if s == '' {
|
||||
return error_invalid_time(0)
|
||||
}
|
||||
@ -124,10 +124,10 @@ pub fn parse_iso8601(s string) ?Time {
|
||||
if !(parts.len == 1 || parts.len == 2) {
|
||||
return error_invalid_time(12)
|
||||
}
|
||||
year, month, day := parse_iso8601_date(parts[0])?
|
||||
year, month, day := parse_iso8601_date(parts[0])!
|
||||
mut hour_, mut minute_, mut second_, mut microsecond_, mut unix_offset, mut is_local_time := 0, 0, 0, 0, i64(0), true
|
||||
if parts.len == 2 {
|
||||
hour_, minute_, second_, microsecond_, unix_offset, is_local_time = parse_iso8601_time(parts[1])?
|
||||
hour_, minute_, second_, microsecond_, unix_offset, is_local_time = parse_iso8601_time(parts[1])!
|
||||
}
|
||||
mut t := new_time(
|
||||
year: year
|
||||
@ -152,7 +152,7 @@ pub fn parse_iso8601(s string) ?Time {
|
||||
}
|
||||
|
||||
// parse_rfc2822 returns time from a date string in RFC 2822 datetime format.
|
||||
pub fn parse_rfc2822(s string) ?Time {
|
||||
pub fn parse_rfc2822(s string) !Time {
|
||||
if s == '' {
|
||||
return error_invalid_time(0)
|
||||
}
|
||||
@ -171,7 +171,7 @@ pub fn parse_rfc2822(s string) ?Time {
|
||||
}
|
||||
|
||||
// ----- iso8601 -----
|
||||
fn parse_iso8601_date(s string) ?(int, int, int) {
|
||||
fn parse_iso8601_date(s string) !(int, int, int) {
|
||||
year, month, day, dummy := 0, 0, 0, u8(0)
|
||||
count := unsafe { C.sscanf(&char(s.str), c'%4d-%2d-%2d%c', &year, &month, &day, &dummy) }
|
||||
if count != 3 {
|
||||
@ -189,7 +189,7 @@ fn parse_iso8601_date(s string) ?(int, int, int) {
|
||||
return year, month, day
|
||||
}
|
||||
|
||||
fn parse_iso8601_time(s string) ?(int, int, int, int, i64, bool) {
|
||||
fn parse_iso8601_time(s string) !(int, int, int, int, i64, bool) {
|
||||
hour_ := 0
|
||||
minute_ := 0
|
||||
second_ := 0
|
||||
|
@ -19,6 +19,6 @@ pub fn parse(s string) Time {
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn parse_iso8601(s string) ?Time {
|
||||
pub fn parse_iso8601(s string) !Time {
|
||||
return parse(s)
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import time
|
||||
|
||||
fn test_add_to_day_in_the_previous_century() {
|
||||
a := time.parse_iso8601('1900-01-01')?
|
||||
a := time.parse_iso8601('1900-01-01')!
|
||||
aa := a.add_days(180)
|
||||
dump(a.debug())
|
||||
dump(aa.debug())
|
||||
@ -9,25 +9,25 @@ fn test_add_to_day_in_the_previous_century() {
|
||||
}
|
||||
|
||||
fn test_add_to_day_in_the_past() {
|
||||
a := time.parse_iso8601('1990-03-01')?
|
||||
a := time.parse_iso8601('1990-03-01')!
|
||||
aa := a.add_days(180)
|
||||
assert aa.ymmdd() == '1990-08-28'
|
||||
}
|
||||
|
||||
fn test_add_to_day_in_the_recent_past() {
|
||||
a := time.parse_iso8601('2021-03-01')?
|
||||
a := time.parse_iso8601('2021-03-01')!
|
||||
aa := a.add_days(180)
|
||||
assert aa.ymmdd() == '2021-08-28'
|
||||
}
|
||||
|
||||
fn test_add_to_day_in_the_future_1() {
|
||||
a := time.parse_iso8601('3000-11-01')?
|
||||
a := time.parse_iso8601('3000-11-01')!
|
||||
aa := a.add_days(180)
|
||||
assert aa.ymmdd() == '3001-04-30'
|
||||
}
|
||||
|
||||
fn test_add_to_day_in_the_future_2() {
|
||||
a := time.parse_iso8601('3000-12-30')?
|
||||
a := time.parse_iso8601('3000-12-30')!
|
||||
aa := a.add_days(180)
|
||||
assert aa.ymmdd() == '3001-06-28'
|
||||
}
|
||||
|
@ -644,7 +644,7 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
|
||||
c.error('json.decode: second argument needs to be a string', node.pos)
|
||||
}
|
||||
typ := expr as ast.TypeNode
|
||||
ret_type := typ.typ.set_flag(.optional)
|
||||
ret_type := typ.typ.set_flag(.result)
|
||||
node.return_type = ret_type
|
||||
return ret_type
|
||||
} else if fn_name == '__addr' {
|
||||
|
@ -1,34 +1,34 @@
|
||||
vlib/v/checker/tests/json_decode.vv:11:7: error: json.decode: unknown type `St2`
|
||||
9 | fn main() {
|
||||
10 | json.decode(St, '{a: ""}')? // OK
|
||||
11 | json.decode(St2, '{a: ""}')? // BAD
|
||||
10 | json.decode(St, '{a: ""}')! // OK
|
||||
11 | json.decode(St2, '{a: ""}')! // BAD
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~
|
||||
12 | json.decode(St)? // BAD
|
||||
13 | json.decode(string, '""')? // BAD
|
||||
12 | json.decode(St)! // BAD
|
||||
13 | json.decode(string, '""')! // BAD
|
||||
vlib/v/checker/tests/json_decode.vv:12:7: error: json.decode expects 2 arguments, a type and a string (e.g `json.decode(T, '')`)
|
||||
10 | json.decode(St, '{a: ""}')? // OK
|
||||
11 | json.decode(St2, '{a: ""}')? // BAD
|
||||
12 | json.decode(St)? // BAD
|
||||
10 | json.decode(St, '{a: ""}')! // OK
|
||||
11 | json.decode(St2, '{a: ""}')! // BAD
|
||||
12 | json.decode(St)! // BAD
|
||||
| ~~~~~~~~~~
|
||||
13 | json.decode(string, '""')? // BAD
|
||||
14 | json.decode(Num, '5')? // BAD
|
||||
13 | json.decode(string, '""')! // BAD
|
||||
14 | json.decode(Num, '5')! // BAD
|
||||
vlib/v/checker/tests/json_decode.vv:13:14: error: json.decode: expected sum type, struct, map or array, found string
|
||||
11 | json.decode(St2, '{a: ""}')? // BAD
|
||||
12 | json.decode(St)? // BAD
|
||||
13 | json.decode(string, '""')? // BAD
|
||||
11 | json.decode(St2, '{a: ""}')! // BAD
|
||||
12 | json.decode(St)! // BAD
|
||||
13 | json.decode(string, '""')! // BAD
|
||||
| ~~~~~~
|
||||
14 | json.decode(Num, '5')? // BAD
|
||||
15 | json.decode(St, 6)? // BAD
|
||||
14 | json.decode(Num, '5')! // BAD
|
||||
15 | json.decode(St, 6)! // BAD
|
||||
vlib/v/checker/tests/json_decode.vv:14:14: error: json.decode: expected sum type, struct, map or array, found u8
|
||||
12 | json.decode(St)? // BAD
|
||||
13 | json.decode(string, '""')? // BAD
|
||||
14 | json.decode(Num, '5')? // BAD
|
||||
12 | json.decode(St)! // BAD
|
||||
13 | json.decode(string, '""')! // BAD
|
||||
14 | json.decode(Num, '5')! // BAD
|
||||
| ~~~
|
||||
15 | json.decode(St, 6)? // BAD
|
||||
15 | json.decode(St, 6)! // BAD
|
||||
16 | }
|
||||
vlib/v/checker/tests/json_decode.vv:15:7: error: json.decode: second argument needs to be a string
|
||||
13 | json.decode(string, '""')? // BAD
|
||||
14 | json.decode(Num, '5')? // BAD
|
||||
15 | json.decode(St, 6)? // BAD
|
||||
13 | json.decode(string, '""')! // BAD
|
||||
14 | json.decode(Num, '5')! // BAD
|
||||
15 | json.decode(St, 6)! // BAD
|
||||
| ~~~~~~~~~~~~~
|
||||
16 | }
|
||||
|
@ -7,10 +7,10 @@ struct St {
|
||||
type Num = u8
|
||||
|
||||
fn main() {
|
||||
json.decode(St, '{a: ""}')? // OK
|
||||
json.decode(St2, '{a: ""}')? // BAD
|
||||
json.decode(St)? // BAD
|
||||
json.decode(string, '""')? // BAD
|
||||
json.decode(Num, '5')? // BAD
|
||||
json.decode(St, 6)? // BAD
|
||||
json.decode(St, '{a: ""}')! // OK
|
||||
json.decode(St2, '{a: ""}')! // BAD
|
||||
json.decode(St)! // BAD
|
||||
json.decode(string, '""')! // BAD
|
||||
json.decode(Num, '5')! // BAD
|
||||
json.decode(St, 6)! // BAD
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
vlib/v/checker/tests/orm_empty_struct.vv:9:15: error: V orm: select: empty fields in `Person`
|
||||
7 | db := sqlite.connect(':memory:')?
|
||||
7 | db := sqlite.connect(':memory:')!
|
||||
8 | _ := sql db {
|
||||
9 | select from Person
|
||||
| ~~~~~~
|
||||
|
@ -4,7 +4,7 @@ struct Person {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
db := sqlite.connect(':memory:')?
|
||||
db := sqlite.connect(':memory:')!
|
||||
_ := sql db {
|
||||
select from Person
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ struct Person {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
db := sqlite.connect(':memory:')?
|
||||
db := sqlite.connect(':memory:')!
|
||||
_ := sql db {
|
||||
select from Person
|
||||
} or {
|
||||
|
@ -1,5 +1,5 @@
|
||||
vlib/v/checker/tests/orm_not_a_struct.vv:10:15: error: The table symbol `Person` has to be a struct
|
||||
8 | db := sqlite.connect(':memory:')?
|
||||
8 | db := sqlite.connect(':memory:')!
|
||||
9 | _ := sql db {
|
||||
10 | select from Person
|
||||
| ~~~~~~
|
||||
|
@ -5,7 +5,7 @@ enum Person {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
db := sqlite.connect(':memory:')?
|
||||
db := sqlite.connect(':memory:')!
|
||||
_ := sql db {
|
||||
select from Person
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ struct User {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
db := sqlite.connect(':memory:')?
|
||||
db := sqlite.connect(':memory:')!
|
||||
sql db {
|
||||
create table User
|
||||
}
|
||||
|
@ -4,16 +4,16 @@ struct Request {
|
||||
a int
|
||||
}
|
||||
|
||||
fn parse(s string) ?Request {
|
||||
fn parse(s string) !Request {
|
||||
return json.decode(Request, s)
|
||||
}
|
||||
|
||||
fn parse2(s string) ?Request {
|
||||
req := json.decode(Request, s)?
|
||||
fn parse2(s string) !Request {
|
||||
req := json.decode(Request, s)!
|
||||
return req
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println(parse('{"a": 22} ')?)
|
||||
println(parse2('{"a": 22} ')?)
|
||||
println(parse('{"a": 22} ')!)
|
||||
println(parse2('{"a": 22} ')!)
|
||||
}
|
||||
|
@ -1301,7 +1301,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
|
||||
g.call_args(node)
|
||||
g.writeln(');')
|
||||
tmp2 = g.new_tmp_var()
|
||||
g.writeln('${option_name}_$typ $tmp2 = ${fn_name}($json_obj);')
|
||||
g.writeln('${result_name}_$typ $tmp2 = ${fn_name}($json_obj);')
|
||||
}
|
||||
if !g.is_autofree {
|
||||
g.write('cJSON_Delete($json_obj); // del')
|
||||
|
@ -44,12 +44,12 @@ fn (mut g Gen) gen_jsons() {
|
||||
mut enc := strings.new_builder(100)
|
||||
sym := g.table.sym(utyp)
|
||||
styp := g.typ(utyp)
|
||||
g.register_optional(utyp)
|
||||
g.register_result(utyp)
|
||||
// decode_TYPE funcs receive an actual cJSON* object to decode
|
||||
// cJSON_Parse(str) call is added by the compiler
|
||||
// Codegen decoder
|
||||
dec_fn_name := js_dec_name(styp)
|
||||
dec_fn_dec := '${option_name}_$styp ${dec_fn_name}(cJSON* root)'
|
||||
dec_fn_dec := '${result_name}_$styp ${dec_fn_name}(cJSON* root)'
|
||||
|
||||
mut init_styp := '$styp res'
|
||||
if sym.kind == .struct_ {
|
||||
@ -89,7 +89,7 @@ $dec_fn_dec {
|
||||
int maxchars = vstrlen_char(prevline_ptr);
|
||||
vmemcpy(buf, prevline_ptr, (maxchars < maxcontext_chars ? maxchars : maxcontext_chars));
|
||||
}
|
||||
return (${option_name}_$styp){.state = 2,.err = _v_error(tos2(buf)),.data = {0}};
|
||||
return (${result_name}_$styp){.is_error = true,.err = _v_error(tos2(buf)),.data = {0}};
|
||||
}
|
||||
}
|
||||
')
|
||||
@ -153,8 +153,8 @@ $enc_fn_dec {
|
||||
g.gen_struct_enc_dec(sym.info, styp, mut enc, mut dec)
|
||||
}
|
||||
// cJSON_delete
|
||||
dec.writeln('\t${option_name}_$styp ret;')
|
||||
dec.writeln('\t_option_ok(&res, ($option_name*)&ret, sizeof(res));')
|
||||
dec.writeln('\t${result_name}_$styp ret;')
|
||||
dec.writeln('\t_result_ok(&res, ($result_name*)&ret, sizeof(res));')
|
||||
dec.writeln('\treturn ret;\n}')
|
||||
enc.writeln('\treturn o;\n}')
|
||||
g.gowrappers.writeln(dec.str())
|
||||
@ -251,9 +251,9 @@ fn (mut g Gen) gen_sumtype_enc_dec(sym ast.TypeSymbol, mut enc strings.Builder,
|
||||
dec.writeln('\t\t\t}')
|
||||
} else if !is_js_prim(variant_typ) && variant_sym.kind != .enum_ {
|
||||
dec.writeln('\t\t\tif (strcmp("$unmangled_variant_name", $type_var) == 0) {')
|
||||
dec.writeln('\t\t\t\t${option_name}_$variant_typ $tmp = ${js_dec_name(variant_typ)}(root);')
|
||||
dec.writeln('\t\t\t\tif (${tmp}.state != 0) {')
|
||||
dec.writeln('\t\t\t\t\treturn (${option_name}_$sym.cname){ .state = ${tmp}.state, .err = ${tmp}.err, .data = {0} };')
|
||||
dec.writeln('\t\t\t\t${result_name}_$variant_typ $tmp = ${js_dec_name(variant_typ)}(root);')
|
||||
dec.writeln('\t\t\t\tif (${tmp}.is_error) {')
|
||||
dec.writeln('\t\t\t\t\treturn (${result_name}_$sym.cname){ .is_error = true, .err = ${tmp}.err, .data = {0} };')
|
||||
dec.writeln('\t\t\t\t}')
|
||||
dec.writeln('\t\t\t\tres = ${variant_typ}_to_sumtype_${sym.cname}(($variant_typ*)${tmp}.data);')
|
||||
dec.writeln('\t\t\t}')
|
||||
@ -317,9 +317,9 @@ fn (mut g Gen) gen_sumtype_enc_dec(sym ast.TypeSymbol, mut enc strings.Builder,
|
||||
'cJSON_IsNumber(root->child)'
|
||||
}
|
||||
dec.writeln('\t\tif (cJSON_IsArray(root) && $judge_elem_typ) {')
|
||||
dec.writeln('\t\t\t${option_name}_$var_t $tmp = ${js_dec_name(var_t)}(root);')
|
||||
dec.writeln('\t\t\tif (${tmp}.state != 0) {')
|
||||
dec.writeln('\t\t\t\treturn (${option_name}_$sym.cname){ .state = ${tmp}.state, .err = ${tmp}.err, .data = {0} };')
|
||||
dec.writeln('\t\t\t${result_name}_$var_t $tmp = ${js_dec_name(var_t)}(root);')
|
||||
dec.writeln('\t\t\tif (${tmp}.is_error) {')
|
||||
dec.writeln('\t\t\t\treturn (${result_name}_$sym.cname){ .is_error = true, .err = ${tmp}.err, .data = {0} };')
|
||||
dec.writeln('\t\t\t}')
|
||||
dec.writeln('\t\t\tres = ${var_t}_to_sumtype_${sym.cname}(($var_t*)${tmp}.data);')
|
||||
dec.writeln('\t\t}')
|
||||
@ -499,7 +499,7 @@ fn gen_js_get(styp string, tmp string, name string, mut dec strings.Builder, is_
|
||||
dec.writeln('\tcJSON *jsonroot_$tmp = js_get(root, "$name");')
|
||||
if is_required {
|
||||
dec.writeln('\tif (jsonroot_$tmp == 0) {')
|
||||
dec.writeln('\t\treturn (${option_name}_$styp){ .state = 2, .err = _v_error(_SLIT("expected field \'$name\' is missing")), .data = {0} };')
|
||||
dec.writeln('\t\treturn (${result_name}_$styp){ .is_error = true, .err = _v_error(_SLIT("expected field \'$name\' is missing")), .data = {0} };')
|
||||
dec.writeln('\t}')
|
||||
}
|
||||
}
|
||||
@ -507,11 +507,11 @@ fn gen_js_get(styp string, tmp string, name string, mut dec strings.Builder, is_
|
||||
fn gen_js_get_opt(dec_name string, field_type string, styp string, tmp string, name string, mut dec strings.Builder, is_required bool) {
|
||||
gen_js_get(styp, tmp, name, mut dec, is_required)
|
||||
value_field_type := field_type.trim_right('*')
|
||||
dec.writeln('\t${option_name}_$value_field_type $tmp;')
|
||||
dec.writeln('\t${result_name}_$value_field_type $tmp;')
|
||||
dec.writeln('\tif (jsonroot_$tmp) {')
|
||||
dec.writeln('\t\t$tmp = ${dec_name}(jsonroot_$tmp);')
|
||||
dec.writeln('\t\tif (${tmp}.state != 0) {')
|
||||
dec.writeln('\t\t\treturn (${option_name}_$styp){ .state = ${tmp}.state, .err = ${tmp}.err, .data = {0} };')
|
||||
dec.writeln('\t\tif (${tmp}.is_error) {')
|
||||
dec.writeln('\t\t\treturn (${result_name}_$styp){ .is_error = true, .err = ${tmp}.err, .data = {0} };')
|
||||
dec.writeln('\t\t}')
|
||||
dec.writeln('\t}')
|
||||
}
|
||||
@ -557,10 +557,10 @@ fn (mut g Gen) decode_array(value_type ast.Type, fixed_array_size int) string {
|
||||
s = '$styp val = ${fn_name}((cJSON *)jsval); '
|
||||
} else {
|
||||
s = '
|
||||
${option_name}_$styp val2 = $fn_name ((cJSON *)jsval);
|
||||
if(val2.state != 0) {
|
||||
${result_name}_$styp val2 = $fn_name ((cJSON *)jsval);
|
||||
if(val2.is_error) {
|
||||
$array_free_str
|
||||
return *(${option_name}_Array_$fixed_array_str$styp$fixed_array_size_str*)&val2;
|
||||
return *(${result_name}_Array_$fixed_array_str$styp$fixed_array_size_str*)&val2;
|
||||
}
|
||||
$styp val = *($styp*)val2.data;
|
||||
'
|
||||
@ -568,7 +568,7 @@ fn (mut g Gen) decode_array(value_type ast.Type, fixed_array_size int) string {
|
||||
|
||||
return '
|
||||
if(root && !cJSON_IsArray(root) && !cJSON_IsNull(root)) {
|
||||
return (${option_name}_Array_$fixed_array_str$styp$fixed_array_size_str){.state = 2, .err = _v_error(string__plus(_SLIT("Json element is not an array: "), tos2((byteptr)cJSON_PrintUnformatted(root)))), .data = {0}};
|
||||
return (${result_name}_Array_$fixed_array_str$styp$fixed_array_size_str){.is_error = true, .err = _v_error(string__plus(_SLIT("Json element is not an array: "), tos2((byteptr)cJSON_PrintUnformatted(root)))), .data = {0}};
|
||||
}
|
||||
$res_str
|
||||
const cJSON *jsval = NULL;
|
||||
@ -612,17 +612,17 @@ fn (mut g Gen) decode_map(key_type ast.Type, value_type ast.Type) string {
|
||||
s = '$styp_v val = $fn_name_v (js_get(root, jsval->string));'
|
||||
} else {
|
||||
s = '
|
||||
${option_name}_$styp_v val2 = $fn_name_v (js_get(root, jsval->string));
|
||||
if(val2.state != 0) {
|
||||
${result_name}_$styp_v val2 = $fn_name_v (js_get(root, jsval->string));
|
||||
if(val2.is_error) {
|
||||
map_free(&res);
|
||||
return *(${option_name}_Map_${styp}_$styp_v*)&val2;
|
||||
return *(${result_name}_Map_${styp}_$styp_v*)&val2;
|
||||
}
|
||||
$styp_v val = *($styp_v*)val2.data;
|
||||
'
|
||||
}
|
||||
return '
|
||||
if(!cJSON_IsObject(root) && !cJSON_IsNull(root)) {
|
||||
return (${option_name}_Map_${styp}_$styp_v){ .state = 2, .err = _v_error(string__plus(_SLIT("Json element is not an object: "), tos2((byteptr)cJSON_PrintUnformatted(root)))), .data = {0}};
|
||||
return (${result_name}_Map_${styp}_$styp_v){ .is_error = true, .err = _v_error(string__plus(_SLIT("Json element is not an object: "), tos2((byteptr)cJSON_PrintUnformatted(root)))), .data = {0}};
|
||||
}
|
||||
res = new_map(sizeof($styp), sizeof($styp_v), $hash_fn, $key_eq_fn, $clone_fn, $free_fn);
|
||||
cJSON *jsval = NULL;
|
||||
|
@ -75,11 +75,11 @@ fn (mut g Gen) sql_stmt_line(nd ast.SqlStmtLine, expr string, or_expr ast.OrExpr
|
||||
unsafe { fields.free() }
|
||||
}
|
||||
if node.kind == .create {
|
||||
g.write('${option_name}_void $res = orm__Connection_name_table[${expr}._typ]._method_')
|
||||
g.write('${result_name}_void $res = orm__Connection_name_table[${expr}._typ]._method_')
|
||||
g.sql_create_table(node, expr, table_name)
|
||||
subs = true
|
||||
} else if node.kind == .drop {
|
||||
g.write('${option_name}_void $res = orm__Connection_name_table[${expr}._typ]._method_')
|
||||
g.write('${result_name}_void $res = orm__Connection_name_table[${expr}._typ]._method_')
|
||||
g.writeln('drop(${expr}._object, _SLIT("$table_name"));')
|
||||
subs = true
|
||||
} else if node.kind == .insert {
|
||||
@ -87,14 +87,14 @@ fn (mut g Gen) sql_stmt_line(nd ast.SqlStmtLine, expr string, or_expr ast.OrExpr
|
||||
g.writeln('Array_orm__Primitive $arr = __new_array_with_default_noscan(0, 0, sizeof(orm__Primitive), 0);')
|
||||
g.sql_insert(node, expr, table_name, arr, res, '', false, '', or_expr)
|
||||
} else if node.kind == .update {
|
||||
g.write('${option_name}_void $res = orm__Connection_name_table[${expr}._typ]._method_')
|
||||
g.write('${result_name}_void $res = orm__Connection_name_table[${expr}._typ]._method_')
|
||||
g.sql_update(node, expr, table_name)
|
||||
} else if node.kind == .delete {
|
||||
g.write('${option_name}_void $res = orm__Connection_name_table[${expr}._typ]._method_')
|
||||
g.write('${result_name}_void $res = orm__Connection_name_table[${expr}._typ]._method_')
|
||||
g.sql_delete(node, expr, table_name)
|
||||
}
|
||||
if or_expr.kind == .block {
|
||||
g.or_block(res, or_expr, ast.int_type)
|
||||
g.or_block(res, or_expr, ast.int_type.set_flag(.result))
|
||||
}
|
||||
if subs {
|
||||
for _, sub in node.sub_structs {
|
||||
@ -186,7 +186,7 @@ fn (mut g Gen) sql_insert(node ast.SqlStmtLine, expr string, table_name string,
|
||||
g.writeln('array_push(&$last_ids_arr, _MOV((orm__Primitive[]){orm__Connection_name_table[${expr}._typ]._method_last_id(${expr}._object)}));')
|
||||
}
|
||||
|
||||
g.write('${option_name}_void $res = orm__Connection_name_table[${expr}._typ]._method_')
|
||||
g.write('${result_name}_void $res = orm__Connection_name_table[${expr}._typ]._method_')
|
||||
g.write('insert(${expr}._object, _SLIT("$table_name"), (orm__QueryData){')
|
||||
|
||||
g.write('.fields = new_array_from_c_array($fields.len, $fields.len, sizeof(string),')
|
||||
@ -583,7 +583,7 @@ fn (mut g Gen) sql_select(node ast.SqlExpr, expr string, left string, or_expr as
|
||||
res := g.new_tmp_var()
|
||||
table_name := g.get_table_name(node.table_expr)
|
||||
g.sql_table_name = g.table.sym(node.table_expr.typ).name
|
||||
g.write('${option_name}_Array_Array_orm__Primitive _o$res = orm__Connection_name_table[${expr}._typ]._method_select(${expr}._object, ')
|
||||
g.write('${result_name}_Array_Array_orm__Primitive _o$res = orm__Connection_name_table[${expr}._typ]._method_select(${expr}._object, ')
|
||||
g.write('(orm__SelectConfig){')
|
||||
g.write('.table = _SLIT("$table_name"),')
|
||||
g.write('.is_count = $node.is_count,')
|
||||
@ -677,12 +677,12 @@ fn (mut g Gen) sql_select(node ast.SqlExpr, expr string, left string, or_expr as
|
||||
g.writeln(');')
|
||||
|
||||
mut tmp_left := g.new_tmp_var()
|
||||
g.writeln('${g.typ(node.typ.set_flag(.optional))} $tmp_left;')
|
||||
g.writeln('${g.typ(node.typ.set_flag(.result))} $tmp_left;')
|
||||
|
||||
if node.or_expr.kind == .block {
|
||||
g.writeln('${tmp_left}.state = _o${res}.state;')
|
||||
g.writeln('${tmp_left}.is_error = _o${res}.is_error;')
|
||||
g.writeln('${tmp_left}.err = _o${res}.err;')
|
||||
g.or_block(tmp_left, node.or_expr, node.typ)
|
||||
g.or_block(tmp_left, node.or_expr, node.typ.set_flag(.result))
|
||||
g.writeln('else {')
|
||||
g.indent++
|
||||
}
|
||||
|
@ -8,23 +8,23 @@ pub:
|
||||
|
||||
struct Abc {}
|
||||
|
||||
pub fn (x &Abc) notification_at<T>() ?NotificationMessage<T> {
|
||||
pub fn (x &Abc) notification_at<T>() !NotificationMessage<T> {
|
||||
return json.decode(NotificationMessage<T>, '{}')
|
||||
}
|
||||
|
||||
pub fn (x &Abc) generic_method<T>(method_name string) ?NotificationMessage<T> {
|
||||
pub fn (x &Abc) generic_method<T>(method_name string) !NotificationMessage<T> {
|
||||
return x.notification_at<T>()
|
||||
}
|
||||
|
||||
struct Res {}
|
||||
|
||||
pub fn (mut x Abc) diagnostics() ?Res {
|
||||
got := x.generic_method<Res>('xyz')?
|
||||
pub fn (mut x Abc) diagnostics() !Res {
|
||||
got := x.generic_method<Res>('xyz')!
|
||||
return got.params
|
||||
}
|
||||
|
||||
fn test_generic_method_returning_optional() {
|
||||
mut a := Abc{}
|
||||
a.diagnostics()?
|
||||
a.diagnostics()!
|
||||
assert true
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ fn test_json_serialisation_of_fixed_arrays() {
|
||||
]!}
|
||||
s := json.encode(a)
|
||||
dump(s)
|
||||
b := json.decode(Fixed_Array, s)?
|
||||
b := json.decode(Fixed_Array, s)!
|
||||
dump(b)
|
||||
assert a == b
|
||||
}
|
||||
|
@ -12,6 +12,6 @@ struct LinksData {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
links_data := json.decode(LinksData, '{}')?
|
||||
links_data := json.decode(LinksData, '{}')!
|
||||
println(links_data.messages)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user