| 1 | // vtest build: present_sqlite3? |
| 2 | import db.sqlite |
| 3 | import orm |
| 4 | import os |
| 5 | |
| 6 | type Connection = sqlite.DB |
| 7 | |
| 8 | struct User { |
| 9 | pub: |
| 10 | id int @[primary; sql: serial] |
| 11 | name string |
| 12 | last_name ?string |
| 13 | } |
| 14 | |
| 15 | type Content = []u8 | string |
| 16 | |
| 17 | struct Host { |
| 18 | pub mut: |
| 19 | db Connection |
| 20 | } |
| 21 | |
| 22 | fn (back Host) get_users() []User { |
| 23 | return [] |
| 24 | } |
| 25 | |
| 26 | fn create_host(db Connection) !Host { |
| 27 | sql db { |
| 28 | create table User |
| 29 | }! |
| 30 | |
| 31 | return Host{ |
| 32 | db: db |
| 33 | } |
| 34 | } |
| 35 | |
| 36 | fn test_sqlite() { |
| 37 | mut db := sqlite.connect(':memory:') or { panic(err) } |
| 38 | assert db.is_open |
| 39 | assert db.validate()! |
| 40 | db.exec('drop table if exists users')! |
| 41 | db.exec("create table users (id integer primary key, name text default '', last_name text null default null);")! |
| 42 | db.exec("insert into users (name) values ('Sam')")! |
| 43 | assert db.last_insert_rowid() == 1 |
| 44 | assert db.get_affected_rows_count() == 1 |
| 45 | db.exec("insert into users (name) values ('Peter')")! |
| 46 | assert db.last_insert_rowid() == 2 |
| 47 | db.exec("insert into users (name) values ('Kate')")! |
| 48 | assert db.last_insert_rowid() == 3 |
| 49 | db.exec_param('insert into users (name) values (?)', 'Tom')! |
| 50 | assert db.last_insert_rowid() == 4 |
| 51 | nr_users := db.q_int('select count(*) from users')! |
| 52 | assert nr_users == 4 |
| 53 | name := db.q_string('select name from users where id = 1')! |
| 54 | assert name == 'Sam' |
| 55 | username := db.exec_param('select name from users where id = ?', '1')! |
| 56 | assert username[0].vals[0] == 'Sam' |
| 57 | |
| 58 | // this insert will be rejected due to duplicated id |
| 59 | db.exec("insert into users (id,name) values (1,'Silly')")! |
| 60 | assert db.get_affected_rows_count() == 0 |
| 61 | |
| 62 | mut users := db.exec('select * from users')! |
| 63 | // dump(users) |
| 64 | assert users.len == 4 |
| 65 | code := db.exec_none('vacuum') |
| 66 | assert code == 101 |
| 67 | user := db.exec_one('select * from users where id = 3') or { panic(err) } |
| 68 | // dump(user) |
| 69 | assert user.vals.len == 3 |
| 70 | |
| 71 | db.exec("update users set name='zzzz' where name='qqqq'")! |
| 72 | assert db.get_affected_rows_count() == 0 |
| 73 | |
| 74 | db.exec("update users set name='Peter1' where name='Peter'")! |
| 75 | assert db.get_affected_rows_count() == 1 |
| 76 | db.exec_param_many('update users set name=? where name=?', ['Peter', 'Peter1'])! |
| 77 | assert db.get_affected_rows_count() == 1 |
| 78 | |
| 79 | db.exec("delete from users where name='qqqq'")! |
| 80 | assert db.get_affected_rows_count() == 0 |
| 81 | |
| 82 | db.exec("delete from users where name='Sam'")! |
| 83 | assert db.get_affected_rows_count() == 1 |
| 84 | |
| 85 | // transaction test |
| 86 | db.begin()! |
| 87 | db.exec("insert into users (name) values ('John')")! |
| 88 | assert db.last_insert_rowid() == 5 |
| 89 | db.savepoint('new_savepoint')! |
| 90 | db.exec("insert into users (name) values ('Kitty')")! |
| 91 | assert db.last_insert_rowid() == 6 |
| 92 | db.rollback_to('new_savepoint')! |
| 93 | db.exec("insert into users (name) values ('Mars')")! |
| 94 | assert db.last_insert_rowid() == 6 |
| 95 | db.commit()! |
| 96 | users = db.exec('select * from users')! |
| 97 | // dump(users) |
| 98 | assert users.len == 5 |
| 99 | |
| 100 | db.close() or { panic(err) } |
| 101 | assert !db.is_open |
| 102 | } |
| 103 | |
| 104 | fn test_can_access_sqlite_result_consts() { |
| 105 | assert sqlite.sqlite_ok == 0 |
| 106 | assert sqlite.sqlite_error == 1 |
| 107 | // assert sqlite.misuse == 21 |
| 108 | assert sqlite.sqlite_row == 100 |
| 109 | assert sqlite.sqlite_done == 101 |
| 110 | } |
| 111 | |
| 112 | fn test_alias_db() { |
| 113 | mut host := create_host(sqlite.connect(':memory:')!)! |
| 114 | host.db.close()! |
| 115 | assert true |
| 116 | } |
| 117 | |
| 118 | fn test_exec_param_many() { |
| 119 | mut db := sqlite.connect(':memory:') or { panic(err) } |
| 120 | assert db.is_open |
| 121 | db.exec('drop table if exists users')! |
| 122 | db.exec("create table users (id integer primary key, name text default '' unique);")! |
| 123 | db.exec("insert into users (name) values ('Sam')")! |
| 124 | db.exec_param_many('insert into users (id, name) values (?, ?)', [ |
| 125 | '60', |
| 126 | 'Sam', |
| 127 | ]) or { |
| 128 | assert err.code() == 19 // constraint failure |
| 129 | db.close()! |
| 130 | return |
| 131 | } |
| 132 | db.close()! |
| 133 | assert false |
| 134 | } |
| 135 | |
| 136 | fn test_exec_param_many2() { |
| 137 | mut db := sqlite.connect(':memory:') or { panic(err) } |
| 138 | assert db.is_open |
| 139 | db.exec('drop table if exists users')! |
| 140 | db.exec("create table users (id integer primary key, name text default '' unique);")! |
| 141 | db.exec_param_many('insert into users (id, name) values (?, ?)', [ |
| 142 | ['60', 'Sam'], |
| 143 | ['61', 'Foo'], |
| 144 | ['62', 'Bar'], |
| 145 | ])! |
| 146 | count := db.q_int('select count(*) from users')! |
| 147 | assert count == 3 |
| 148 | |
| 149 | db.close()! |
| 150 | } |
| 151 | |
| 152 | fn test_tables() { |
| 153 | mut db := sqlite.connect(':memory:') or { panic(err) } |
| 154 | db.exec('create table alpha (id integer)')! |
| 155 | db.exec('create table beta (id integer)')! |
| 156 | tbl := db.tables()! |
| 157 | assert tbl == ['alpha', 'beta'] |
| 158 | db.close()! |
| 159 | } |
| 160 | |
| 161 | fn test_columns() { |
| 162 | mut db := sqlite.connect(':memory:') or { panic(err) } |
| 163 | db.exec('create table items (id integer primary key, name text, price real)')! |
| 164 | cols := db.columns('items')! |
| 165 | assert cols == ['id', 'name', 'price'] |
| 166 | db.close()! |
| 167 | } |
| 168 | |
| 169 | fn test_schema() { |
| 170 | mut db := sqlite.connect(':memory:') or { panic(err) } |
| 171 | db.exec('create table things (id integer primary key, label text)')! |
| 172 | s := db.schema('things')! |
| 173 | assert s.contains('CREATE TABLE things') |
| 174 | // empty table name returns all objects |
| 175 | all := db.schema('')! |
| 176 | assert all.contains('CREATE TABLE things') |
| 177 | db.close()! |
| 178 | } |
| 179 | |
| 180 | fn test_db_size() { |
| 181 | tmp := os.join_path(os.temp_dir(), 'test_db_size.db') |
| 182 | defer { |
| 183 | os.rm(tmp) or {} |
| 184 | } |
| 185 | mut db := sqlite.connect(tmp) or { panic(err) } |
| 186 | db.exec('create table t (id integer)')! |
| 187 | sz := db.db_size()! |
| 188 | assert sz > 0 |
| 189 | db.close()! |
| 190 | } |
| 191 | |
| 192 | fn test_orm_transaction_interface() { |
| 193 | mut db := sqlite.connect(':memory:') or { panic(err) } |
| 194 | defer { |
| 195 | db.close() or {} |
| 196 | } |
| 197 | |
| 198 | mut conn := orm.TransactionalConnection(db) |
| 199 | mut tx := orm.begin(mut conn)! |
| 200 | tx.transaction[int](fn (mut tx orm.Tx) !int { |
| 201 | return 1 |
| 202 | })! |
| 203 | tx.commit()! |
| 204 | } |
| 205 | |