orm: document & fix pg (#14533)
parent
b97ef09b2d
commit
a83ac948a0
|
@ -102,6 +102,10 @@ fn (kind OrderType) to_str() string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Examples for QueryData in SQL: abc == 3 && b == 'test'
|
||||||
|
// => fields[abc, b]; data[3, 'test']; types[index of int, index of string]; kinds[.eq, .eq]; is_and[true];
|
||||||
|
// Every field, data, type & kind of operation in the expr share the same index in the arrays
|
||||||
|
// is_and defines how they're addicted to each other either and or or
|
||||||
pub struct QueryData {
|
pub struct QueryData {
|
||||||
pub:
|
pub:
|
||||||
fields []string
|
fields []string
|
||||||
|
@ -128,6 +132,17 @@ pub:
|
||||||
attrs []StructAttribute
|
attrs []StructAttribute
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// table - Table name
|
||||||
|
// is_count - Either the data will be returned or an integer with the count
|
||||||
|
// has_where - Select all or use a where expr
|
||||||
|
// has_order - Order the results
|
||||||
|
// order - Name of the column which will be ordered
|
||||||
|
// order_type - Type of order (asc, desc)
|
||||||
|
// has_limit - Limits the output data
|
||||||
|
// primary - Name of the primary field
|
||||||
|
// has_offset - Add an offset to the result
|
||||||
|
// fields - Fields to select
|
||||||
|
// types - Types to select
|
||||||
pub struct SelectConfig {
|
pub struct SelectConfig {
|
||||||
pub:
|
pub:
|
||||||
table string
|
table string
|
||||||
|
@ -143,6 +158,14 @@ pub:
|
||||||
types []int
|
types []int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Interfaces gets called from the backend and can be implemented
|
||||||
|
// Since the orm supports arrays aswell, they have to be returned too.
|
||||||
|
// A row is represented as []Primitive, where the data is connected to the fields of the struct by their
|
||||||
|
// index. The indices are mapped with the SelectConfig.field array. This is the mapping for a struct.
|
||||||
|
// To have an array, there has to be an array of structs, basically [][]Primitive
|
||||||
|
//
|
||||||
|
// 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 {
|
pub interface Connection {
|
||||||
@select(config SelectConfig, data QueryData, where QueryData) ?[][]Primitive
|
@select(config SelectConfig, data QueryData, where QueryData) ?[][]Primitive
|
||||||
insert(table string, data QueryData) ?
|
insert(table string, data QueryData) ?
|
||||||
|
@ -153,7 +176,12 @@ pub interface Connection {
|
||||||
last_id() Primitive
|
last_id() Primitive
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn orm_stmt_gen(table string, para string, kind StmtKind, num bool, qm string, start_pos int, data QueryData, where QueryData) string {
|
// Generates an sql stmt, from universal parameter
|
||||||
|
// q - The quotes character, which can be different in every type, so it's variable
|
||||||
|
// num - Stmt uses nums at prepared statements (? or ?1)
|
||||||
|
// qm - Character for prepared statment, qm because of quotation mark like in sqlite
|
||||||
|
// start_pos - When num is true, it's the start position of the counter
|
||||||
|
pub fn orm_stmt_gen(table string, q string, kind StmtKind, num bool, qm string, start_pos int, data QueryData, where QueryData) string {
|
||||||
mut str := ''
|
mut str := ''
|
||||||
|
|
||||||
mut c := start_pos
|
mut c := start_pos
|
||||||
|
@ -163,7 +191,7 @@ pub fn orm_stmt_gen(table string, para string, kind StmtKind, num bool, qm strin
|
||||||
mut values := []string{}
|
mut values := []string{}
|
||||||
|
|
||||||
for _ in 0 .. data.fields.len {
|
for _ in 0 .. data.fields.len {
|
||||||
// loop over the length of data.field and generate ?0, ?1 or just ? based on the $num parameter for value placeholders
|
// loop over the length of data.field and generate ?0, ?1 or just ? based on the $num qmeter for value placeholders
|
||||||
if num {
|
if num {
|
||||||
values << '$qm$c'
|
values << '$qm$c'
|
||||||
c++
|
c++
|
||||||
|
@ -172,16 +200,16 @@ pub fn orm_stmt_gen(table string, para string, kind StmtKind, num bool, qm strin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
str += 'INSERT INTO $para$table$para ('
|
str += 'INSERT INTO $q$table$q ('
|
||||||
str += data.fields.map('$para$it$para').join(', ')
|
str += data.fields.map('$q$it$q').join(', ')
|
||||||
str += ') VALUES ('
|
str += ') VALUES ('
|
||||||
str += values.join(', ')
|
str += values.join(', ')
|
||||||
str += ')'
|
str += ')'
|
||||||
}
|
}
|
||||||
.update {
|
.update {
|
||||||
str += 'UPDATE $para$table$para SET '
|
str += 'UPDATE $q$table$q SET '
|
||||||
for i, field in data.fields {
|
for i, field in data.fields {
|
||||||
str += '$para$field$para = '
|
str += '$q$field$q = '
|
||||||
if data.data.len > i {
|
if data.data.len > i {
|
||||||
d := data.data[i]
|
d := data.data[i]
|
||||||
if d is InfixType {
|
if d is InfixType {
|
||||||
|
@ -217,12 +245,12 @@ pub fn orm_stmt_gen(table string, para string, kind StmtKind, num bool, qm strin
|
||||||
str += ' WHERE '
|
str += ' WHERE '
|
||||||
}
|
}
|
||||||
.delete {
|
.delete {
|
||||||
str += 'DELETE FROM $para$table$para WHERE '
|
str += 'DELETE FROM $q$table$q WHERE '
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if kind == .update || kind == .delete {
|
if kind == .update || kind == .delete {
|
||||||
for i, field in where.fields {
|
for i, field in where.fields {
|
||||||
str += '$para$field$para ${where.kinds[i].to_str()} $qm'
|
str += '$q$field$q ${where.kinds[i].to_str()} $qm'
|
||||||
if num {
|
if num {
|
||||||
str += '$c'
|
str += '$c'
|
||||||
c++
|
c++
|
||||||
|
@ -236,28 +264,32 @@ pub fn orm_stmt_gen(table string, para string, kind StmtKind, num bool, qm strin
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn orm_select_gen(orm SelectConfig, para string, num bool, qm string, start_pos int, where QueryData) string {
|
// Generates an sql select stmt, from universal parameter
|
||||||
|
// orm - See SelectConfig
|
||||||
|
// q, num, qm, start_pos - see orm_stmt_gen
|
||||||
|
// where - See QueryData
|
||||||
|
pub fn orm_select_gen(orm SelectConfig, q string, num bool, qm string, start_pos int, where QueryData) string {
|
||||||
mut str := 'SELECT '
|
mut str := 'SELECT '
|
||||||
|
|
||||||
if orm.is_count {
|
if orm.is_count {
|
||||||
str += 'COUNT(*)'
|
str += 'COUNT(*)'
|
||||||
} else {
|
} else {
|
||||||
for i, field in orm.fields {
|
for i, field in orm.fields {
|
||||||
str += '$para$field$para'
|
str += '$q$field$q'
|
||||||
if i < orm.fields.len - 1 {
|
if i < orm.fields.len - 1 {
|
||||||
str += ', '
|
str += ', '
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
str += ' FROM $para$orm.table$para'
|
str += ' FROM $q$orm.table$q'
|
||||||
|
|
||||||
mut c := start_pos
|
mut c := start_pos
|
||||||
|
|
||||||
if orm.has_where {
|
if orm.has_where {
|
||||||
str += ' WHERE '
|
str += ' WHERE '
|
||||||
for i, field in where.fields {
|
for i, field in where.fields {
|
||||||
str += '$para$field$para ${where.kinds[i].to_str()} $qm'
|
str += '$q$field$q ${where.kinds[i].to_str()} $qm'
|
||||||
if num {
|
if num {
|
||||||
str += '$c'
|
str += '$c'
|
||||||
c++
|
c++
|
||||||
|
@ -276,7 +308,7 @@ pub fn orm_select_gen(orm SelectConfig, para string, num bool, qm string, start_
|
||||||
// ordering is *slow*, especially if there are no indexes!
|
// ordering is *slow*, especially if there are no indexes!
|
||||||
if orm.has_order {
|
if orm.has_order {
|
||||||
str += ' ORDER BY '
|
str += ' ORDER BY '
|
||||||
str += '$para$orm.order$para '
|
str += '$q$orm.order$q '
|
||||||
str += orm.order_type.to_str()
|
str += orm.order_type.to_str()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,11 +332,19 @@ pub fn orm_select_gen(orm SelectConfig, para string, num bool, qm string, start_
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn orm_table_gen(table string, para string, defaults bool, def_unique_len int, fields []TableField, sql_from_v fn (int) ?string, alternative bool) ?string {
|
// Generates an sql table stmt, from universal parameter
|
||||||
mut str := 'CREATE TABLE IF NOT EXISTS $para$table$para ('
|
// table - Table name
|
||||||
|
// q - see orm_stmt_gen
|
||||||
|
// defaults - enables default values in stmt
|
||||||
|
// def_unique_len - sets default unique length for texts
|
||||||
|
// 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 {
|
||||||
|
mut str := 'CREATE TABLE IF NOT EXISTS $q$table$q ('
|
||||||
|
|
||||||
if alternative {
|
if alternative {
|
||||||
str = 'IF NOT EXISTS (SELECT * FROM sysobjects WHERE name=$para$table$para and xtype=${para}U$para) CREATE TABLE $para$table$para ('
|
str = 'IF NOT EXISTS (SELECT * FROM sysobjects WHERE name=$q$table$q and xtype=${q}U$q) CREATE TABLE $q$table$q ('
|
||||||
}
|
}
|
||||||
|
|
||||||
mut fs := []string{}
|
mut fs := []string{}
|
||||||
|
@ -368,7 +408,7 @@ pub fn orm_table_gen(table string, para string, defaults bool, def_unique_len in
|
||||||
if ctyp == '' {
|
if ctyp == '' {
|
||||||
return error('Unknown type ($field.typ) for field $field.name in struct $table')
|
return error('Unknown type ($field.typ) for field $field.name in struct $table')
|
||||||
}
|
}
|
||||||
stmt = '$para$field_name$para $ctyp'
|
stmt = '$q$field_name$q $ctyp'
|
||||||
if defaults && field.default_val != '' {
|
if defaults && field.default_val != '' {
|
||||||
stmt += ' DEFAULT $field.default_val'
|
stmt += ' DEFAULT $field.default_val'
|
||||||
}
|
}
|
||||||
|
@ -376,7 +416,7 @@ pub fn orm_table_gen(table string, para string, defaults bool, def_unique_len in
|
||||||
stmt += ' NOT NULL'
|
stmt += ' NOT NULL'
|
||||||
}
|
}
|
||||||
if is_unique {
|
if is_unique {
|
||||||
mut f := 'UNIQUE($para$field_name$para'
|
mut f := 'UNIQUE($q$field_name$q'
|
||||||
if ctyp == 'TEXT' && def_unique_len > 0 {
|
if ctyp == 'TEXT' && def_unique_len > 0 {
|
||||||
if unique_len > 0 {
|
if unique_len > 0 {
|
||||||
f += '($unique_len)'
|
f += '($unique_len)'
|
||||||
|
@ -396,18 +436,19 @@ pub fn orm_table_gen(table string, para string, defaults bool, def_unique_len in
|
||||||
for k, v in unique {
|
for k, v in unique {
|
||||||
mut tmp := []string{}
|
mut tmp := []string{}
|
||||||
for f in v {
|
for f in v {
|
||||||
tmp << '$para$f$para'
|
tmp << '$q$f$q'
|
||||||
}
|
}
|
||||||
fs << '/* $k */UNIQUE(${tmp.join(', ')})'
|
fs << '/* $k */UNIQUE(${tmp.join(', ')})'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fs << 'PRIMARY KEY($para$primary$para)'
|
fs << 'PRIMARY KEY($q$primary$q)'
|
||||||
fs << unique_fields
|
fs << unique_fields
|
||||||
str += fs.join(', ')
|
str += fs.join(', ')
|
||||||
str += ');'
|
str += ');'
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get's the sql field type
|
||||||
fn sql_field_type(field TableField) int {
|
fn sql_field_type(field TableField) int {
|
||||||
mut typ := field.typ
|
mut typ := field.typ
|
||||||
if field.is_time {
|
if field.is_time {
|
||||||
|
@ -426,6 +467,7 @@ fn sql_field_type(field TableField) int {
|
||||||
return typ
|
return typ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get's the sql field name
|
||||||
fn sql_field_name(field TableField) string {
|
fn sql_field_name(field TableField) string {
|
||||||
mut name := field.name
|
mut name := field.name
|
||||||
for attr in field.attrs {
|
for attr in field.attrs {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// import os
|
// import os
|
||||||
// import pg
|
|
||||||
// import term
|
// import term
|
||||||
import time
|
import time
|
||||||
|
// import pg
|
||||||
import sqlite
|
import sqlite
|
||||||
|
|
||||||
struct Module {
|
struct Module {
|
||||||
|
@ -31,9 +31,12 @@ struct TestTime {
|
||||||
create time.Time
|
create time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_orm_sqlite() {
|
fn test_orm() {
|
||||||
db := sqlite.connect(':memory:') or { panic(err) }
|
db := sqlite.connect(':memory:') or { panic(err) }
|
||||||
db.exec('drop table if exists User')
|
// db.exec('drop table if exists User')
|
||||||
|
|
||||||
|
// db := pg.connect(host: 'localhost', port: 5432, user: 'louis', password: 'abc', dbname: 'orm') or { panic(err) }
|
||||||
|
|
||||||
sql db {
|
sql db {
|
||||||
create table Module
|
create table Module
|
||||||
}
|
}
|
||||||
|
@ -242,7 +245,7 @@ fn test_orm_sqlite() {
|
||||||
//
|
//
|
||||||
offset_const := 2
|
offset_const := 2
|
||||||
z := sql db {
|
z := sql db {
|
||||||
select from User limit 2 offset offset_const
|
select from User order by id limit 2 offset offset_const
|
||||||
}
|
}
|
||||||
assert z.len == 2
|
assert z.len == 2
|
||||||
assert z[0].id == 3
|
assert z[0].id == 3
|
||||||
|
@ -264,6 +267,7 @@ fn test_orm_sqlite() {
|
||||||
}
|
}
|
||||||
assert updated_oldest.age == 31
|
assert updated_oldest.age == 31
|
||||||
|
|
||||||
|
// Remove this when pg is used
|
||||||
db.exec('insert into User (name, age) values (NULL, 31)')
|
db.exec('insert into User (name, age) values (NULL, 31)')
|
||||||
null_user := sql db {
|
null_user := sql db {
|
||||||
select from User where id == 5
|
select from User where id == 5
|
||||||
|
@ -336,11 +340,18 @@ fn test_orm_sqlite() {
|
||||||
sql db {
|
sql db {
|
||||||
update Module set created = t where id == 1
|
update Module set created = t where id == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
updated_time_mod := sql db {
|
updated_time_mod := sql db {
|
||||||
select from Module where id == 1
|
select from Module where id == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: usually updated_time_mod.created != t, because t has
|
// Note: usually updated_time_mod.created != t, because t has
|
||||||
// its microseconds set, while the value retrieved from the DB
|
// its microseconds set, while the value retrieved from the DB
|
||||||
// has them zeroed, because the db field resolution is seconds.
|
// has them zeroed, because the db field resolution is seconds.
|
||||||
assert updated_time_mod.created.format_ss() == t.format_ss()
|
assert updated_time_mod.created.format_ss() == t.format_ss()
|
||||||
|
|
||||||
|
sql db {
|
||||||
|
drop table Module
|
||||||
|
drop table TestTime
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,13 @@ import net.conv
|
||||||
|
|
||||||
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)
|
query := orm.orm_select_gen(config, '"', true, '$', 1, where)
|
||||||
|
|
||||||
|
res := pg_stmt_worker(db, query, where, data)?
|
||||||
|
|
||||||
mut ret := [][]orm.Primitive{}
|
mut ret := [][]orm.Primitive{}
|
||||||
|
|
||||||
res := pg_stmt_worker(db, query, orm.QueryData{}, where)?
|
if config.is_count {
|
||||||
|
}
|
||||||
|
|
||||||
for row in res {
|
for row in res {
|
||||||
mut row_data := []orm.Primitive{}
|
mut row_data := []orm.Primitive{}
|
||||||
|
@ -166,7 +170,9 @@ fn pg_stmt_match(mut types []u32, mut vals []&char, mut lens []int, mut formats
|
||||||
}
|
}
|
||||||
time.Time {
|
time.Time {
|
||||||
types << u32(Oid.t_int4)
|
types << u32(Oid.t_int4)
|
||||||
vals << &char(&int(data.unix))
|
unix := int(data.unix)
|
||||||
|
num := conv.htn32(unsafe { &u32(&unix) })
|
||||||
|
vals << &char(&num)
|
||||||
lens << int(sizeof(u32))
|
lens << int(sizeof(u32))
|
||||||
formats << 1
|
formats << 1
|
||||||
}
|
}
|
||||||
|
@ -178,19 +184,22 @@ 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 {
|
str := match typ {
|
||||||
6, 10 {
|
orm.type_idx['i8'], orm.type_idx['i16'], orm.type_idx['byte'], orm.type_idx['u16'] {
|
||||||
'SMALLINT'
|
'SMALLINT'
|
||||||
}
|
}
|
||||||
7, 11, orm.time {
|
orm.type_idx['bool'] {
|
||||||
|
'BOOLEAN'
|
||||||
|
}
|
||||||
|
orm.type_idx['int'], orm.type_idx['u32'], orm.time {
|
||||||
'INT'
|
'INT'
|
||||||
}
|
}
|
||||||
8, 12 {
|
orm.type_idx['i64'], orm.type_idx['u64'] {
|
||||||
'BIGINT'
|
'BIGINT'
|
||||||
}
|
}
|
||||||
13 {
|
orm.float[0] {
|
||||||
'REAL'
|
'REAL'
|
||||||
}
|
}
|
||||||
14 {
|
orm.float[1] {
|
||||||
'DOUBLE PRECISION'
|
'DOUBLE PRECISION'
|
||||||
}
|
}
|
||||||
orm.string {
|
orm.string {
|
||||||
|
@ -212,54 +221,51 @@ fn pg_type_from_v(typ int) ?string {
|
||||||
fn str_to_primitive(str string, typ int) ?orm.Primitive {
|
fn str_to_primitive(str string, typ int) ?orm.Primitive {
|
||||||
match typ {
|
match typ {
|
||||||
// bool
|
// bool
|
||||||
16 {
|
orm.type_idx['bool'] {
|
||||||
return orm.Primitive(str.i8() == 1)
|
|
||||||
}
|
|
||||||
18 {
|
|
||||||
return orm.Primitive(str == 't')
|
return orm.Primitive(str == 't')
|
||||||
}
|
}
|
||||||
// i8
|
// i8
|
||||||
5 {
|
orm.type_idx['i8'] {
|
||||||
return orm.Primitive(str.i8())
|
return orm.Primitive(str.i8())
|
||||||
}
|
}
|
||||||
// i16
|
// i16
|
||||||
6 {
|
orm.type_idx['i16'] {
|
||||||
return orm.Primitive(str.i16())
|
return orm.Primitive(str.i16())
|
||||||
}
|
}
|
||||||
// int
|
// int
|
||||||
7 {
|
orm.type_idx['int'] {
|
||||||
return orm.Primitive(str.int())
|
return orm.Primitive(str.int())
|
||||||
}
|
}
|
||||||
// i64
|
// i64
|
||||||
8 {
|
orm.type_idx['i64'] {
|
||||||
return orm.Primitive(str.i64())
|
return orm.Primitive(str.i64())
|
||||||
}
|
}
|
||||||
// byte
|
// byte
|
||||||
9 {
|
orm.type_idx['byte'] {
|
||||||
data := str.i8()
|
data := str.i8()
|
||||||
return orm.Primitive(*unsafe { &u8(&data) })
|
return orm.Primitive(*unsafe { &u8(&data) })
|
||||||
}
|
}
|
||||||
// u16
|
// u16
|
||||||
10 {
|
orm.type_idx['u16'] {
|
||||||
data := str.i16()
|
data := str.i16()
|
||||||
return orm.Primitive(*unsafe { &u16(&data) })
|
return orm.Primitive(*unsafe { &u16(&data) })
|
||||||
}
|
}
|
||||||
// u32
|
// u32
|
||||||
11 {
|
orm.type_idx['u32'] {
|
||||||
data := str.int()
|
data := str.int()
|
||||||
return orm.Primitive(*unsafe { &u32(&data) })
|
return orm.Primitive(*unsafe { &u32(&data) })
|
||||||
}
|
}
|
||||||
// u64
|
// u64
|
||||||
12 {
|
orm.type_idx['u64'] {
|
||||||
data := str.i64()
|
data := str.i64()
|
||||||
return orm.Primitive(*unsafe { &u64(&data) })
|
return orm.Primitive(*unsafe { &u64(&data) })
|
||||||
}
|
}
|
||||||
// f32
|
// f32
|
||||||
13 {
|
orm.type_idx['f32'] {
|
||||||
return orm.Primitive(str.f32())
|
return orm.Primitive(str.f32())
|
||||||
}
|
}
|
||||||
// f64
|
// f64
|
||||||
14 {
|
orm.type_idx['f64'] {
|
||||||
return orm.Primitive(str.f64())
|
return orm.Primitive(str.f64())
|
||||||
}
|
}
|
||||||
orm.string {
|
orm.string {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import time
|
||||||
// sql expr
|
// 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)
|
query := orm.orm_select_gen(config, '`', true, '?', 1, where)
|
||||||
stmt := db.new_init_stmt(query)?
|
stmt := db.new_init_stmt(query)?
|
||||||
mut c := 1
|
mut c := 1
|
||||||
|
@ -19,6 +20,7 @@ pub fn (db DB) @select(config orm.SelectConfig, data orm.QueryData, where orm.Qu
|
||||||
mut ret := [][]orm.Primitive{}
|
mut ret := [][]orm.Primitive{}
|
||||||
|
|
||||||
if config.is_count {
|
if config.is_count {
|
||||||
|
// 2. Get count of returned values & add it to ret array
|
||||||
step := stmt.step()
|
step := stmt.step()
|
||||||
if step !in [sqlite_row, sqlite_ok, sqlite_done] {
|
if step !in [sqlite_row, sqlite_ok, sqlite_done] {
|
||||||
return db.error_message(step, query)
|
return db.error_message(step, query)
|
||||||
|
@ -28,6 +30,7 @@ pub fn (db DB) @select(config orm.SelectConfig, data orm.QueryData, where orm.Qu
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
|
// 2. Parse returned values
|
||||||
step := stmt.step()
|
step := stmt.step()
|
||||||
if step == sqlite_done {
|
if step == sqlite_done {
|
||||||
break
|
break
|
||||||
|
@ -83,6 +86,7 @@ pub fn (db DB) drop(table string) ? {
|
||||||
|
|
||||||
// helper
|
// 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) ? {
|
||||||
stmt := db.new_init_stmt(query)?
|
stmt := db.new_init_stmt(query)?
|
||||||
mut c := 1
|
mut c := 1
|
||||||
|
@ -92,6 +96,7 @@ fn sqlite_stmt_worker(db DB, query string, data orm.QueryData, where orm.QueryDa
|
||||||
stmt.finalize()
|
stmt.finalize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 {
|
for data in d.data {
|
||||||
err := bind(stmt, c, data)
|
err := bind(stmt, c, data)
|
||||||
|
@ -103,6 +108,7 @@ fn sqlite_stmt_binder(stmt Stmt, d orm.QueryData, query string, mut c &int) ? {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Universal bind function
|
||||||
fn bind(stmt Stmt, c &int, data orm.Primitive) int {
|
fn bind(stmt Stmt, c &int, data orm.Primitive) int {
|
||||||
mut err := 0
|
mut err := 0
|
||||||
match data {
|
match data {
|
||||||
|
@ -128,6 +134,7 @@ fn bind(stmt Stmt, c &int, data orm.Primitive) int {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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)
|
mut primitive := orm.Primitive(0)
|
||||||
|
|
||||||
|
@ -149,6 +156,7 @@ fn (stmt Stmt) sqlite_select_column(idx int, typ int) ?orm.Primitive {
|
||||||
return primitive
|
return 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 {
|
return if typ in orm.nums || typ < 0 || typ in orm.num64 || typ == orm.time {
|
||||||
'INTEGER'
|
'INTEGER'
|
||||||
|
|
Loading…
Reference in New Issue