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