| 1 | module mysql |
| 2 | |
| 3 | pub struct Result { |
| 4 | pub: |
| 5 | result &C.MYSQL_RES = unsafe { nil } |
| 6 | } |
| 7 | |
| 8 | pub struct Row { |
| 9 | pub mut: |
| 10 | vals []string |
| 11 | } |
| 12 | |
| 13 | pub struct Field { |
| 14 | name string |
| 15 | org_name string |
| 16 | table string |
| 17 | org_table string |
| 18 | db string |
| 19 | catalog string |
| 20 | def string |
| 21 | length int |
| 22 | max_length int |
| 23 | name_length u32 |
| 24 | org_name_length u32 |
| 25 | table_length u32 |
| 26 | org_table_length u32 |
| 27 | db_length u32 |
| 28 | catalog_length u32 |
| 29 | def_length u32 |
| 30 | flags u32 |
| 31 | decimals u32 |
| 32 | charsetnr u32 |
| 33 | type FieldType |
| 34 | } |
| 35 | |
| 36 | // fetch_row fetches the next row from a result. |
| 37 | pub fn (r Result) fetch_row() &charptr { |
| 38 | mut thread_guard := mysql_thread_guard() or { return unsafe { nil } } |
| 39 | defer { |
| 40 | thread_guard.release() |
| 41 | } |
| 42 | return C.mysql_fetch_row(r.result) |
| 43 | } |
| 44 | |
| 45 | // n_rows returns the number of rows from a result. |
| 46 | pub fn (r Result) n_rows() u64 { |
| 47 | mut thread_guard := mysql_thread_guard() or { return 0 } |
| 48 | defer { |
| 49 | thread_guard.release() |
| 50 | } |
| 51 | return C.mysql_num_rows(r.result) |
| 52 | } |
| 53 | |
| 54 | // n_fields returns the number of columns from a result. |
| 55 | pub fn (r Result) n_fields() int { |
| 56 | mut thread_guard := mysql_thread_guard() or { return 0 } |
| 57 | defer { |
| 58 | thread_guard.release() |
| 59 | } |
| 60 | return C.mysql_num_fields(r.result) |
| 61 | } |
| 62 | |
| 63 | // rows returns array of rows, each containing an array of values, |
| 64 | // one for each column. |
| 65 | pub fn (r Result) rows() []Row { |
| 66 | mut thread_guard := mysql_thread_guard() or { return []Row{} } |
| 67 | defer { |
| 68 | thread_guard.release() |
| 69 | } |
| 70 | mut rows := []Row{} |
| 71 | nr_cols := C.mysql_num_fields(r.result) |
| 72 | for rr := C.mysql_fetch_row(r.result); rr; rr = C.mysql_fetch_row(r.result) { |
| 73 | mut row := Row{} |
| 74 | for i in 0 .. nr_cols { |
| 75 | if unsafe { rr[i] == 0 } { |
| 76 | row.vals << '' |
| 77 | } else { |
| 78 | row.vals << mystring(unsafe { &u8(rr[i]) }) |
| 79 | } |
| 80 | } |
| 81 | rows << row |
| 82 | } |
| 83 | return rows |
| 84 | } |
| 85 | |
| 86 | // maps returns an array of maps, each containing a set of |
| 87 | // field name: field value pairs. |
| 88 | pub fn (r Result) maps() []map[string]string { |
| 89 | mut array_map := []map[string]string{} |
| 90 | rows := r.rows() |
| 91 | fields := r.fields() |
| 92 | for i in 0 .. rows.len { |
| 93 | mut map_val := map[string]string{} |
| 94 | for j in 0 .. fields.len { |
| 95 | map_val[fields[j].name] = rows[i].vals[j] |
| 96 | } |
| 97 | array_map << map_val |
| 98 | } |
| 99 | return array_map |
| 100 | } |
| 101 | |
| 102 | // fields returns an array of fields/columns. |
| 103 | // The definitions apply primarily for columns of results, |
| 104 | // such as those produced by `SELECT` statements. |
| 105 | pub fn (r Result) fields() []Field { |
| 106 | mut thread_guard := mysql_thread_guard() or { return []Field{} } |
| 107 | defer { |
| 108 | thread_guard.release() |
| 109 | } |
| 110 | mut fields := []Field{} |
| 111 | nr_cols := C.mysql_num_fields(r.result) |
| 112 | orig_fields := C.mysql_fetch_fields(r.result) |
| 113 | for i in 0 .. nr_cols { |
| 114 | unsafe { |
| 115 | fields << Field{ |
| 116 | name: mystring(orig_fields[i].name) |
| 117 | org_name: mystring(orig_fields[i].org_name) |
| 118 | table: mystring(orig_fields[i].table) |
| 119 | org_table: mystring(orig_fields[i].org_table) |
| 120 | db: mystring(orig_fields[i].db) |
| 121 | catalog: mystring(orig_fields[i].catalog) |
| 122 | def: resolve_nil_str(orig_fields[i].def) |
| 123 | length: orig_fields.length |
| 124 | max_length: orig_fields.max_length |
| 125 | name_length: orig_fields.name_length |
| 126 | org_name_length: orig_fields.org_name_length |
| 127 | table_length: orig_fields.table_length |
| 128 | org_table_length: orig_fields.org_table_length |
| 129 | db_length: orig_fields.db_length |
| 130 | catalog_length: orig_fields.catalog_length |
| 131 | def_length: orig_fields.def_length |
| 132 | flags: orig_fields.flags |
| 133 | decimals: orig_fields.decimals |
| 134 | charsetnr: orig_fields.charsetnr |
| 135 | type: FieldType(orig_fields.type) |
| 136 | } |
| 137 | } |
| 138 | } |
| 139 | return fields |
| 140 | } |
| 141 | |
| 142 | // str serializes the field. |
| 143 | pub fn (f Field) str() string { |
| 144 | return ' |
| 145 | { |
| 146 | name: "${f.name}" |
| 147 | org_name: "${f.org_name}" |
| 148 | table: "${f.table}" |
| 149 | org_table: "${f.org_table}" |
| 150 | db: "${f.db}" |
| 151 | catalog: "${f.catalog}" |
| 152 | def: "${f.def}" |
| 153 | length: ${f.length} |
| 154 | max_length: ${f.max_length} |
| 155 | name_length: ${f.name_length} |
| 156 | org_name_length: ${f.org_name_length} |
| 157 | table_length: ${f.table_length} |
| 158 | org_table_length: ${f.org_table_length} |
| 159 | db_length: ${f.db_length} |
| 160 | catalog_length: ${f.catalog_length} |
| 161 | def_length: ${f.def_length} |
| 162 | flags: ${f.flags} |
| 163 | decimals: ${f.decimals} |
| 164 | charsetnr: ${f.charsetnr} |
| 165 | type: ${f.type.str()} |
| 166 | } |
| 167 | ' |
| 168 | } |
| 169 | |
| 170 | // free frees the memory used by a result. |
| 171 | @[unsafe] |
| 172 | pub fn (r &Result) free() { |
| 173 | mut thread_guard := mysql_thread_guard() or { return } |
| 174 | defer { |
| 175 | thread_guard.release() |
| 176 | } |
| 177 | C.mysql_free_result(r.result) |
| 178 | } |
| 179 | |