Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/src/ha_tritonn.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 163 - (show annotations) (download) (as text)
Tue Jul 1 01:26:15 2008 UTC (15 years, 8 months ago) by mir
File MIME type: text/x-c++src
File size: 20050 byte(s)
cutting off some debug print
1 #ifdef USE_PRAGMA_IMPLEMENTATION
2 #pragma implementation // gcc: Class implementation
3 #endif
4
5 #include "mysql_priv.h"
6 #undef PACKAGE
7 #undef VERSION
8 #undef HAVE_DTRACE
9 #undef _DTRACE_VERSION
10
11 #include "tritonn_config.h"
12
13 /* We define DTRACE after mysql_priv.h in case it disabled dtrace in the main server */
14 #ifdef HAVE_DTRACE
15 #define _DTRACE_VERSION 1
16 #else
17 #endif
18
19 #include "ha_tritonn.h"
20 #include <mysql/plugin.h>
21
22 /* create ha_tritonn instance */
23 static handler *tritonn_create_handler(handlerton *hton,
24 TABLE_SHARE *table,
25 MEM_ROOT *mem_root);
26
27 static TRITONN_DB *tdb;
28 static sen_db *get_sen_db(const char *db_name);
29
30 /* delete database files */
31 static void tritonn_drop_database(handlerton *hton, char* path);
32
33 /* flush logfile */
34 static bool tritonn_flush_logs(handlerton *hton);
35
36 /* show engine status */
37 static bool tritonn_show_status(handlerton *hton, THD *thd, stat_print_fn *print,
38 enum ha_stat_type stat);
39
40 static void dump_create(const char *name, TABLE *table_arg,
41 HA_CREATE_INFO *create_info);
42
43 static void call_senna_ql(sen_ctx *ctx, const char *str, bool disp=true);
44
45 static char *mysqltype2sennatype_string(enum_field_types types);
46
47 /* handlerton capability flags. see handler.h for more information */
48 static int tritonn_hton_flags = HTON_ALTER_NOT_SUPPORTED | HTON_CAN_RECREATE |
49 HTON_TEMPORARY_NOT_SUPPORTED | HTON_NO_PARTITION;
50
51 /* Variables for tritonn share methods */
52 static HASH tritonn_open_tables; ///< Hash used to track the number of open tables; variable for tritonn share methods
53 pthread_mutex_t tritonn_mutex; ///< This is the mutex used to init the hash; variable for tritonn share methods
54
55 static uchar* get_key(TRITONN_SHARE *share, size_t *length,
56 my_bool not_used __attribute__((unused)))
57 {
58 *length=share->table_name_length;
59 return (uchar*) share->table_name;
60 }
61
62 static int tritonn_init_hton(void *p)
63 {
64 DBUG_ENTER("tritonn_init_hton");
65 DBTN;
66
67 handlerton *hton;
68
69 hton= (handlerton *)p;
70 VOID(pthread_mutex_init(&tritonn_mutex, MY_MUTEX_INIT_FAST));
71 (void) hash_init(&tritonn_open_tables, system_charset_info, 32, 0, 0,
72 (hash_get_key) get_key, 0, 0);
73
74 hton->state = SHOW_OPTION_YES;
75 hton->create = tritonn_create_handler;
76 hton->drop_database = tritonn_drop_database;
77 hton->flush_logs = tritonn_flush_logs;
78 hton->show_status = tritonn_show_status;
79 hton->flags = tritonn_hton_flags;
80
81 sen_init();
82 DBUG_RETURN(0);
83 }
84
85 static int tritonn_deinit_hton(void *p)
86 {
87 int error= 0;
88 DBUG_ENTER("tritonn_deinit_hton");
89 DBTN;
90
91 if (tritonn_open_tables.records)
92 error= 1;
93 hash_free(&tritonn_open_tables);
94 while (tdb != NULL) {
95 sen_db_close(tdb->db);
96 tdb = tdb->next;
97 }
98 pthread_mutex_destroy(&tritonn_mutex);
99
100 sen_fin();
101 DBUG_RETURN(0);
102 }
103
104 /** @brief
105 Skeleton of simple lock controls. The "share" it creates is a structure we will
106 pass to each tritonn handler. Do you have to have one of these? Well, you have
107 pieces that are used for locking, and they are needed to function.
108 */
109 static TRITONN_SHARE *get_share(const char *table_name, TABLE *table)
110 {
111 TRITONN_SHARE *share;
112 uint length;
113 char *tmp_name;
114
115 DBTN;
116
117 pthread_mutex_lock(&tritonn_mutex);
118 length=(uint) strlen(table_name);
119
120 if (!(share=(TRITONN_SHARE*) hash_search(&tritonn_open_tables,
121 (uchar*) table_name,
122 length)))
123 {
124 if (!(share=(TRITONN_SHARE *)
125 my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
126 &share, sizeof(*share),
127 &tmp_name, length+1,
128 NullS)))
129 {
130 pthread_mutex_unlock(&tritonn_mutex);
131 return NULL;
132 }
133
134 share->use_count=0;
135 share->table_name_length=length;
136 share->table_name=tmp_name;
137 strmov(share->table_name,table_name);
138 if (my_hash_insert(&tritonn_open_tables, (uchar*) share))
139 goto error;
140 thr_lock_init(&share->lock);
141 pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST);
142 }
143 share->use_count++;
144 pthread_mutex_unlock(&tritonn_mutex);
145
146 return share;
147
148 error:
149 pthread_mutex_unlock(&tritonn_mutex);
150 pthread_mutex_destroy(&share->mutex);
151 my_free((uchar *) share, MYF(0));
152
153 return NULL;
154 }
155
156 /** @brief
157 Free lock controls. We call this whenever we close a table. If the table had
158 the last reference to the share, then we free memory associated with it.
159 */
160 static int free_share(TRITONN_SHARE *share)
161 {
162 DBTN;
163 pthread_mutex_lock(&tritonn_mutex);
164 if (!--share->use_count)
165 {
166 hash_delete(&tritonn_open_tables, (uchar*) share);
167 thr_lock_delete(&share->lock);
168 pthread_mutex_destroy(&share->mutex);
169 my_free((uchar *) share, MYF(0));
170 }
171 pthread_mutex_unlock(&tritonn_mutex);
172
173 return 0;
174 }
175
176 /* create ha_tritonn instance */
177 static handler* tritonn_create_handler(handlerton *hton,
178 TABLE_SHARE *table,
179 MEM_ROOT *mem_root)
180 {
181 DBTN;
182 return new (mem_root) ha_tritonn(hton, table);
183 }
184
185 /* delete database files */
186 static void tritonn_drop_database(handlerton *hton, char* path)
187 {
188 DBTN;
189 }
190
191 /* flush logfile */
192 static bool tritonn_flush_logs(handlerton *hton)
193 {
194 DBTN;
195 return true;
196 }
197
198 /* show engine status */
199 static bool tritonn_show_status(handlerton *hton, THD *thd, stat_print_fn *print,
200 enum ha_stat_type stat)
201 {
202 DBTN;
203 return true;
204 }
205
206 ha_tritonn::ha_tritonn(handlerton *hton, TABLE_SHARE *table_arg)
207 :handler(hton, table_arg)
208 {
209 DBTN;
210 }
211
212 ha_tritonn::~ha_tritonn()
213 {
214 DBTN;
215 }
216
217 const char *ha_tritonn::table_type() const
218 {
219 DBTN;
220 return "TRITONN";
221 }
222
223 const char *ha_tritonn::index_type(uint inx) const
224 {
225 DBTN;
226 return "SENNA";
227 }
228
229 /* TODO: examin this feature */
230 static const char *ha_tritonn_exts[] = {
231 NullS
232 };
233
234 const char **ha_tritonn::bas_ext() const
235 {
236 DBTN;
237 return ha_tritonn_exts;
238 }
239
240 // see $MYSQL_SRC/sql/handler.h "bits in table_flags"
241 ulonglong ha_tritonn::table_flags() const {
242 DBTN;
243 return (HA_NO_TRANSACTIONS | HA_STATS_RECORDS_IS_EXACT |
244 HA_NO_PREFIX_CHAR_KEYS | HA_CAN_FULLTEXT | HA_NO_AUTO_INCREMENT);
245 }
246
247 // see $MYSQL_SRC/sql/handler.h, "bits in index_flags"
248 ulong ha_tritonn::index_flags(uint inx, uint part, bool all_parts) const {
249 DBTN;
250 return (HA_ONLY_WHOLE_INDEX);
251 }
252
253 int ha_tritonn::add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys) {
254 DBTN;
255 return HA_ERR_WRONG_COMMAND;
256 }
257
258 int ha_tritonn::prepare_drop_index(TABLE *table_arg, uint *key_num, uint num_of_keys)
259 {
260 DBTN;
261 return HA_ERR_WRONG_COMMAND;
262 }
263
264 int ha_tritonn::final_drop_index(TABLE *table_arg)
265 {
266 DBTN;
267 return HA_ERR_WRONG_COMMAND;
268 }
269
270
271 int ha_tritonn::open(const char *name, int mode, uint test_if_locked)
272 {
273 DBUG_ENTER("ha_tritonn::open");
274 DBTN;
275
276 if (!(share = get_share(name, table)))
277 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
278 thr_lock_data_init(&share->lock,&lock,NULL);
279 share->short_name = table_share->table_name.str;
280 ctx = sen_ctx_open(get_sen_db(table_share->db.str),SEN_CTX_USEQL);
281 call_senna_ql(ctx, "(define (select recs expr) (reverse (letrec "
282 "((func (lambda (r x) (if x (let ((y (expr x))) "
283 "(func (if y (cons y r) r) (recs ::+ x))) r)))) "
284 "(func () (recs ::)))))",false);
285 call_senna_ql(ctx, "(define (slot-exps class) (select <db> "
286 "(lambda (x) (let ((s (x ::schema))) (and (pair? s) "
287 "(eq? class (car s)) (list () (car (cdr (cdr s)))))))))",false);
288 call_senna_ql(ctx, "(define (dump-table class) (if (< 0 class.:nrecords) "
289 "(begin (disp `(: ,class (.:key ,@(slot-exps class)) 0 0) "
290 ":tsv))))",false);
291
292 DBUG_RETURN(0);
293 }
294
295 int ha_tritonn::close(void)
296 {
297 DBUG_ENTER("ha_tritonn::close");
298 DBTN;
299 sen_ctx_close(ctx);
300 DBUG_RETURN(free_share(share));
301 }
302
303 int ha_tritonn::rnd_init(bool scan)
304 {
305 DBUG_ENTER("ha_tritonn::rnd_init");
306 DBTN;
307 char buf[1024];
308 my_snprintf(buf,1024,"(dump-table <%s>)", share->short_name);
309 call_senna_ql(ctx,buf, false);
310 DBUG_RETURN(0);
311 }
312
313 int ha_tritonn::rnd_next(uchar *buf)
314 {
315 DBUG_ENTER("ha_tritonn::rnd_next");
316 DBTN;
317 char *res;
318 unsigned int res_len;
319 int res_flags;
320 char *row;
321 sen_ctx_recv(ctx,&res,&res_len,&res_flags);
322 if (res_flags & SEN_CTX_MORE) {
323 char token[1024];
324 int offset=0;
325 int i;
326 for (Field **field=table->field; *field ; field++) {
327 for (i=0; offset < res_len && *(res+offset) != '\t'; offset++,i++) {
328 token[i] = *(res+offset);
329 }
330 offset++;
331 switch((*field)->result_type()) {
332 case STRING_RESULT:
333 (*field)->store(token,i,system_charset_info);
334 break;
335 case REAL_RESULT:
336 token[i] = '\0';
337 (*field)->store(atof(token));
338 break;
339 case INT_RESULT:
340 token[i] = '\0';
341 (*field)->store(atoi(token),false);
342 break;
343 case ROW_RESULT:
344 (*field)->store("row_result",10,system_charset_info);
345 break;
346 case DECIMAL_RESULT:
347 (*field)->store("decimal",7,system_charset_info);
348 break;
349 }
350 }
351 memset(buf, 0, table->s->null_bytes);
352 DBUG_RETURN(0);
353 } else {
354 DBUG_RETURN(HA_ERR_END_OF_FILE);
355 }
356 }
357
358 void ha_tritonn::position(const uchar *record)
359 {
360 DBUG_ENTER("ha_tritonn::position");
361 DBTN;
362 DBUG_VOID_RETURN;
363 }
364
365 int ha_tritonn::rnd_pos(uchar * buf, uchar *pos)
366 {
367 DBUG_ENTER("ha_tritonn::rnd_pos");
368 DBTN;
369 DBUG_RETURN(HA_ERR_WRONG_COMMAND);
370 }
371
372 int ha_tritonn::info(uint flag)
373 {
374 DBUG_ENTER("ha_tritonn::info");
375 DBTN;
376 char buf[1024];
377 char *res;
378 unsigned int res_len;
379 int res_flag;
380 int i;
381 my_snprintf(buf,1024,"(<%s> ::nrecords)", share->short_name);
382 call_senna_ql(ctx,buf,false);
383 sen_ctx_recv(ctx,&res,&res_len,&res_flag);
384 char *res2 = (char*) sql_alloc(res_len+1);
385 for (i=0; i<res_len; i++) {
386 *(res2+i) = *(res+i);
387 }
388 *(res2+res_len) = '\0';
389 stats.records=atoi(res2);
390 // printf("[SennaQL] returned nrecords = %d\n",stats.records);
391 DBUG_RETURN(0);
392 }
393
394 THR_LOCK_DATA **ha_tritonn::store_lock(THD *thd,
395 THR_LOCK_DATA **to,
396 enum thr_lock_type lock_type)
397 {
398 DBTN;
399 if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)
400 lock.type=lock_type;
401 *to++= &lock;
402 return to;
403 }
404
405 int ha_tritonn::create(const char *name, TABLE *table_arg,
406 HA_CREATE_INFO *create_info)
407 {
408 DBUG_ENTER("ha_tritonn::create");
409 DBTN;
410 char buf[FN_REFLEN];
411 //dump_create(name,table_arg,create_info);
412 ctx = sen_ctx_open(get_sen_db(table_share->db.str),SEN_CTX_USEQL);
413 my_snprintf(buf,1024,"(ptable '<%s>)",table_arg->s->table_name);
414 call_senna_ql(ctx,buf);
415 int i;
416 /* col1 is assigned to pkey so i=1 here */
417 for (i=1; i < table_arg->s->fields; i++) {
418 Field *field = table_arg->s->field[i];
419 my_snprintf(buf,1024,"(<%s> ::def :%s <%s>)",
420 create_info->alias,
421 field->field_name,
422 mysqltype2sennatype_string(field->type()));
423 call_senna_ql(ctx,buf);
424 }
425 sen_ctx_close(ctx);
426 DBUG_RETURN(0);
427 }
428
429 uint ha_tritonn::max_supported_keys() const
430 {
431 DBTN;
432 return 1024;
433 }
434
435 uint ha_tritonn::max_supported_key_length() const
436 {
437 DBTN;
438 return 1024;
439 }
440
441 uint ha_tritonn::max_supported_key_part_length() const
442 {
443 DBTN;
444 return 1024;
445 }
446
447
448 struct st_mysql_storage_engine storage_engine_structure=
449 { MYSQL_HANDLERTON_INTERFACE_VERSION };
450
451 mysql_declare_plugin(tritonn)
452 {
453 MYSQL_STORAGE_ENGINE_PLUGIN,
454 &storage_engine_structure,
455 "TRITONN",
456 "Tritonn Project",
457 "Tritonn storage engine",
458 PLUGIN_LICENSE_BSD,
459 tritonn_init_hton, /* Plugin Init */
460 tritonn_deinit_hton, /* Plugin Deinit */
461 0x0001 /* 0.1 */,
462 NULL, /* status variables */
463 NULL, /* system variables */
464 NULL /* config options */
465 }
466 mysql_declare_plugin_end;
467
468 char *a_type[] = {"FIELD_ITEM","FUNC_ITEM", "SUM_FUNC_ITEM", "STRING_ITEM",
469 "INT_ITEM", "REAL_ITEM", "NULL_ITEM", "VARBIN_ITEM",
470 "COPY_STR_ITEM", "FIELD_AVG_ITEM", "DEFAULT_VALUE_ITEM",
471 "PROC_ITEM","COND_ITEM", "REF_ITEM", "FIELD_STD_ITEM",
472 "FIELD_VARIANCE_ITEM", "INSERT_VALUE_ITEM",
473 "SUBSELECT_ITEM", "ROW_ITEM", "CACHE_ITEM", "TYPE_HOLDER",
474 "PARAM_ITEM", "TRIGGER_FIELD_ITEM", "DECIMAL_ITEM",
475 "XPATH_NODESET", "XPATH_NODESET_CMP",
476 "VIEW_FIXER_ITEM"};
477
478 char *f_type[] ={"UNKNOWN_FUNC","EQ_FUNC","EQUAL_FUNC","NE_FUNC","LT_FUNC","LE_FUNC",
479 "GE_FUNC","GT_FUNC","FT_FUNC",
480 "LIKE_FUNC","ISNULL_FUNC","ISNOTNULL_FUNC",
481 "COND_AND_FUNC", "COND_OR_FUNC", "COND_XOR_FUNC",
482 "BETWEEN", "IN_FUNC", "MULT_EQUAL_FUNC",
483 "INTERVAL_FUNC", "ISNOTNULLTEST_FUNC",
484 "SP_EQUALS_FUNC", "SP_DISJOINT_FUNC","SP_INTERSECTS_FUNC",
485 "SP_TOUCHES_FUNC","SP_CROSSES_FUNC","SP_WITHIN_FUNC",
486 "SP_CONTAINS_FUNC","SP_OVERLAPS_FUNC",
487 "SP_STARTPOINT","SP_ENDPOINT","SP_EXTERIORRING",
488 "SP_POINTN","SP_GEOMETRYN","SP_INTERIORRINGN",
489 "NOT_FUNC", "NOT_ALL_FUNC",
490 "NOW_FUNC", "TRIG_COND_FUNC",
491 "SUSERVAR_FUNC", "GUSERVAR_FUNC", "COLLATE_FUNC",
492 "EXTRACT_FUNC", "CHAR_TYPECAST_FUNC", "FUNC_SP", "UDF_FUNC",
493 "NEG_FUNC" };
494
495 extern int string2my_decimal(uint mask, const String *str, my_decimal *d);
496 #include "item_func.h"
497 #include "my_decimal.h"
498
499 void dump_condition(Item *cond)
500 {
501 char buff[256];
502 String str(buff,(uint32) sizeof(buff), system_charset_info);
503 str.length(0);
504 cond->print(&str, QT_ORDINARY);
505 str.append("\0");
506 printf("COND* name=%s, type()=%s", cond->name, a_type[cond->type()]);
507 if (cond->type() == Item::FUNC_ITEM) {
508 Item_func *item = (Item_func*) cond;
509 printf(", functype=%s", f_type[item->functype()]);
510 } else if (cond->type() == Item::INT_ITEM) {
511 Item_int *item = (Item_int*) cond;
512 printf(", value=%d", item->value);
513 } else if (cond->type() == Item::FIELD_ITEM) {
514 }
515 printf(", str=%s",str.ptr());
516 printf("\n");
517 if (cond->next != NULL) dump_condition(cond->next);
518 return;
519 }
520
521
522 const COND* ha_tritonn::cond_push(const COND *cond)
523 {
524 printf("===ha_tritonn::cond_push is called===\n");
525 Item *item = (Item*) cond;
526 dump_condition(item);
527 return cond;
528 }
529
530 static void dump_create(const char *name, TABLE *table_arg,
531 HA_CREATE_INFO *create_info)
532 {
533 int i;
534 printf("===dump_create is called===\n");
535 printf("argments:: name=%s, table_arg=%p, create_info=%p\n",name,table_arg,create_info);
536 printf("table_arg->s->table_name = %s\n",table_arg->s->table_name);
537 printf("table_arg->s->db = %s\n", table_arg->s->db);
538 printf("table_arg->s->path = %s\n", table_arg->s->path);
539 printf("table_arg->s->fields = %d\n", table_arg->s->fields);
540 printf("table_arg->s->keys = %d\n", table_arg->s->keys);
541 printf("table_arg->s->primary_key = %d\n", table_arg->s->primary_key);
542 printf("table_arg->s->row_type = %d\n", table_arg->s->row_type);
543 printf("create_info->alias = %s\n", create_info->alias);
544 printf("create_info->table_charset = %p\n", create_info->table_charset);
545 printf("create_info->default_table_charset = %p\n", create_info->default_table_charset);
546 printf("create_info->connect_string.str = %s\n",create_info->connect_string.str);
547 printf("create_info->comment.str = %s\n", create_info->comment.str);
548
549 for (i=0; i < table_arg->s->fieldnames.count; i++) {
550 printf(" table_arg->s->fieldnames.type_names=%s\n", table_arg->s->fieldnames.type_names[i]);
551 }
552 for (i=0; i < table_arg->s->keynames.count; i++) {
553 printf(" table_arg->s->keynames.type_names=%s\n", table_arg->s->keynames.type_names[i]);
554 }
555
556 for (i=0; i < table_arg->s->fields; i++) {
557 Field *field = table_arg->s->field[i];
558 printf(" field=%p\n",field);
559 printf(" field->field_name = %s\n", field->field_name);
560 printf(" field->comment.str = %s\n", field->comment.str);
561 printf(" field->field_length = %d\n", field->field_length);
562 printf(" field->unireg_chekc = %d\n", field->unireg_check);
563 printf(" field->flags = %d\n", field->flags);
564 printf(" field->field_index = %d\n", field->field_index);
565 printf(" field->type() = %d\n", field->type());
566 printf(" field->result_type() = %d\n", field->result_type());
567 }
568
569 int keys = table_arg->s->keys;
570 for (i=0; i < keys; i++) {
571 KEY *key = table_arg->key_info+i;
572 printf(" key=%p\n",key);
573 printf(" key->name = %s\n", key->name);
574 printf(" key->algorithm = %d\n", key->algorithm);
575 printf(" key->key_parts = %d\n", key->key_parts);
576 int j;
577 for (j=0; j < key->key_parts; j++) {
578 KEY_PART_INFO *part = key->key_part+j;
579 printf(" part=%p\n",part);
580 printf(" part->fieldnr=%d\n",part->fieldnr);
581 printf(" part->field->field_name=%s\n",part->field->field_name);
582 printf(" part->field->comment.str=%s\n",part->field->comment.str);
583 }
584 }
585 }
586
587 void call_senna_ql(sen_ctx *ctx, const char *str, bool disp)
588 {
589 char *ql;
590 char *res;
591 unsigned int res_len;
592 int res_flags;
593 char *buf;
594 unsigned int ql_len = strlen(str);
595 ql = (char*) malloc(ql_len);
596 strncpy(ql,str,ql_len);
597 sen_ctx_send(ctx,ql,ql_len,0);
598 if (disp == true) {
599 do {
600 sen_ctx_recv(ctx,&res,&res_len,&res_flags);
601 buf = (char*) calloc(1,1024);
602 printf("[SennaQL] %s => %s\n",str,strncat(buf,res,res_len));
603 free(buf);
604 } while (res_flags & SEN_CTX_MORE);
605 }
606 free(ql);
607 }
608
609 static char *mysqltype2sennatype_string(enum_field_types types)
610 {
611 switch(types) {
612 case MYSQL_TYPE_TINY:
613 case MYSQL_TYPE_SHORT:
614 case MYSQL_TYPE_INT24:
615 case MYSQL_TYPE_LONG:
616 return "int";
617 case MYSQL_TYPE_FLOAT:
618 case MYSQL_TYPE_DOUBLE:
619 return "float";
620 case MYSQL_TYPE_STRING:
621 case MYSQL_TYPE_VAR_STRING:
622 case MYSQL_TYPE_VARCHAR:
623 case MYSQL_TYPE_BLOB:
624 return "text";
625 default:
626 return "null";
627 }
628 }
629
630 const char* tritonn_escape_string(const char* str){
631 int i,len,cnt,offset;
632 for (i=0,len=strlen(str),cnt=0; i<len; i++) {
633 if (*(str+i) == '\\' || *(str+i) == '"') cnt++;
634 }
635 if (cnt == 0) return str;
636 char *res = (char*) sql_alloc(len+cnt);
637 for (i=0,offset=0; i<len; i++) {
638 if (*(str+i) == '\\') {
639 *(res+i+offset) = '\\';
640 offset++;
641 *(res+i+offset) = '\\';
642 } else if (*(str+i) == '"') {
643 *(res+i+offset) = '\\';
644 offset++;
645 *(res+i+offset) = '"';
646 } else {
647 *(res+i+offset) = *(str+i);
648 }
649 }
650 return res;
651 }
652
653 int ha_tritonn::write_row(uchar* buf)
654 {
655 DBTN;
656 int i=0;
657 char ql[1024];
658 char* pkey;
659 for (Field **field=table->field; *field; field++) {
660 String str;
661 (*field)->val_str(&str);
662 str.chop();
663 if (i==0) {
664 pkey = (char*) sql_alloc(strlen(str.ptr()));
665 strcpy(pkey,str.ptr());
666 my_snprintf(ql,1024,"(<%s> ::new \"%s\")",share->short_name,
667 tritonn_escape_string(str.ptr()));
668 } else {
669 my_snprintf(ql,1024,"((<%s> : \"%s\") :%s \"%s\")",
670 share->short_name,
671 tritonn_escape_string(pkey), (*field)->field_name,
672 tritonn_escape_string(str.ptr()));
673 }
674 call_senna_ql(ctx,ql);
675 i++;
676 }
677 return 0;
678 }
679
680 TRITONN_DB *open_or_create_db(const char *db_name)
681 {
682 char file_name[FN_REFLEN];
683 TRITONN_DB *d = (TRITONN_DB*) my_malloc(sizeof(TRITONN_DB), MYF(0));
684 d->db_name_length = strlen(db_name);
685 d->db_name = (char*) my_malloc(d->db_name_length,MYF(0));
686 memcpy(d->db_name,db_name,d->db_name_length);
687 my_snprintf(file_name,FN_REFLEN,"%s/tritonn.db",db_name);
688 d->db = sen_db_open(file_name);
689 if (d->db == NULL) {
690 d->db = sen_db_create(file_name,0,sen_enc_utf8);
691 }
692 d->next = NULL;
693 pthread_mutex_unlock(&tritonn_mutex);
694 return d;
695 }
696
697 sen_db *get_sen_db(const char *db_name)
698 {
699 pthread_mutex_lock(&tritonn_mutex);
700 /* case1: no instance created yet */
701 if (tdb == NULL) {
702 tdb = open_or_create_db(db_name);
703 pthread_mutex_unlock(&tritonn_mutex);
704 return tdb->db;
705 }
706 /* case2: instance hit */
707 TRITONN_DB *cur = tdb;
708 while (true) {
709 if (strcmp(cur->db_name,db_name) == 0) {
710 pthread_mutex_unlock(&tritonn_mutex);
711 return cur->db;
712 } else if (cur->next != NULL) {
713 cur = cur->next;
714 } else {
715 break;
716 }
717 }
718 /* case3: instance not hit */
719 cur->next = open_or_create_db(db_name);
720 pthread_mutex_unlock(&tritonn_mutex);
721 return cur->next->db;
722 }
723

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26