9 #define MAX_LINE_SZ 256
10 #define expect(c) do { if( ch != c ) return -1; ++cp; } while(0)
15 char line[MAX_LINE_SZ];
17 iline(FILE *f) : fp(f), pos(0), no(0) { line[0] = 0; }
19 fp = i.fp; pos = i.pos;
20 strcpy(line,i.line); no = i.no;
24 class ichar : public virtual iline {
27 ichar(FILE *f) : iline(f) { i = n = 0; }
31 char &operator [](int n) { return line[i+n]; }
32 char &operator +=(int n) { i+=n; return operator*(); }
33 char &operator -=(int n) { i-=n; return operator*(); }
34 friend ichar &operator ++(ichar &t);
35 friend char operator ++(ichar &t,int);
38 ichar &operator ++(ichar &t) { ++t.i; return t; }
39 char operator ++(ichar &t,int) { return t.line[t.i++]; }
41 char &ichar::operator *()
44 int ch; fseek(fp, pos, SEEK_SET);
45 for( i=n=0; n<MAX_LINE_SZ; ) {
46 if( (ch=fgetc(fp)) < 0 ) ch = 0;
47 if( (line[n++]=ch) == '\n' || !ch ) break;
49 if( ch == '\n' ) ++no;
57 typedef list<string *> eobjs;
63 enum { ty_none, ty_bit, ty_boolean,
64 ty_tinyint, ty_smallint, ty_mediumint, ty_decimal,
65 ty_integer, ty_bigint, ty_real, ty_double, ty_float,
66 ty_date, ty_time, ty_timestamp, ty_datetime, ty_year,
67 ty_char, ty_varchar, ty_binary, ty_varbinary,
68 ty_blob, ty_tinyblob, ty_mediumblob, ty_longblob,
69 ty_text, ty_tinytext, ty_mediumtext, ty_longtext,
70 ty_enum, ty_set, ty_media } ty;
72 var_types = (1<<ty_varchar) | (1<<ty_varbinary) | (1<<ty_blob) |
73 (1<<ty_tinyblob) | (1<<ty_mediumblob) | (1<<ty_longblob) |
75 text_types = (1<<ty_text) |
76 (1<<ty_tinytext) | (1<<ty_mediumtext) | (1<<ty_longtext),
77 integer_types = (1<<ty_boolean) | (1<<ty_bit) | (1<<ty_binary) |
78 (1<<ty_tinyint) | (1<<ty_smallint) | (1<<ty_decimal) |
79 (1<<ty_mediumint) | (1<<ty_integer) | (1<<ty_bigint),
80 double_types = (1<<ty_real) | (1<<ty_double) | (1<<ty_float),
82 int is_var() { return (var_types>>ty) & 1; }
83 int is_integer() { return (integer_types>>ty) & 1; }
84 int is_double() { return (double_types>>ty) & 1; }
85 int length, zeroed, is_null, is_autoincr, is_binary, is_unsign, has_def;
88 enum def_type { def_none, def_integer, def_double, def_string, def_null, };
89 union { int i; double d; string *s; } def;
90 dobj(tobj *tp) : top(tp) {
91 ty = ty_none; idx = 0;
92 length = zeroed = is_null = is_autoincr = is_binary = is_unsign = has_def = -1;
97 typedef list<dobj*> dobjs;
103 dobj *dobj_of(const char *knm);
111 tobj *tobj_of(const char *tnm)
113 list<tobj*>::iterator it = tables.begin();
114 list<tobj*>::iterator eit = tables.end();
115 while( it!=eit && *(*it)->name!=tnm ) ++it;
116 return it == eit ? 0 : *it;
119 dobj *tobj::dobj_of(const char *knm)
121 dobjs::iterator eid = dop.end();
122 dobjs::iterator id = dop.begin();
123 while( id!=eid && *(*id)->name!=knm ) ++id;
124 return id == eid ? 0 : *id;
132 short unique, primary;
135 iobj() : name(0), tbl(0), unique(0), primary(0), is_dir(-1) {}
139 list<iobj*> indecies;
144 enum { xref_no_action, xref_restrict, xref_cascade, xref_set_null, };
145 int on_delete, on_update;
147 robj() : on_delete(xref_no_action), on_update(xref_no_action) {}
157 if( isspace(*b) ) { ++b; continue; }
158 if( *b == '/' && b[1] == '*' ) {
159 ++b; do { ++b; } while( *b != '*' || b[1] != '/' );
162 else if( *b == '-' && b[1] == '-' ) {
163 ++b; do { ++b; } while( *b != '\n' );
173 string *tid(ichar &c, string *sp=0)
177 if( *b && (isalpha(*b) || *b == '_') ) {
178 rp = !sp ? new string() : sp;
179 rp->push_back(toupper(b++));
180 while( *b && (isalpha(*b) || isdigit(*b) || *b == '_') ) {
181 rp->push_back(tolower(b++));
188 // scan string '..' or ".."
189 int str_value(ichar &cp, string *&sp)
191 ichar bp = cp; sp = 0;
193 if( ch != '\'' && ch != '"' ) return -1;
194 int delim = ch; ++cp;
195 for( sp=new string(); (ch=*cp) && ch != delim; ++cp ) {
196 if( ch == '\\' && !(ch=*++cp) ) break;
208 // scan string '..' or "..", or number, or NULL
209 int def_value(ichar &cp, dobj *dp)
212 if( str_value(cp,dp->def.s) >= 0 ) {
213 dp->has_def = dobj::def_string;
217 if( isdigit(ch) || ch == '-' || ch == '+' ) {
219 if( ch == '-' ) sign = -1;
220 if( ch == '+' ) sign = 1;
221 if( sign ) ++cp; else sign = 1;
223 while( (ch-='0') >= 0 && ch <= 9 ) {
224 n = n*10 + ch; ch = *++cp;
229 while( (ch-='0') >= 0 && ch <= 9 ) {
230 v = v + ch/(frac*=10); ch = *++cp;
232 dp->has_def = dobj::def_double;
233 dp->def.d = v * sign;
236 dp->has_def = dobj::def_integer;
237 dp->def.i = n * sign;
241 string *id = tid(cp);
243 if( *id == "Null" ) {
244 dp->has_def = dobj::def_null;
255 int dimen(ichar &cp, dobj *dp)
261 while( (ch-='0') >= 0 && ch <= 9 ) {
262 n = n*10 + ch; ch = *++cp;
264 ch = *tws(cp); expect(')');
270 // scan Unsigned or Signed, Zerofill
271 int numeric(ichar &cp, dobj *dp)
274 string *id = tid(cp);
275 if( id && *id == "Unsigned" ) {
277 bp = cp; id = tid(cp);
279 else if( id && *id == "Signed" ) {
281 bp = cp; id = tid(cp);
283 if( id && *id == "Zerofill" ) {
291 // (number) or numeric qualifier
292 int dimen0(ichar &cp, dobj *dp)
294 return dimen(cp, dp) < 0 || numeric(cp, dp) < 0 ? -1 : 0;
298 int dtype(ichar &cp, dobj *dp)
300 string *id = tid(cp);
304 dp->ty = dobj::ty_bit;
305 if( dimen0(cp, dp) < 0 ) return -1;
309 if( *id == "Tinyint" ) {
310 dp->ty = dobj::ty_tinyint;
311 if( dimen0(cp, dp) < 0 ) return -1;
315 if( *id == "Smallint" ) {
316 dp->ty = dobj::ty_smallint;
317 if( dimen0(cp, dp) < 0 ) return -1;
321 if( *id == "Mediumint" ) {
322 dp->ty = dobj::ty_mediumint;
323 if( dimen0(cp, dp) < 0 ) return -1;
327 if( *id == "Int" || *id == "Integer" ) {
328 dp->ty = dobj::ty_integer;
329 if( dimen0(cp, dp) < 0 ) return -1;
333 if( *id == "Bigint" ) {
334 dp->ty = dobj::ty_bigint;
335 if( dimen0(cp, dp) < 0 ) return -1;
339 if( *id == "Real" ) {
340 dp->ty = dobj::ty_real;
341 if( dimen0(cp, dp) < 0 ) return -1;
345 if( *id == "Double" ) {
346 dp->ty = dobj::ty_double;
347 if( dimen0(cp, dp) < 0 ) return -1;
351 if( *id == "Float" ) {
352 dp->ty = dobj::ty_float;
353 if( dimen0(cp, dp) < 0 ) return -1;
357 if( *id == "Decimal" ) {
358 dp->ty = dobj::ty_decimal;
359 if( dimen0(cp, dp) < 0 ) return -1;
363 if( *id == "Date" ) {
364 dp->ty = dobj::ty_date;
367 else if( *id == "Time" ) {
368 dp->ty = dobj::ty_time;
371 else if( *id == "Timestamp" ) {
372 dp->ty = dobj::ty_timestamp;
375 else if( *id == "Datetime" ) {
376 dp->ty = dobj::ty_datetime;
379 else if( *id == "Year" ) {
380 dp->ty = dobj::ty_year;
384 if( *id == "Char" ) {
385 dp->ty = dobj::ty_char;
386 if( dimen(cp, dp) < 0 ) return -1;
390 if( *id == "Varchar" ) {
391 dp->ty = dobj::ty_varchar;
392 if( dimen(cp, dp) < 0 ) return -1;
393 if( (id=tid(cp)) != 0 ) {
395 if( *id == "Binary" ) {
404 if( *id == "Binary" ) {
405 dp->ty = dobj::ty_binary;
406 if( dimen(cp, dp) < 0 ) return -1;
410 if( *id == "Varbinary" ) {
411 dp->ty = dobj::ty_varbinary;
412 if( dimen(cp, dp) < 0 ) return -1;
416 if( *id == "Tinyblob" ) {
417 dp->ty = dobj::ty_tinyblob;
421 if( *id == "Blob" ) {
422 dp->ty = dobj::ty_blob;
426 if( *id == "Mediumblob" ) {
428 dp->ty = dobj::ty_mediumblob;
432 if( *id == "Longblob" ) {
433 dp->ty = dobj::ty_longblob;
437 if( *id == "Tinytext" ) {
438 dp->ty = dobj::ty_tinytext;
442 if( *id == "Text" ) {
443 dp->ty = dobj::ty_text;
447 if( *id == "Mediumtext" ) {
448 dp->ty = dobj::ty_mediumtext;
452 if( *id == "Longtext" ) {
453 dp->ty = dobj::ty_longtext;
457 if( *id == "Bool" || *id == "Boolean" ) {
458 dp->ty = dobj::ty_boolean;
462 if( *id == "Enum" ) {
463 dp->ty = dobj::ty_enum;
464 int ch = *tws(cp); expect('(');
465 if( str_value(tws(cp),id) < 0 ) return -1;
466 dp->eop.push_back(id);
467 while( *tws(cp) == ',' ) {
468 if( str_value(tws(++cp),id) < 0 ) return -1;
469 dp->eop.push_back(id);
471 ch = *tws(cp); expect(')');
475 if( *id == "Media" ) {
476 dp->ty = dobj::ty_media;
485 int xrefer(ichar &cp, robj *rp)
487 string *id = tid(cp);
490 int ch = *tws(cp); expect('(');
491 if( !(id=tid(cp)) ) return -1;
492 rp->keys.push_back(id);
493 while( *tws(cp) == ',' ) {
494 if( !(id=tid(++cp)) ) return -1;
495 rp->keys.push_back(id);
497 ch = *tws(cp); expect(')');
498 if( !(id=tid(cp)) ) return -1;
499 if( *id != "On" ) return -1;
500 if( !(id=tid(cp)) ) return -1;
502 if( *id == "Delete" ) {
505 else if( *id == "Update" ) {
509 if( !(id=tid(cp)) ) return -1;
510 if( *id == "Restrict" ) {
511 rp->on_delete = robj::xref_restrict;
514 if( *id == "Cascade" ) {
515 rp->on_delete = robj::xref_cascade;
519 if( !(id=tid(cp)) ) return -1;
520 if( *id != "Null" ) return -1;
521 rp->on_delete = robj::xref_set_null;
525 if( !(id=tid(cp)) ) return -1;
526 if( *id != "Action" ) return -1;
527 rp->on_delete = robj::xref_no_action;
533 // scan datatype extension
534 int xtype(ichar &cp, dobj *dp)
536 string *id = tid(cp);
539 if( *tid(cp) != "Null" ) return -1;
544 if( *id == "Null" ) {
549 if( *id == "Default" ) {
550 if( def_value(tws(cp),dp) < 0 ) return -1;
554 if( *id == "Auto_increment" ) {
556 if( dp->idx ) dp->idx->unique = 1;
560 if( *id == "Unique" || *id == "Primary" ) {
561 int unique = dp->is_autoincr > 0 ? 1 : 0;
563 if( *id == "Unique" ) {
564 unique = 1; id = tid(cp);
566 if( *id == "Primary" ) primary = 1;
568 if( *tid(cp) != "Key" ) cp = bp;
569 iobj *idx = new iobj();
571 idx->name = new string(*dp->name);
572 idx->name->push_back('_');
574 idx->unique = unique;
575 idx->primary = primary;
576 idx->keys.push_back(dp);
577 indecies.push_back(idx);
582 if( *id == "Comment" ) {
586 if( *id == "Column_format" ) {
590 if( *id == "Storage" ) {
595 if( *id == "References" ) {
597 robj *rop = new robj();
598 if ( xrefer(cp, rop) < 0 ) {
608 // scan table member line
609 int member(ichar &cp, dobj *dp)
612 if( dtype(cp,dp) < 0 ) return -1;
614 for( int ch=*tws(cp); (ch=*tws(cp)) && isalpha(ch); ) {
615 if( xtype(cp,dp) < 0 ) return -1;
621 // scan create table line
622 int table(ichar &cp, tobj *top)
624 string *id = tid(cp);
627 int ch = *tws(cp); expect('(');
629 dobj *dp = new dobj(top);
630 if( member(cp,dp) < 0 ) {
631 printf(" err in %s/%s at %d\n",id->c_str(),dp->name->c_str(),cp.no);
635 top->dop.push_back(dp);
636 if( (ch=*tws(cp)) == ')' ) break;
640 while( (id=tid(cp)) ) {
641 ch = *tws(cp); expect('=');
642 printf(" skipping %s at %d\n",id->c_str(),cp.no);
643 if( isdigit(*tws(cp)) ) while( isdigit(*++cp) );
644 else if( !tid(cp) ) return -1;
646 ch = *tws(cp); expect(';');
650 int iobj::is_direct()
654 dobjs::iterator ekey = keys.end();
655 dobjs::iterator key = keys.begin();
656 for( int i=0; key!=ekey; ++i ) {
658 if( dp->is_integer() ) continue;
659 if( dp->is_double() ) continue;
667 int keylen(ichar &cp, iobj *ip)
673 while( (ch-='0') >= 0 && ch <= 9 ) {
674 n = n*10 + ch; ch = *++cp;
676 ch = *tws(cp); expect(')');
681 // scan create index line
682 int index(ichar &cp, iobj *iop)
684 string *id = tid(cp);
687 if( !(id=tid(cp)) ) return -1;
688 if( *id != "On" ) return -1;
689 if( !(id=tid(cp)) ) return -1;
690 tobj *tp = tobj_of(id->c_str());
692 printf("index err On:%s at %d\n",id->c_str(),cp.no);
696 int ch = *tws(cp); expect('(');
697 if( !(id=tid(cp)) ) return -1;
698 dobj *dp = tp->dobj_of(id->c_str());
700 printf("index err Key:%s/%s at %d\n",tp->name->c_str(),id->c_str(),cp.no);
703 iop->keys.push_back(dp);
704 if( keylen(cp,iop) < 0 ) return -1;
705 while( *tws(cp) == ',' ) {
706 if( !(id=tid(++cp)) ) return -1;
707 dp = tp->dobj_of(id->c_str());
709 printf("index err Key:%s/%s at %d\n",tp->name->c_str(),id->c_str(),cp.no);
712 iop->keys.push_back(dp);
713 if( keylen(cp,iop) < 0 ) return -1;
715 ch = *tws(cp); expect(')');
716 ch = *tws(cp); expect(';');
720 // process create line
721 int create(ichar &cp)
723 int online = -1; (void) online; // avoid unused warn
724 enum { none, unique, fulltext, spatial } modifier = none;
726 string *tp = tid(cp);
727 if( *tp == "Table" ) {
728 printf("Create Table at %d\n",cp.no);
729 tobj *top = new tobj();
730 if( table(cp, top) < 0 ) {
734 tables.push_back(top);
737 if( *tp == "Online" ) {
741 else if( *tp == "Offine" ) {
745 if( *tp == "Unique" ) {
749 else if( *tp == "Fulltext" ) {
753 else if( *tp == "Spatial" ) {
757 if( *tp == "Index" ) {
758 printf("Create index at %d\n",cp.no);
759 iobj *iop = new iobj();
760 if( index(cp, iop) < 0 ) {
762 printf("== FAILED!\n");
765 if( modifier == unique ) iop->unique = 1;
766 indecies.push_back(iop);
769 fprintf(stderr,"unknown keyword - %s\n", tp->c_str());
773 void varg_dobj(FILE *sp, dobj *dp, const char *ty, int is_unsign=-1)
775 const char *tnm = dp->top->name->c_str();
776 const char *nm = dp->name->c_str();
777 fprintf(sp,"const %sObj::t_%s &%s", tnm, nm, nm);
780 void arg_dobj(FILE *sp, dobj *dp, const char *ty, int is_unsign=-1)
782 if( is_unsign < 0 ) is_unsign = dp->is_unsign;
783 if( is_unsign > 0 ) fprintf(sp, "unsigned ");
784 fprintf(sp,"%s ", ty);
785 if( dp->length > 0 ) fprintf(sp, "*");
786 fprintf(sp,"%s", dp->name->c_str());
789 void arg_dobj(FILE *sp, dobj *dp)
792 case dobj::ty_boolean:
794 case dobj::ty_binary: arg_dobj(sp, dp, "char", 1); break;
796 case dobj::ty_tinyint: arg_dobj(sp, dp, "char"); break;
798 case dobj::ty_smallint: arg_dobj(sp, dp, "short"); break;
799 case dobj::ty_decimal:
800 case dobj::ty_mediumint:
801 case dobj::ty_integer: arg_dobj(sp, dp, "int"); break;
802 case dobj::ty_bigint: arg_dobj(sp, dp, "long"); break;
804 case dobj::ty_double: arg_dobj(sp, dp, "double", 0); break;
805 case dobj::ty_float: arg_dobj(sp, dp, "float", 0); break;
808 case dobj::ty_timestamp:
809 case dobj::ty_datetime:
810 case dobj::ty_year: varg_dobj(sp, dp, "char",0); break;
811 case dobj::ty_varchar:
812 if( dp->is_binary ) { varg_dobj(sp, dp, "char",1); break; }
813 case dobj::ty_tinytext:
815 case dobj::ty_mediumtext:
816 case dobj::ty_longtext: varg_dobj(sp, dp, "char",0); break;
817 case dobj::ty_varbinary:
818 case dobj::ty_tinyblob:
820 case dobj::ty_mediumblob:
821 case dobj::ty_longblob:
822 case dobj::ty_media: varg_dobj(sp, dp, "char",1); break;
824 fprintf(sp,"unimplemented %s,", dp->name->c_str());
829 void put_targs(FILE *sp, tobj *tp, iobj *ip)
831 dobjs::iterator ekey=ip->keys.end();
832 dobjs::iterator key=ip->keys.begin();
834 while( key != ekey ) {
836 if( !dp || dp->ty == dobj::ty_none ) {
837 fprintf(stderr," %s member %s error: ty_none\n",
838 tp->name->c_str(),dp->name->c_str());
843 if( key == ekey ) break;
848 const char *typ_dobj(dobj *dp)
852 case dobj::ty_boolean:
854 case dobj::ty_binary: cp = "unsigned char"; break;
856 case dobj::ty_tinyint: cp = dp->is_unsign > 0 ? "unsigned char" : "char"; break;
858 case dobj::ty_smallint: cp = dp->is_unsign > 0 ? "unsigned short" : "short"; break;
859 case dobj::ty_decimal:
860 case dobj::ty_mediumint:
861 case dobj::ty_integer: cp = dp->is_unsign > 0 ? "unsigned int" : "int"; break;
862 case dobj::ty_bigint: cp = dp->is_unsign > 0 ? "unsigned long" : "long"; break;
864 case dobj::ty_double: cp = "double"; break;
865 case dobj::ty_float: cp = "float"; break;
868 case dobj::ty_timestamp:
869 case dobj::ty_datetime:
870 case dobj::ty_year: cp = "char"; break;
871 case dobj::ty_varchar:
872 if( dp->is_binary ) { cp = "unsigned char"; break; }
873 case dobj::ty_tinytext:
875 case dobj::ty_mediumtext:
876 case dobj::ty_longtext: cp = "char"; break;
877 case dobj::ty_varbinary:
878 case dobj::ty_tinyblob:
880 case dobj::ty_mediumblob:
881 case dobj::ty_longblob:
882 case dobj::ty_media: cp = "unsigned char"; break;
883 default: cp = "unimplemented"; break;
888 void put_keysz(FILE *sp, tobj *tp, iobj *ip)
890 dobjs::iterator ekey=ip->keys.end();
891 dobjs::iterator key=ip->keys.begin();
892 const char *tnm = tp->name->c_str();
894 while( key != ekey ) {
896 const char *nm = dp->name->c_str();
897 fprintf(sp," +sizeof(%sObj::t_%s)", tnm, nm);
899 if( ip->unique <= 0 ) fprintf(sp,"+sizeof(int)");
902 void put_keys(FILE *sp, tobj *tp, iobj *ip)
904 dobjs::iterator ekey = ip->keys.end();
905 dobjs::iterator key = ip->keys.begin();
906 const char *tnm = tp->name->c_str();
908 while( key != ekey ) {
910 const char *nm = dp->name->c_str();
911 fprintf(sp," %sObj::t_%s v_%s;\n", tnm, nm, nm);
913 if( ip->unique <= 0 ) fprintf(sp," int v_id;\n");
916 void put_init(FILE *sp, tobj *tp, iobj *ip)
918 dobjs::iterator ekey = ip->keys.end();
919 dobjs::iterator key = ip->keys.begin();
921 while( key != ekey ) {
923 const char *nm = dp->name->c_str();
924 fprintf(sp,",\n v_%s(%s)", nm, nm);
928 const char *put_cmpr(dobj *dp)
932 case dobj::ty_boolean:
934 case dobj::ty_binary: cp = "uchar"; break;
936 case dobj::ty_tinyint: cp = dp->is_unsign > 0 ? "uchar" : "char"; break;
938 case dobj::ty_smallint: cp = dp->is_unsign > 0 ? "ushort" : "short"; break;
939 case dobj::ty_decimal:
940 case dobj::ty_mediumint:
941 case dobj::ty_integer: cp = dp->is_unsign > 0 ? "uint" : "int"; break;
942 case dobj::ty_bigint: cp = dp->is_unsign > 0 ? "ulong" : "long"; break;
944 case dobj::ty_double: cp = "double"; break;
945 case dobj::ty_float: cp = "float"; break;
948 case dobj::ty_timestamp:
949 case dobj::ty_datetime:
950 case dobj::ty_year: cp = "char"; break;
951 case dobj::ty_varchar:
952 if( dp->is_binary ) { cp = "uchar"; break; }
953 case dobj::ty_tinytext:
955 case dobj::ty_mediumtext:
956 case dobj::ty_longtext: cp = "char"; break;
957 case dobj::ty_varbinary:
958 case dobj::ty_tinyblob:
960 case dobj::ty_mediumblob:
961 case dobj::ty_longblob: cp = "uchar"; break;
962 case dobj::ty_media: cp = "media"; break;
963 default: cp = "unimplemented"; break;
968 void put_rkey(FILE *sp, tobj *tp, iobj *ip)
970 dobjs::iterator ekey=ip->keys.end();
971 dobjs::iterator key=ip->keys.begin();
973 while( key != ekey ) {
975 const char *nm = dp->name->c_str();
976 fprintf(sp," if( bp ) memcpy(cp, kloc._%s(), kloc.size_%s());\n", nm, nm);
977 fprintf(sp," cp += kloc.size_%s();\n", nm);
979 if( ip->unique <= 0 ) {
980 fprintf(sp," if( bp ) memcpy(cp, kloc._id(), kloc._id_size());\n");
981 fprintf(sp," cp += kloc._id_size();\n");
985 void dir_rcmpr(FILE *sp, tobj *tp, iobj *ip)
987 dobjs::iterator ekey=ip->keys.end();
988 dobjs::iterator key=ip->keys.begin();
990 while( key != ekey ) {
992 fprintf(sp," { %s vv", typ_dobj(dp));
993 if( dp->length > 0 ) fprintf(sp, "[%d]", dp->length);
994 fprintf(sp,"; memcpy(&vv,b,sizeof(vv)); b += sizeof(vv);\n");
995 fprintf(sp," int v = cmpr_%s", put_cmpr(dp));
996 const char *nm = dp->name->c_str();
997 fprintf(sp,"( kloc._%s(), kloc->v_%s.size(), &vv", nm, nm);
998 if( dp->length > 0 ) fprintf(sp, "[0]");
999 fprintf(sp,", sizeof(vv));\n");
1000 fprintf(sp," if( v != 0 ) return v; }\n");
1002 if( ip->unique <= 0 ) {
1003 fprintf(sp," int vid; memcpy(&vid,b,sizeof(vid)); b += sizeof(vid);\n");
1004 fprintf(sp," int v = cmpr_int(kloc._id(), kloc._id_size(), &vid, sizeof(vid));\n");
1005 fprintf(sp," if( v != 0 ) return v;\n");
1009 void ind_rcmpr(FILE *sp, tobj *tp, iobj *ip)
1011 fprintf(sp," int b_id; memcpy(&b_id,b,sizeof(b_id));\n");
1012 fprintf(sp," if( kloc->id == b_id ) return 0;\n");
1013 fprintf(sp," %sLoc vloc(kloc.entity);\n", tp->name->c_str());
1014 fprintf(sp," if( vloc.FindId(b_id) )\n");
1015 fprintf(sp," kloc.err_(Db::errCorrupt);\n");
1016 dobjs::iterator ekey=ip->keys.end();
1017 dobjs::iterator key=ip->keys.begin();
1019 while( key != ekey ) {
1021 const char *nm = dp->name->c_str();
1022 fprintf(sp," { int v = cmpr_%s", put_cmpr(dp));
1023 fprintf(sp,"( kloc._%s(), kloc->v_%s.size(),\n", nm, nm);
1024 fprintf(sp," vloc._%s(), vloc->v_%s.size());\n", nm, nm);
1025 fprintf(sp," if( v != 0 ) return v; }\n");
1027 if( ip->unique <= 0 ) {
1028 fprintf(sp," { int v = cmpr_int(kloc._id(), kloc._id_size(),\n");
1029 fprintf(sp," vloc._id(), vloc._id_size());\n");
1030 fprintf(sp," if( v != 0 ) return v; }\n");
1034 void dir_icmpr(FILE *sp, tobj *tp, iobj *ip)
1036 dobjs::iterator ekey=ip->keys.end();
1037 dobjs::iterator key=ip->keys.begin();
1039 while( key != ekey ) {
1041 fprintf(sp," { %s vv", typ_dobj(dp));
1042 if( dp->length > 0 ) fprintf(sp, "[%d]", dp->length);
1043 fprintf(sp,"; memcpy(&vv,b,sizeof(vv)); b += sizeof(vv);\n");
1044 fprintf(sp," int v = cmpr_%s", put_cmpr(dp));
1045 const char *nm = dp->name->c_str();
1046 fprintf(sp,"( kp->v_%s.addr(), kp->v_%s.size(), &vv", nm, nm);
1047 if( dp->length > 0 ) fprintf(sp, "[0]");
1048 fprintf(sp,", sizeof(vv));\n");
1049 fprintf(sp," if( v != 0 ) return v; }\n");
1051 if( ip->unique <= 0 ) {
1052 fprintf(sp," if( kp->v_id >= 0 ) {\n");
1053 fprintf(sp," int vid; memcpy(&vid,b,sizeof(vid)); b += sizeof(vid);\n");
1054 fprintf(sp," int v = cmpr_int(&kp->v_id, sizeof(kp->v_id), &vid, sizeof(vid));\n");
1055 fprintf(sp," if( v != 0 ) return v;\n");
1060 void ind_icmpr(FILE *sp, tobj *tp, iobj *ip)
1062 fprintf(sp," int b_id; memcpy(&b_id,b,sizeof(b_id)); b += sizeof(b_id);\n");
1063 if( ip->unique <= 0 ) fprintf(sp," if( kp->v_id == b_id ) return 0;\n");
1064 fprintf(sp," %sLoc vloc(kp->loc.entity);\n", tp->name->c_str());
1065 fprintf(sp," if( vloc.FindId(b_id) )\n");
1066 fprintf(sp," vloc.err_(Db::errCorrupt);\n");
1068 dobjs::iterator ekey=ip->keys.end();
1069 dobjs::iterator key=ip->keys.begin();
1071 while( key != ekey ) {
1073 const char *nm = dp->name->c_str();
1074 fprintf(sp," { int v = cmpr_%s", put_cmpr(dp));
1075 fprintf(sp,"( kp->v_%s.addr(), kp->v_%s.size(),\n", nm, nm);
1076 fprintf(sp," vloc._%s(), vloc->v_%s.size());\n", nm, nm);
1077 fprintf(sp," if( v != 0 ) return v; }\n");
1079 if( ip->unique <= 0 ) {
1080 fprintf(sp," if( kp->v_id >= 0 ) {\n");
1081 fprintf(sp," int v = cmpr_int(&kp->v_id, sizeof(kp->v_id),\n");
1082 fprintf(sp," vloc._id(), vloc._id_size());\n");
1083 fprintf(sp," if( v != 0 ) return v;\n");
1088 void put_dobj(FILE *sp, dobj *dp, const char *dty, int n)
1090 fprintf(sp," array_%s(char,%s,%d);\n", dty, dp->name->c_str(), n);
1093 void put_dobj(FILE *sp, dobj *dp, const char *dty, const char *ty, int is_unsign=-1)
1095 fprintf(sp," %s_%s(", dp->length > 0 ? "array" : "basic", dty);
1096 if( is_unsign < 0 ) is_unsign = dp->is_unsign;
1097 if( is_unsign > 0 ) fprintf(sp, "unsigned ");
1098 fprintf(sp,"%s,%s", ty, dp->name->c_str());
1099 if( dp->length > 0 ) fprintf(sp, ",%d", dp->length);
1100 fprintf(sp, ");\n");
1103 void put_decl(FILE *sp, dobj *dp, const char *dty)
1106 case dobj::ty_boolean:
1108 case dobj::ty_binary: put_dobj(sp, dp, dty, "char", 1); break;
1110 case dobj::ty_tinyint: put_dobj(sp, dp, dty, "char"); break;
1112 case dobj::ty_smallint: put_dobj(sp, dp, dty, "short"); break;
1113 case dobj::ty_decimal:
1114 case dobj::ty_mediumint:
1115 case dobj::ty_integer: put_dobj(sp, dp, dty, "int"); break;
1116 case dobj::ty_bigint: put_dobj(sp, dp, dty, "long"); break;
1118 case dobj::ty_double: put_dobj(sp, dp, dty, "double", 0); break;
1119 case dobj::ty_float: put_dobj(sp, dp, dty, "float", 0); break;
1120 case dobj::ty_date: put_dobj(sp, dp, dty, 8); break;
1121 case dobj::ty_time: put_dobj(sp, dp, dty, 6); break;
1122 case dobj::ty_timestamp:
1123 case dobj::ty_datetime: put_dobj(sp, dp, dty, 14); break;
1124 case dobj::ty_year: put_dobj(sp, dp, dty, 4); break;
1126 case dobj::ty_tinytext:
1127 case dobj::ty_mediumtext:
1128 case dobj::ty_longtext:
1129 fprintf(sp," sarray_%s(char,%s);\n", dty, dp->name->c_str());
1131 case dobj::ty_varchar:
1132 if( !dp->is_binary ) {
1133 fprintf(sp," varray_%s(char,%s);\n", dty, dp->name->c_str());
1136 case dobj::ty_varbinary:
1138 case dobj::ty_tinyblob:
1139 case dobj::ty_mediumblob:
1140 case dobj::ty_longblob:
1141 case dobj::ty_media:
1142 fprintf(sp," varray_%s(unsigned char,%s);\n", dty, dp->name->c_str());
1146 fprintf(sp," %s %s unimplemented;\n", dty, dp->name->c_str());
1152 int main(int ac, char **av)
1154 const char *tdb = ac > 1 ? av[1] : "theDb";
1155 const char *sfn = ac > 2 ? av[2] : "./s";
1161 for( string *sp=tid(cp); sp!=0; sp=tid(cp) ) {
1162 if( *sp == "Create" ) create(cp);
1165 printf(" %d Tables\n",(int)tables.size());
1166 printf(" %d Indecies\n",(int)indecies.size());
1168 char fn[512]; sprintf(fn,"%s.h",sfn);
1169 FILE *sp = fopen(fn,"w");
1171 // get basename for sfn.h, _SFN_H_
1173 for( const char *ap=sfn; *ap; ++ap )
1174 if( *ap == '/' ) bp = ap+1;
1176 char ups[512], *up = ups; *up++ = '_';
1177 for( const char *cp=bp; *cp; ++cp ) *up++ = toupper(*cp);
1178 *up++ = '_'; *up++ = 'H'; *up++ = '_'; *up = 0;
1180 fprintf(sp,"#ifndef %s\n",ups);
1181 fprintf(sp,"#define %s\n",ups);
1182 fprintf(sp,"#include <cstdio>\n");
1183 fprintf(sp,"#include <stdlib.h>\n");
1184 fprintf(sp,"#include <unistd.h>\n");
1185 fprintf(sp,"#include <fcntl.h>\n");
1186 fprintf(sp,"#include <errno.h>\n");
1188 fprintf(sp,"#include \"tdb.h\"\n");
1192 list<tobj*>::iterator sit = tables.begin();
1193 list<tobj*>::iterator eit = tables.end();
1194 list<tobj*>::iterator it;
1196 list<iobj*>::iterator sidx = indecies.begin();
1197 list<iobj*>::iterator eidx = indecies.end();
1198 list<iobj*>::iterator idx;
1200 for( idx=sidx; idx!=eidx; ++idx ) {
1202 ip->is_dir = ip->is_direct();
1206 for( it=sit ; it!=eit; ++i, ++it ) {
1208 const char *tnm = tp->name->c_str();
1209 printf(" %2d. %s (",i,tnm);
1210 fprintf(sp,"// %s\n",tnm);
1211 fprintf(sp,"DbObj(%s)\n",tnm);
1213 list<dobj*>::iterator sid = tp->dop.begin();
1214 list<dobj*>::iterator eid = tp->dop.end();
1215 list<dobj*>::iterator id;
1217 // output table member declarations
1218 for( id=sid ; id!=eid; ++id ) {
1220 printf(" %s",dp->name->c_str());
1221 if( dp->ty == dobj::ty_none ) {
1222 fprintf(stderr," %s member %s error: ty_none\n",
1223 tnm,dp->name->c_str());
1226 put_decl(sp,dp,"def");
1234 for( idx=sidx; idx!=eidx; ++idx ) {
1236 if( ip->tbl != tp ) continue;
1238 printf(" %2d.%d%c %s on %s(",i,j++,
1239 ip->is_dir>0 ? '=' : '.',
1240 ip->name->c_str(),tp->name->c_str());
1241 dobjs::iterator ekey=ip->keys.end();
1242 dobjs::iterator key=ip->keys.begin();
1244 while( key != ekey ) {
1246 printf(" %s", dp->name->c_str());
1250 if( n > 0 ) printf("\n");
1252 // output table member accessors
1253 fprintf(sp,"DbLoc(%s)\n",tnm);
1254 for( id=sid ; id!=eid; ++id ) {
1256 if( dp->ty == dobj::ty_none ) {
1257 fprintf(stderr," %s member %s error: ty_none\n",
1258 tnm,dp->name->c_str());
1261 put_decl(sp, dp, "ref");
1264 for( idx=sidx; idx!=eidx; ++idx ) {
1266 if( ip->tbl != tp ) continue;
1267 const char *knm = ip->name->c_str();
1269 fprintf(sp," class key_%s { public:\n", knm);
1270 fprintf(sp," static const int size() { return 0");
1271 put_keysz(sp, *it, ip);
1272 fprintf(sp,"; }\n");
1273 fprintf(sp," };\n");
1275 fprintf(sp," class ikey_%s : public Db::iKey { public:\n", knm);
1276 put_keys(sp, *it, ip);
1277 fprintf(sp," static int icmpr(char *a, char *b);\n");
1279 fprintf(sp," ikey_%s(ObjectLoc &loc,\n", knm);
1280 put_targs(sp, *it, ip);
1281 if( ip->unique <= 0 ) fprintf(sp,", int id=-1");
1282 fprintf(sp,")\n : iKey(\"%s\",loc,icmpr)", knm);
1283 put_init(sp, *it, ip);
1284 if( ip->unique <= 0 ) fprintf(sp,",\n v_id(id)");
1285 fprintf(sp," {}\n");
1286 fprintf(sp," };\n");
1287 fprintf(sp," class rkey_%s : public Db::rKey { public:\n", knm);
1288 fprintf(sp," static int rcmpr(char *a, char *b);\n");
1289 fprintf(sp," rkey_%s(ObjectLoc &loc) : rKey(\"%s\",loc,rcmpr) {}\n", knm, knm);
1290 fprintf(sp," int wr_key(char *cp=0);\n");
1291 fprintf(sp," };\n");
1294 fprintf(sp," int Allocate();\n");
1295 fprintf(sp," int Construct();\n");
1296 fprintf(sp," int Destruct();\n");
1297 fprintf(sp," void Deallocate();\n");
1299 fprintf(sp," int Copy(ObjectLoc &that);\n");
1306 fprintf(sp,"class %s : public Db {\n",tdb);
1307 fprintf(sp," int dfd, dkey, no_atime;\n");
1308 fprintf(sp," int db_create();\n");
1309 fprintf(sp," int db_open();\n");
1310 fprintf(sp," int db_access();\n");
1311 fprintf(sp,"public:\n");
1312 fprintf(sp," Objects objects;\n");
1313 for( it=sit ; it!=eit; ++it ) {
1315 const char *tnm = tp->name->c_str();
1316 fprintf(sp," Entity %s; %sLoc %c%s;\n", tnm, tnm, tolower(tnm[0]), &tnm[1]);
1319 fprintf(sp," int create(const char *dfn);\n");
1320 fprintf(sp," int open(const char *dfn, int key=-1);\n");
1321 fprintf(sp," int access(const char *dfn, int key=-1, int rw=0);\n");
1322 fprintf(sp," void close();\n");
1323 fprintf(sp," int attach(int rw=0) { return Db::attach(rw); }\n");
1324 fprintf(sp," int detach() { return Db::detach(); }\n");
1326 fprintf(sp," %s();\n",tdb);
1327 fprintf(sp," ~%s() { finit(objects); }\n",tdb);
1330 fprintf(sp,"#endif\n");
1333 sprintf(fn,"%s.C",sfn);
1335 fprintf(sp,"#include \"%s.h\"\n",bp);
1338 for( it=sit ; it!=eit; ++it ) {
1340 const char * tnm = tp->name->c_str();
1342 for( idx=sidx; idx!=eidx; ++idx ) {
1344 if( ip->tbl != tp ) continue;
1345 const char *knm = ip->name->c_str();
1347 fprintf(sp,"int %sLoc::ikey_%s::\n", tnm, knm);
1348 fprintf(sp,"icmpr(char *a, char *b)\n");
1350 fprintf(sp," ikey_%s *kp = (ikey_%s *)a;\n", knm, knm);
1351 (ip->is_dir>0 ? dir_icmpr : ind_icmpr)(sp, tp, ip);
1352 fprintf(sp," return 0;\n");
1354 fprintf(sp,"int %sLoc::rkey_%s::\n", tnm, knm);
1355 fprintf(sp,"rcmpr(char *a, char *b)\n");
1357 fprintf(sp," rkey_%s *kp = (rkey_%s *)a;\n", knm, knm);
1358 fprintf(sp," %sLoc &kloc = (%sLoc&)kp->loc;\n", tnm, tnm);
1359 (ip->is_dir>0 ? dir_rcmpr : ind_rcmpr)(sp, tp, ip);
1360 fprintf(sp," return 0;\n");
1362 fprintf(sp,"int %sLoc::rkey_%s::\n", tnm, knm);
1363 fprintf(sp,"wr_key(char *bp)\n");
1365 fprintf(sp," char *cp = bp;\n");
1366 fprintf(sp," %sLoc &kloc = (%sLoc&)loc;\n", tnm, tnm);
1367 put_rkey(sp, tp, ip);
1368 fprintf(sp," return cp-bp;\n");
1372 fprintf(sp,"int %sLoc::Allocate()\n", tnm);
1374 fprintf(sp," if_err( allocate() );\n");
1375 fprintf(sp," if( !addr_wr() ) return err_(Db::errNoMemory);\n");
1378 list<dobj*>::iterator sid = tp->dop.begin();
1379 list<dobj*>::iterator eid = tp->dop.end();
1380 list<dobj*>::iterator id;
1382 for( id=sid ; !n && id!=eid; ++id ) {
1385 case dobj::ty_varchar:
1386 case dobj::ty_tinytext:
1388 case dobj::ty_mediumtext:
1389 case dobj::ty_longtext:
1390 case dobj::ty_varbinary:
1391 case dobj::ty_tinyblob:
1393 case dobj::ty_mediumblob:
1394 case dobj::ty_longblob:
1395 case dobj::ty_media:
1396 if( !n++ ) fprintf(sp," v_init();\n");
1403 for( id=sid ; id!=eid; ++id ) {
1405 const char *dnm = dp->name->c_str();
1406 if( dp->is_autoincr > 0 && dp->idx ) {
1407 const char *inm = dp->idx->name->c_str();
1408 fprintf(sp," { %s", typ_dobj(dp));
1409 fprintf(sp," (%sLoc::*fn)() = &%sLoc::%s;\n", tnm, tnm, dnm);
1410 fprintf(sp," %s", typ_dobj(dp));
1411 fprintf(sp," v = last(\"%s\",(%s", inm, typ_dobj(dp));
1412 fprintf(sp," (Db::ObjectLoc::*)())fn); %s(v+1); }\n", dnm);
1414 if( dp->has_def > 0 ) {
1415 switch( dp->has_def ) {
1416 case dobj::def_integer:
1417 fprintf(sp," %s(%d);\n", dnm, dp->def.i);
1419 case dobj::def_double:
1420 fprintf(sp," %s(%f);\n", dnm, dp->def.d);
1422 case dobj::def_string:
1424 case dobj::ty_enum: {
1425 list<string*>::iterator snm = dp->eop.begin();
1426 list<string*>::iterator enm = dp->eop.end();
1427 list<string*>::iterator nm;
1428 for( n=0,nm=snm; nm!=enm && *(*nm)!=*dp->def.s; ++nm ) ++n;
1429 fprintf(sp," %s(%d);\n", dnm, n);
1431 case dobj::ty_boolean:
1433 case dobj::ty_tinyint:
1434 case dobj::ty_smallint:
1435 case dobj::ty_decimal:
1436 case dobj::ty_mediumint:
1437 case dobj::ty_integer:
1438 case dobj::ty_bigint: {
1439 fprintf(sp," %s(%ld);\n", dnm, strtol(dp->def.s->c_str(),0,0));
1442 case dobj::ty_double:
1443 case dobj::ty_float: {
1444 fprintf(sp," %s(%f);\n", dnm, strtod(dp->def.s->c_str(),0));
1448 case dobj::ty_timestamp:
1449 case dobj::ty_binary:
1451 case dobj::ty_datetime:
1453 case dobj::ty_varchar:
1454 case dobj::ty_tinytext:
1456 case dobj::ty_mediumtext:
1457 case dobj::ty_longtext:
1458 case dobj::ty_varbinary:
1459 case dobj::ty_tinyblob:
1461 case dobj::ty_mediumblob:
1462 case dobj::ty_longblob:
1463 case dobj::ty_media: {
1464 fprintf(sp," %s((%s", dnm, typ_dobj(dp));
1465 fprintf(sp," *)\"%s\",%d);\n", dp->def.s->c_str(), (int)dp->def.s->size());
1476 fprintf(sp," return 0;\n");
1479 fprintf(sp,"int %sLoc::Construct()\n", tnm);
1481 fprintf(sp," if_err( insertProhibit() );\n");
1482 fprintf(sp," if_err( construct() );\n");
1484 for( idx=sidx; idx!=eidx; ++idx ) {
1486 if( ip->tbl != tp ) continue;
1487 const char *knm = ip->name->c_str();
1488 fprintf(sp," { rkey_%s rkey(*this);\n",knm);
1489 fprintf(sp," if_err( entity->index(\"%s\")->Insert(rkey,(void*)_id()) ); }\n", knm);
1491 fprintf(sp," if_err( insertCascade() );\n");
1492 fprintf(sp," return 0;\n");
1495 fprintf(sp,"int %sLoc::Destruct()\n", tnm);
1497 fprintf(sp," if_err( deleteProhibit() );\n");
1498 for( idx=sidx; idx!=eidx; ++idx ) {
1500 if( ip->tbl != tp ) continue;
1501 const char *knm = ip->name->c_str();
1502 fprintf(sp," { rkey_%s rkey(*this);\n",knm);
1503 fprintf(sp," if_err( entity->index(\"%s\")->Delete(rkey) ); }\n",knm);
1505 fprintf(sp," if_err( destruct() );\n");
1506 fprintf(sp," if_err( deleteCascade() );\n");
1507 fprintf(sp," return 0;\n");
1510 fprintf(sp,"void %sLoc::Deallocate()\n", tnm);
1513 for( id=sid ; !n && id!=eid; ++id ) {
1516 case dobj::ty_varchar:
1517 case dobj::ty_tinytext:
1519 case dobj::ty_mediumtext:
1520 case dobj::ty_longtext:
1521 case dobj::ty_varbinary:
1522 case dobj::ty_tinyblob:
1524 case dobj::ty_mediumblob:
1525 case dobj::ty_longblob:
1526 case dobj::ty_media:
1527 if( !n++ ) fprintf(sp," v_del();\n");
1533 fprintf(sp," deallocate();\n");
1539 fprintf(sp,"int %s::\n",tdb);
1540 fprintf(sp,"create(const char *dfn)\n");
1542 fprintf(sp," dfd = ::open(dfn,O_RDWR+O_CREAT+O_TRUNC+no_atime,0666);\n");
1543 fprintf(sp," if( dfd < 0 ) { perror(dfn); return -1; }\n");
1544 fprintf(sp," int ret = db_create();\n");
1545 fprintf(sp," close();\n");
1546 fprintf(sp," return ret;\n");
1549 fprintf(sp,"int %s::\n",tdb);
1550 fprintf(sp,"db_create()\n");
1552 fprintf(sp," if_ret( Db::make(dfd) );\n");
1553 for( it=sit ; it!=eit; ++it ) {
1555 const char *tnm = tp->name->c_str();
1556 fprintf(sp," if_ret( %s.new_entity(\"%s\", sizeof(%sObj)) );\n", tnm, tnm, tnm);
1557 for( idx=sidx; idx!=eidx; ++idx ) {
1559 if( ip->tbl != tp ) continue;
1560 const char *nm = ip->name->c_str();
1561 if( ip->is_dir > 0 )
1562 fprintf(sp," if_ret( %s.add_dir_index(\"%s\", %sLoc::key_%s::size()) );\n",
1565 fprintf(sp," if_ret( %s.add_ind_index(\"%s\") );\n", tnm, nm);
1569 fprintf(sp," if_ret( Db::commit(1) );\n");
1570 fprintf(sp," return 0;\n");
1574 fprintf(sp,"%s::\n", tdb);
1575 fprintf(sp,"%s()\n", tdb);
1576 fprintf(sp," : dfd(-1), dkey(-1), no_atime(getuid()?0:O_NOATIME), objects(0)");
1577 for( it=sit ; it!=eit; ++it ) {
1579 const char *tnm = tp->name->c_str();
1580 fprintf(sp,",\n %s(this)", tnm);
1581 fprintf(sp,", %c%s(%s)", tolower(tnm[0]), &tnm[1], tnm);
1585 for( it=sit ; it!=eit; ++it ) {
1587 const char *tnm = tp->name->c_str();
1588 fprintf(sp,"\n objects = new ObjectList(objects, %c%s);",
1589 tolower(tnm[0]), &tnm[1]);
1592 for( it=sit ; it!=eit; ++it ) {
1594 const char *tnm = tp->name->c_str();
1595 list<dobj*>::iterator sid = tp->dop.begin();
1596 list<dobj*>::iterator eid = tp->dop.end();
1597 list<dobj*>::iterator id;
1598 for( id=sid ; id!=eid; ++id ) {
1600 const char *dnm = dp->name->c_str();
1602 case dobj::ty_varchar:
1603 case dobj::ty_tinytext:
1605 case dobj::ty_mediumtext:
1606 case dobj::ty_longtext:
1607 case dobj::ty_varbinary:
1608 case dobj::ty_tinyblob:
1610 case dobj::ty_mediumblob:
1611 case dobj::ty_longblob:
1612 case dobj::ty_media: {
1613 fprintf(sp," %s.add_vref((vRef)&%sObj::v_%s);\n", tnm, tnm, dnm);
1623 fprintf(sp,"int %s::\n",tdb);
1624 fprintf(sp,"open(const char *dfn, int key)\n");
1626 fprintf(sp," dfd = ::open(dfn,O_RDWR+no_atime);\n");
1627 fprintf(sp," if( dfd < 0 ) { perror(dfn); return errNotFound; }\n");
1628 fprintf(sp," if( (dkey=key) >= 0 ) Db::use_shm(1);\n");
1629 fprintf(sp," int ret = Db::open(dfd, dkey);\n");
1630 fprintf(sp," if( !ret ) ret = db_open();\n");
1631 fprintf(sp," if( ret ) close();\n");
1632 fprintf(sp," return ret;\n");
1636 fprintf(sp,"int %s::\n",tdb);
1637 fprintf(sp,"db_open()\n");
1639 for( it=sit ; it!=eit; ++it ) {
1641 const char *tnm = tp->name->c_str();
1642 fprintf(sp," if_ret( %s.get_entity(\"%s\") );\n", tnm, tnm);
1643 for( idx=sidx; idx!=eidx; ++idx ) {
1645 if( ip->tbl != tp ) continue;
1646 const char *nm = ip->name->c_str();
1647 fprintf(sp," if_ret( %s.get_index(\"%s\") );\n", tnm, nm);
1651 fprintf(sp," if_ret( Db::start_transaction() );\n");
1652 fprintf(sp," return 0;\n");
1655 fprintf(sp,"void %s::\n",tdb);
1656 fprintf(sp,"close()\n");
1658 fprintf(sp," Db::close();\n");
1659 fprintf(sp," if( dfd >= 0 ) { ::close(dfd); dfd = -1; }\n");
1662 fprintf(sp,"int %s::\n",tdb);
1663 fprintf(sp,"access(const char *dfn, int key, int rw)\n");
1665 fprintf(sp," if( key < 0 ) return Db::errInvalid;\n");
1666 fprintf(sp," dfd = ::open(dfn,O_RDWR+no_atime);\n");
1667 fprintf(sp," if( dfd < 0 ) { perror(dfn); return Db::errNotFound; }\n");
1668 fprintf(sp," dkey = key; Db::use_shm(1);\n");
1669 fprintf(sp," int ret = Db::attach(dfd, dkey, rw);\n");
1670 fprintf(sp," if( !ret ) ret = db_access();\n");
1671 fprintf(sp," else if( ret == errNotFound ) {\n");
1672 fprintf(sp," ret = Db::open(dfd, dkey);\n");
1673 fprintf(sp," if( !ret ) ret = db_open();\n");
1674 fprintf(sp," if( !ret ) ret = Db::attach(rw);\n");
1676 fprintf(sp," if( ret ) close();\n");
1677 fprintf(sp," return ret;\n");
1680 fprintf(sp,"int %s::\n",tdb);
1681 fprintf(sp,"db_access()\n");
1683 for( it=sit ; it!=eit; ++it ) {
1685 const char *tnm = tp->name->c_str();
1686 fprintf(sp," if_ret( %s.get_entity(\"%s\") );\n", tnm, tnm);
1688 fprintf(sp," return 0;\n");
1692 printf("ended on line %d - ",cp.no);
1693 for( int i=0, n=cp.i; i<n; ++i ) printf("%c",cp.line[i]);
1695 for( int i=cp.i, n=cp.n; i<n; ++i ) printf("%c",cp.line[i]);