1 /* Copyright(C) 2006 Brazil
2 All rights reserved.
3 This is free software with ABSOLUTELY NO WARRANTY.
4
5 You can redistribute it and/or modify it under the terms of
6 the GNU General Public License version 2.
7 */
8
9 #include "myisam.h"
10 #include "sql/mysql_priv.h"
11 #include "mysql.h"
12 #include "sql/ha_myisam.h"
13 #include "myisam/myisamdef.h"
14 #include "myisenna.h"
15
16 /*
17 #include <stdio.h>
18 #include <sys/time.h>
19 #include <time.h>
20 */
21
22 struct _myis_table {
23 TABLE table;
24 MI_INFO *info;
25 myis_column *columns;
26 myis_index *indexes;
27 };
28
29 struct _myis_index {
30 int n;
31 KEY *key;
32 };
33
34 struct _myis_cursor {
35 myis_table *table;
36 int n;
37 char *record;
38 myis_id id;
39 };
40
41 struct _myis_column {
42 Field *field;
43 };
44
45 int
myis_init(void)46 myis_init(void)
47 {
48 char *server_default_groups[] = { "server", "embedded", "mysql_SERVER", 0 };
49 char *pargv[] = {"--skip-innodb", 0};
50 mysql_server_init(1, pargv, server_default_groups);
51 sen_init();
52 return 0;
53 }
54
55 myis_table *
myis_table_open(const char * path)56 myis_table_open(const char *path)
57 {
58 int i, error;
59 myis_table *table = (myis_table *)malloc(sizeof(myis_table));
60 if (!table) { return NULL; }
61 error = openfrm(path, "",
62 HA_OPEN_KEYFILE|HA_OPEN_RNDFILE|HA_GET_INDEX|HA_TRY_READ_ONLY,
63 READ_KEYINFO|COMPUTE_TYPES|EXTRA_RECORD, 0, &table->table);
64 table->columns = (myis_column *) malloc(sizeof(myis_column) * table->table.fields);
65 for (i = 0; i < table->table.fields; i++) {
66 table->columns[i].field = table->table.field[i];
67 }
68 table->indexes = (myis_index *) malloc(sizeof(myis_index) * table->table.keys);
69 for (i = 0; i < table->table.keys; i++) {
70 table->indexes[i].n = i;
71 table->indexes[i].key = &table->table.key_info[i];
72 }
73 table->info = ((ha_myisam *)table->table.file)->getfile();
74 return table;
75 }
76
77 int
myis_table_close(myis_table * table)78 myis_table_close(myis_table *table)
79 {
80 int error = closefrm(&table->table);
81 free(table);
82 return error;
83 }
84
85 int
myis_table_info(myis_table * table,int * n_columns,int * n_indexes)86 myis_table_info(myis_table *table, int *n_columns, int *n_indexes)
87 {
88 if (!table) { return 1; }
89 if (n_columns) { *n_columns = table->table.fields; }
90 if (n_indexes) { *n_indexes = table->table.keys; }
91 return 0;
92 }
93
94 myis_index *
myis_table_index(myis_table * table,int n)95 myis_table_index(myis_table *table, int n)
96 {
97 if (!table || table->table.keys <= n) { return NULL; }
98 return &table->indexes[n];
99 }
100
101 sen_index *
myis_table_fti(myis_table * table,int n)102 myis_table_fti(myis_table *table, int n)
103 {
104 if (!table || table->table.keys <= n) { return NULL; }
105 return table->info->s->keyinfo[n].senna;
106 }
107
108 static ha_rkey_function myis_key_opt2ha_rkey_function[] = {
109 HA_READ_KEY_EXACT,
110 HA_READ_KEY_OR_NEXT,
111 HA_READ_KEY_OR_PREV,
112 HA_READ_AFTER_KEY,
113 HA_READ_BEFORE_KEY,
114 HA_READ_PREFIX,
115 HA_READ_PREFIX_LAST,
116 HA_READ_MBR_CONTAIN,
117 HA_READ_MBR_INTERSECT,
118 HA_READ_MBR_WITHIN,
119 HA_READ_MBR_DISJOINT,
120 HA_READ_MBR_EQUAL
121 };
122
123 int
myis_index_rkey(myis_index * index,myis_cursor * cursor,const char * key,unsigned int key_len,myis_key_opt opt)124 myis_index_rkey(myis_index *index, myis_cursor *cursor,
125 const char *key, unsigned int key_len, myis_key_opt opt)
126 {
127 cursor->n = index->n;
128 ha_rkey_function flag = myis_key_opt2ha_rkey_function[opt];
129 // mi_extra(cursor->table->info, HA_EXTRA_NO_KEYREAD, 0);
130 // mi_extra(cursor->table->info, HA_EXTRA_NO_CACHE, 0);
131 // mi_extra(cursor->table->info, HA_EXTRA_KEYREAD, 0);
132 return mi_rkey(cursor->table->info, cursor->record, cursor->n, key, key_len, flag);
133 }
134
135 int
myis_index_rfirst(myis_index * index,myis_cursor * cursor)136 myis_index_rfirst(myis_index *index, myis_cursor *cursor)
137 {
138 cursor->n = index->n;
139 return mi_rfirst(cursor->table->info, cursor->record, cursor->n);
140 }
141
142 int
myis_index_rlast(myis_index * index,myis_cursor * cursor)143 myis_index_rlast(myis_index *index, myis_cursor *cursor)
144 {
145 cursor->n = index->n;
146 return mi_rlast(cursor->table->info, cursor->record, cursor->n);
147 }
148
149 const char *
myis_index_name(myis_index * index)150 myis_index_name(myis_index *index)
151 {
152 if (!index) { return NULL; }
153 return index->key->name;
154 }
155
156 myis_cursor *
myis_cursor_open(myis_table * table)157 myis_cursor_open(myis_table *table)
158 {
159 myis_cursor *cursor;
160 if (!table || !(cursor = (myis_cursor *)malloc(sizeof(myis_cursor)))) { return NULL; }
161 cursor->table = table;
162 cursor->record = table->table.record[0];
163 return cursor;
164 }
165
166 int
myis_cursor_close(myis_cursor * cursor)167 myis_cursor_close(myis_cursor *cursor)
168 {
169 if (!cursor) { return 1; }
170 free(cursor);
171 return 0;
172 }
173
174 int
myis_cursor_next(myis_cursor * cursor)175 myis_cursor_next(myis_cursor *cursor)
176 {
177 // mi_extra(cursor->table->info, HA_EXTRA_NO_KEYREAD, 0);
178 // mi_extra(cursor->table->info, HA_EXTRA_NO_CACHE, 0);
179 return mi_rnext(cursor->table->info, cursor->record, cursor->n);
180 }
181
182 int
myis_cursor_prev(myis_cursor * cursor)183 myis_cursor_prev(myis_cursor *cursor)
184 {
185 return mi_rprev(cursor->table->info, cursor->record, cursor->n);
186 }
187
188 int
myis_cursor_scan_init(myis_cursor * cursor)189 myis_cursor_scan_init(myis_cursor *cursor)
190 {
191 return mi_scan_init(cursor->table->info);
192 }
193
194 int
myis_cursor_scan(myis_cursor * cursor)195 myis_cursor_scan(myis_cursor *cursor)
196 {
197 return mi_scan(cursor->table->info, cursor->record);
198 }
199
200 int
myis_cursor_rrnd(myis_cursor * cursor,myis_id id)201 myis_cursor_rrnd(myis_cursor *cursor, myis_id id)
202 {
203 cursor->id = id;
204 return mi_rrnd(cursor->table->info, cursor->record, id);
205 }
206
207 myis_column *
myis_table_column(myis_table * table,int n)208 myis_table_column(myis_table *table, int n)
209 {
210 if (!table || table->table.fields <= n) { return NULL; }
211 return &table->columns[n];
212 }
213
214 const char *
myis_column_name(myis_column * column)215 myis_column_name(myis_column *column)
216 {
217 if (!column) { return NULL; }
218 return column->field->field_name;
219 }
220
221 int
myis_column_val_str(myis_column * column,myis_cursor * cursor,char * buf,size_t bufsize)222 myis_column_val_str(myis_column *column, myis_cursor *cursor,
223 char *buf, size_t bufsize)
224 {
225 int len;
226 String tmp(buf, bufsize);
227 column->field->val_str(&tmp, &tmp);
228 len = tmp.length();
229 memcpy(buf, tmp.ptr(), len);
230 buf[len] = '\0';
231 return 0;
232 }
233