3 #define YYLTYPE Location
6 static OldList * tableStatements, * indexStatements, * addFieldStatements/*, * findFieldStatements*/;
8 static External addAfter;
10 static void ProcessSpecifier(Specifier spec)
21 for(def = spec.definitions->first; def; def = def.next)
23 // TODO: Should use the ProcessClassDef function here right?
25 //if(def.type == ClassDefDeclaration && def.decl && def.decl.type == DeclarationStruct)
26 // ProcessDeclaration(def.decl);
29 case declarationClassDef:
30 ProcessDeclaration(def.decl);
32 case defaultPropertiesClassDef:
35 for(init = def.defProperties->first; init; init = init.next)
37 //Class oldThisClass = thisClass;
38 ProcessMemberInit(init);
42 case functionClassDef:
43 ProcessClassFunction(def.function);
45 case propertyClassDef:
48 ProcessProperty(def.propertyDef);
51 case propertyWatchClassDef:
52 if(def.propertyWatch && def.propertyWatch.compound)
54 ProcessStatement(def.propertyWatch.compound);
57 case classPropertyValueClassDef:
59 ProcessInitializer(def.initializer);
69 static void ProcessIdentifier(Identifier id)
74 static void ProcessExpression(Expression exp)
79 ProcessExpression(exp._new.size);
82 ProcessExpression(exp._renew.exp);
83 ProcessExpression(exp._renew.size);
88 ProcessIdentifier(exp.identifier);
91 ProcessInstance(exp.instance);
98 ProcessExpression(exp.op.exp1);
102 ProcessExpression(exp.op.exp2);
107 Expression expression;
108 for(expression = exp.list->first; expression; expression = expression.next)
110 ProcessExpression(expression);
116 Expression expression;
117 ProcessExpression(exp.index.exp);
119 for(expression = exp.index.index->first; expression; expression = expression.next)
121 ProcessExpression(expression);
127 ProcessExpression(exp.call.exp);
129 if(exp.call.arguments)
131 Expression expression;
133 for(expression = exp.call.arguments->first; expression; expression = expression.next)
135 ProcessExpression(expression);
141 ProcessExpression(exp.member.exp);
144 ProcessExpression(exp.member.exp);
149 ProcessExpression(exp.cast.exp);
152 ProcessExpression(exp.cond.cond);
155 Expression expression;
156 for(expression = exp.cond.exp->first; expression; expression = expression.next)
158 ProcessExpression(expression);
161 ProcessExpression(exp.cond.elseExp);
167 char tableName[1024];
169 int len = strlen(exp.db.table);
170 memcpy(tableName, exp.db.table+1, len-2);
171 tableName[len-2] = 0;
172 ChangeCh(tableName, ' ', '_');
173 sprintf(name, "__ecereDBField_%s_%s", tableName, exp.db.id.string);
174 FreeExpContents(exp);
175 exp.type = identifierExp;
176 exp.identifier = MkIdentifier(name);
181 char tableName[1024];
183 int len = strlen(exp.db.table);
184 memcpy(tableName, exp.db.table+1, len-2);
185 tableName[len-2] = 0;
186 ChangeCh(tableName, ' ', '_');
187 sprintf(name, "__ecereDBTable_%s", tableName);
188 FreeExpContents(exp);
189 exp.type = identifierExp;
190 exp.identifier = MkIdentifier(name);
195 char tableName[1024];
197 int len = strlen(exp.db.table);
198 memcpy(tableName, exp.db.table+1, len-2);
199 tableName[len-2] = 0;
200 ChangeCh(tableName, ' ', '_');
201 sprintf(name, "__ecereDBIndex_%s_%s", tableName, exp.db.id.string);
202 FreeExpContents(exp);
203 exp.type = identifierExp;
204 exp.identifier = MkIdentifier(name);
211 Statement databaseOpenStmt = MkCompoundStmt(MkList(), MkList());
212 Statement compound/*, compound2*/;
215 char numIndexesString[16];
217 databaseOpenStmt.compound.context = Context { parent = curContext };
219 databaseOpenStmt.compound.declarations->Add(MkDeclaration(MkListOne(MkSpecifierName("Database")),
220 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("db")), null))));
222 // bool createNow = false;
223 /*databaseOpenStmt.compound.declarations->Add(MkDeclaration(MkListOne(MkSpecifierName("bool")),
224 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("createNow")), MkInitializerAssignment(MkExpIdentifier(MkIdentifier("false")))))));*/
226 // static bool initialized = false;
228 args->Add(MkSpecifier(STATIC));
229 args->Add(MkSpecifierName("bool"));
230 databaseOpenStmt.compound.declarations->Add(MkDeclaration(args,
231 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("initialized")), MkInitializerAssignment(MkExpIdentifier(MkIdentifier("false")))))));
233 // Assuming we're in a function where we can return 0 (Typically a DataBase InitSchema() or an Application constructor)
234 // if(initialized) return 0;
235 databaseOpenStmt.compound.statements->Add(MkIfStmt(MkListOne(MkExpIdentifier(MkIdentifier("initialized"))), MkReturnStmt(MkListOne(MkExpConstant("0"))), null));
237 // initialized = true;
238 databaseOpenStmt.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier("initialized")), '=', MkExpIdentifier(MkIdentifier("true"))))));
240 // db = ds.OpenDatabase("med", no);
242 args->Add(CopyExpression(exp.dbopen.name));
243 args->Add(MkExpIdentifier(MkIdentifier("no")));
244 databaseOpenStmt.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier("db")), '=',
245 MkExpCall(MkExpMember(CopyExpression(exp.dbopen.ds), MkIdentifier("OpenDatabase")), args)))));
249 db = ds.OpenDatabase("med", create);
253 databaseOpenStmt.compound.statements->Add(MkIfStmt(MkListOne(MkExpOp(null, '!', MkExpIdentifier(MkIdentifier("db")))),
254 compound = MkCompoundStmt(null, MkList()), null));
255 compound.compound.context = Context { parent = databaseOpenStmt.compound.context };
258 args->Add(exp.dbopen.name);
259 args->Add(MkExpIdentifier(MkIdentifier("create")));
260 compound.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier("db")), '=',
261 MkExpCall(MkExpMember(exp.dbopen.ds, MkIdentifier("OpenDatabase")), args)))));
262 /*compound.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier("createNow")), '=',
263 MkExpIdentifier(MkIdentifier("true")))));*/
265 exp.dbopen.name = null;
266 exp.dbopen.ds = null;
269 databaseOpenStmt.compound.statements->Add(MkIfStmt(MkListOne(MkExpIdentifier(MkIdentifier("db"))),
270 ifDBStmt = MkCompoundStmt(MkList(), MkList()), null));
272 ifDBStmt.compound.context = Context { parent = databaseOpenStmt.compound.context };
274 // FieldIndex indexes[numIndexes] = { null };
275 sprintf(numIndexesString, "%d", numIndexes);
276 ifDBStmt.compound.declarations->Add(MkDeclaration(MkListOne(MkSpecifierName("FieldIndex")), MkListOne(MkInitDeclarator(MkDeclaratorArray(MkDeclaratorIdentifier(MkIdentifier("indexes")),
277 MkExpConstant(numIndexesString)), MkInitializerList(MkListOne(MkInitializerList(MkListOne(MkInitializerAssignment(MkExpIdentifier(MkIdentifier("null")))))))))));
280 ifDBStmt.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("db")), MkIdentifier("Begin")), MkList()))));
282 ifDBStmt.compound.statements->Add(compound = MkCompoundStmt(null, tableStatements));
283 compound.compound.context = Context { parent = ifDBStmt.compound.context };
285 ifDBStmt.compound.statements->Add(MkIfStmt(MkListOne(MkExpIdentifier(MkIdentifier("createNow"))),
286 (compound = MkCompoundStmt(null, addFieldStatements), compound.compound.context = Context { parent = ifDBStmt.compound.context }, compound),
287 (compound2 = MkCompoundStmt(null, findFieldStatements), compound2.compound.context = Context { parent = ifDBStmt.compound.context }, compound2)));
289 ifDBStmt.compound.statements->Add(
290 (compound = MkCompoundStmt(null, addFieldStatements), compound.compound.context = Context { parent = ifDBStmt.compound.context }, compound)
293 ifDBStmt.compound.statements->Add(compound = MkCompoundStmt(null, indexStatements));
294 compound.compound.context = Context { parent = ifDBStmt.compound.context };
297 ifDBStmt.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("db")), MkIdentifier("Commit")), MkList()))));
299 // TODO: Don't make use of extension
300 exp.type = extensionCompoundExp;
301 exp.compound = databaseOpenStmt;
303 databaseOpenStmt.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier("db")))));
305 tableStatements = null;
309 FreeExpContents(exp);
310 Compiler_Error($"No database table defined in this module or database_open already used.\n");
318 static void ProcessStatement(Statement stmt)
323 ProcessStatement(stmt.labeled.stmt);
326 if(stmt.caseStmt.exp)
328 ProcessExpression(stmt.caseStmt.exp);
331 if(stmt.caseStmt.stmt)
333 ProcessStatement(stmt.caseStmt.stmt);
336 case badDeclarationStmt:
338 ProcessDeclaration(stmt.decl);
343 Context oldContext = curContext;
344 curContext = stmt.compound.context;
345 if(stmt.compound.declarations)
348 for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
350 ProcessDeclaration(decl);
353 if(stmt.compound.statements)
356 for(statement = stmt.compound.statements->first; statement; statement = statement.next)
358 ProcessStatement(statement);
361 curContext = oldContext;
369 for(exp = stmt.expressions->first; exp; exp = exp.next)
371 ProcessExpression(exp);
379 for(exp = stmt.ifStmt.exp->first; exp; exp = exp.next)
381 ProcessExpression(exp);
385 ProcessStatement(stmt.ifStmt.stmt);
387 if(stmt.ifStmt.elseStmt)
389 ProcessStatement(stmt.ifStmt.elseStmt);
396 for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
398 ProcessExpression(exp);
400 ProcessStatement(stmt.switchStmt.stmt);
406 if(stmt.whileStmt.exp)
408 for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
410 ProcessExpression(exp);
413 if(stmt.whileStmt.stmt)
414 ProcessStatement(stmt.whileStmt.stmt);
419 ProcessStatement(stmt.doWhile.stmt);
424 for(exp = stmt.doWhile.exp->first; exp; exp = exp.next)
426 ProcessExpression(exp);
435 if(stmt.forStmt.init)
437 ProcessStatement(stmt.forStmt.init);
440 if(stmt.forStmt.check)
442 ProcessStatement(stmt.forStmt.check);
445 if(stmt.forStmt.increment)
447 for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
449 ProcessExpression(exp);
453 if(stmt.forStmt.stmt)
454 ProcessStatement(stmt.forStmt.stmt);
468 for(exp = stmt.expressions->first; exp; exp = exp.next)
470 ProcessExpression(exp);
474 case fireWatchersStmt:
475 case stopWatchingStmt:
478 if(stmt._watch.watcher)
480 ProcessExpression(stmt._watch.watcher);
482 if(stmt._watch.object)
484 ProcessExpression(stmt._watch.object);
486 if(stmt._watch.watches)
488 for(_watch = stmt._watch.watches->first; _watch; _watch = _watch.next)
490 ProcessIdentifier(_watch);
497 PropertyWatch _watch;
498 if(stmt._watch.watcher)
500 ProcessExpression(stmt._watch.watcher);
502 if(stmt._watch.object)
504 ProcessExpression(stmt._watch.object);
506 if(stmt._watch.watches)
508 for(_watch = stmt._watch.watches->first; _watch; _watch = _watch.next)
512 ProcessStatement(_watch.compound);
521 static void ProcessInitializer(Initializer initializer)
523 switch(initializer.type)
525 case listInitializer:
529 for(init = initializer.list->first; init; init = init.next)
531 ProcessInitializer(init);
536 ProcessExpression(initializer.exp);
541 static void ProcessInitDeclarator(InitDeclarator decl)
544 ProcessInitializer(decl.initializer);
547 static void ProcessDeclaration(Declaration decl)
551 case structDeclaration:
556 for(spec = decl.specifiers->first; spec; spec = spec.next)
558 ProcessSpecifier(spec);
563 case initDeclaration:
565 // Need to loop through specifiers to look for :: completion
570 for(s = decl.specifiers->first; s; s = s.next)
576 if(decl.declarators && decl.declarators->first)
579 for(d = decl.declarators->first; d; d = d.next)
581 ProcessInitDeclarator(d);
586 case instDeclaration:
587 ProcessInstance(decl.inst);
592 static void ProcessFunction(FunctionDefinition func)
596 ProcessStatement(func.body);
600 static void ProcessMemberInit(MemberInit init)
604 ProcessInitializer(init.initializer);
608 static void ProcessInstance(Instantiation inst)
613 MemberInit memberInit;
614 for(init = inst.members->first; init; init = init.next)
616 if(init.type == dataMembersInit && init.dataMembers)
618 for(memberInit = init.dataMembers->first; memberInit; memberInit = memberInit.next)
620 ProcessMemberInit(memberInit);
624 if(init.type == methodMembersInit)
626 ProcessClassFunction(init.function);
632 static void ProcessClassFunction(ClassFunction func)
636 ProcessStatement(func.body);
640 static void ProcessProperty(PropertyDef def)
644 ProcessStatement(def.getStmt);
648 ProcessStatement(def.setStmt);
652 static void ProcessClassDef(ClassDef def)
656 case declarationClassDef:
657 ProcessDeclaration(def.decl);
659 case defaultPropertiesClassDef:
662 for(init = def.defProperties->first; init; init = init.next)
664 ProcessMemberInit(init);
668 case classPropertyValueClassDef:
670 ProcessInitializer(def.initializer);
672 case functionClassDef:
673 ProcessClassFunction(def.function);
675 case propertyClassDef:
678 ProcessProperty(def.propertyDef);
681 case propertyWatchClassDef:
682 if(def.propertyWatch && def.propertyWatch.compound)
684 ProcessStatement(def.propertyWatch.compound);
690 static void ProcessClass(ClassDefinition _class)
692 if(_class.definitions)
695 for(def = _class.definitions->first; def; def = def.next)
697 ProcessClassDef(def);
702 static void ProcessDBTable(DBTableDef table)
704 OldList * rowClassDefs = MkList(), * idClassDefs = null;
705 char tableName[1024];
706 char rowClassName[1024];
707 int len = strlen(table.name);
708 bool indexed = false;
710 char nameField[1024];
714 idClassDefs = MkList();
717 memcpy(tableName, table.name+1, len-2);
718 tableName[len-2] = 0;
719 ChangeCh(tableName, ' ', '_');
721 sprintf(tableID, "__ecereDBTable_%s", tableName);
723 sprintf(rowClassName, "Row%s", tableName);
724 ChangeCh(rowClassName, ' ', '_');
728 tableStatements = MkList();
729 indexStatements = MkList();
730 addFieldStatements = MkList();
731 // findFieldStatements = MkList();
737 external = MkExternalDeclaration(MkDeclaration(
738 MkListOne(MkSpecifierName("Table")),
739 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(tableID)), null))));
740 external.declaration.declMode = table.declMode;
741 ast->Insert(addAfter, external);
743 // tClasses = db.OpenTable("Classes", { tableRows, create });
745 tableStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(tableID)), '=', MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("db")), MkIdentifier("OpenTable")),
747 args->Add(MkExpString(table.name));
749 args->Add(MkExpInstance(MkInstantiation(null, null, MkListOne(MkMembersInitList(members)))));
750 members->Add(MkMemberInit(null, MkInitializerAssignment(MkExpIdentifier(MkIdentifier("tableRows")))));
751 members->Add(MkMemberInit(null, MkInitializerAssignment(MkExpIdentifier(MkIdentifier("create")))));
756 ClassDefinition _class;
759 OldList * inheritanceSpecs = MkList();
760 inheritanceSpecs->Add(MkSpecifier(PRIVATE));
761 inheritanceSpecs->Add(MkSpecifierName("Row"));
763 _class = MkClass(DeclClass(rowClassName), inheritanceSpecs, rowClassDefs);
764 PopContext(curContext);
766 def = MkClassDefDefaultProperty(MkListOne(MkMemberInitExp(MkExpIdentifier(MkIdentifier("tbl")), MkInitializerAssignment(MkExpIdentifier(MkIdentifier(tableID))))));
767 rowClassDefs->Add(def);
769 _class.declMode = table.declMode;
770 external = MkExternalClass(_class);
771 ast->Insert(addAfter, external);
775 if(table.definitions)
779 for(entry = table.definitions->first; entry; entry = entry.next)
785 bool isIndex = false;
788 Specifier spec = entry.dataType.qualifiers ? (Specifier)entry.dataType.qualifiers->first : null;
790 sprintf(fieldID, "__ecereDBField_%s_%s", tableName, entry.id.string);
794 if(!nameField[0] && spec.type == nameSpecifier && (!strcmp(spec.name, "String") || !strcmp(spec.name, "eda::CIString")))
796 // strcpy(nameField, entry.name);
797 strcpy(nameField, entry.id.string);
799 if(!indexed && spec.type == nameSpecifier && !strcmp(spec.name, table.symbol.string))
801 Statement rowSet = MkCompoundStmt(MkList(), MkList());
805 numIndexes = Max(numIndexes, 1);
808 sprintf(name, "_%s", entry.id.string);
809 curContext = rowSet.compound.context = Context { parent = globalContext };
811 // Find(fieldSECid, middle, nil, value);
812 rowSet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("Find")),
814 args->Add(MkExpIdentifier(MkIdentifier(fieldID)));
815 args->Add(MkExpIdentifier(MkIdentifier("middle")));
816 args->Add(MkExpIdentifier(MkIdentifier("nil")));
817 args->Add(MkExpIdentifier(MkIdentifier("value")));
819 curContext = globalContext;
821 def = MkClassDefProperty(MkProperty(
822 CopyList(entry.dataType.qualifiers, CopySpecifier), CopyDeclarator(entry.dataType.declarator),
823 MkIdentifier(name), rowSet, null));
824 def.propertyDef.isDBProp = true;
825 def.memberAccess = publicAccess;
826 rowClassDefs->Add(def);
831 Statement rowSet = MkCompoundStmt(MkList(), MkList()), rowGet = MkCompoundStmt(MkList(), MkList());
834 curContext = rowGet.compound.context = Context { parent = globalContext };
838 if(spec.type == nameSpecifier && spec.symbol && spec.symbol.registered && spec.symbol.registered.type == structClass)
840 rowGet.compound.declarations->Add(MkDeclarationInst(MkInstantiation(MkSpecifierName(spec.name), MkExpIdentifier(MkIdentifier("d")), null)));
845 rowGet.compound.declarations->Add(MkDeclaration(CopyList(entry.dataType.qualifiers, CopySpecifier),
846 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("d")), MkInitializerAssignment(exp = MkExpConstant("0"))))));
847 exp.destType = Type { kind = intType, refCount = 1 };
850 // GetData(fieldCNTid, d);
851 rowGet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("GetData")),
853 args->Add(MkExpIdentifier(MkIdentifier(fieldID)));
854 /*if(spec.type == nameSpecifier && spec.symbol && spec.symbol.registered && spec.symbol.registered.type == structClass)
855 args->Add(MkExpIdentifier(MkIdentifier("value")));
857 args->Add(MkExpIdentifier(MkIdentifier("d")));
860 if(spec.type == nameSpecifier && spec.symbol && spec.symbol.registered && spec.symbol.registered.type == structClass)
862 rowGet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier("value")), '=',
863 MkExpIdentifier(MkIdentifier("d"))))));
866 rowGet.compound.statements->Add(MkReturnStmt(MkListOne(MkExpIdentifier(MkIdentifier("d")))));
869 curContext = rowSet.compound.context = Context { parent = globalContext };
871 // SetData(fieldCNTid, value);
872 rowSet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("SetData")),
874 args->Add(MkExpIdentifier(MkIdentifier(fieldID)));
875 args->Add(MkExpIdentifier(MkIdentifier("value")));
877 curContext = globalContext;
878 def = MkClassDefProperty(MkProperty(CopyList(entry.dataType.qualifiers, CopySpecifier), entry.dataType.declarator, CopyIdentifier(entry.id), rowSet, rowGet));
879 def.propertyDef.isDBProp = true;
880 def.memberAccess = publicAccess;
881 rowClassDefs->Add(def);
886 external = MkExternalDeclaration(MkDeclaration(
887 MkListOne(MkSpecifierName("Field")),
888 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(fieldID)), null))));
890 external.declaration.declMode = table.declMode;
892 // fieldCLSname = tClasses.AddField("name", class(String), 0 );
894 addFieldStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(fieldID)), '=', MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier(tableID)), MkIdentifier("FindField")),
896 args->Add(MkExpString(entry.name));
899 addFieldStatements->Add(
900 MkIfStmt(MkListOne(MkExpOp(null, '!', MkExpIdentifier(MkIdentifier(fieldID)))),
901 MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(fieldID)), '=', MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier(tableID)), MkIdentifier("AddField")),
903 args->Add(MkExpString(entry.name));
904 args->Add(MkExpClass(CopyList(entry.dataType.qualifiers, CopySpecifier), CopyDeclarator(entry.dataType.declarator)));
905 args->Add(MkExpConstant("0"));
907 // fieldCLSname = tClasses.FindField("name");
910 findFieldStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(fieldID)), '=', MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier(tableID)), MkIdentifier("FindField")),
912 args->Add(MkExpString(entry.name));
917 // indexes[0].field = fieldCLSid;
918 indexStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpMember(MkExpIndex(MkExpIdentifier(MkIdentifier("indexes")),
919 MkListOne(MkExpConstant("0"))), MkIdentifier("field")), '=', MkExpIdentifier(MkIdentifier(fieldID))))));
921 // indexes[0].order = ascending;
922 indexStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpMember(MkExpIndex(MkExpIdentifier(MkIdentifier("indexes")),
923 MkListOne(MkExpConstant("0"))), MkIdentifier("order")), '=', MkExpIdentifier(MkIdentifier("ascending"))))));
925 // tClasses.Index(1, indexes);
927 indexStatements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier(tableID)), MkIdentifier("Index")), args))));
928 args->Add(MkExpConstant("1"));
929 args->Add(MkExpIdentifier(MkIdentifier("indexes")));
940 ClassDefinition _class;
946 _class = MkClass(table.symbol, MkListOne(MkSpecifierName("Id")), idClassDefs);
947 PopContext(curContext);
948 _class.declMode = table.declMode;
949 external = MkExternalClass(_class);
950 ast->Insert(addAfter, external);
953 def = MkClassDefClassPropertyValue(MkIdentifier("table"), MkInitializerAssignment(exp = MkExpOp(null, '&', MkExpDBTable(CopyString(table.name)))));
954 ProcessExpression(exp);
955 idClassDefs->Add(def);
958 def = MkClassDefClassPropertyValue(MkIdentifier("nameField"), MkInitializerAssignment(exp = MkExpOp(null, '&', MkExpDBField(CopyString(table.name), MkIdentifier(nameField)))));
959 ProcessExpression(exp);
960 idClassDefs->Add(def);
965 if(table.definitions)
969 for(entry = table.definitions->first; entry; entry = entry.next)
977 Specifier spec = entry.dataType.qualifiers ? (Specifier)entry.dataType.qualifiers->first : null;
979 sprintf(fieldID, "__ecereDBField_%s_%s", tableName, entry.id.string);
981 if(idClassDefs && spec)
983 Statement idSet = MkCompoundStmt(MkList(), MkList()), idGet = MkCompoundStmt(MkList(), MkList());
986 curContext = idGet.compound.context = Context { parent = globalContext };
989 // RowContacts r { this };
990 idGet.compound.declarations->Add(MkDeclarationInst(MkInstantiation(MkSpecifierName(rowClassName), MkExpIdentifier(MkIdentifier("r")),
991 MkListOne(MkMembersInitList(MkListOne(MkMemberInit(null, MkInitializerAssignment(MkExpIdentifier(MkIdentifier("this"))))))))));
994 if(spec.type == nameSpecifier && spec.symbol && spec.symbol.registered && spec.symbol.registered.type == structClass)
996 idGet.compound.declarations->Add(MkDeclarationInst(MkInstantiation(MkSpecifierName(spec.name), MkExpIdentifier(MkIdentifier("d")), null)));
1001 idGet.compound.declarations->Add(MkDeclaration(CopyList(entry.dataType.qualifiers, CopySpecifier),
1002 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("d")), MkInitializerAssignment(exp = MkExpConstant("0"))))));
1003 exp.destType = Type { kind = intType, refCount = 1 };
1006 // r.GetData(fieldCNTid, d);
1007 idGet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("r")), MkIdentifier("GetData")),
1008 args = MkList()))));
1009 args->Add(MkExpIdentifier(MkIdentifier(fieldID)));
1010 /*if(spec.type == nameSpecifier && spec.symbol && spec.symbol.registered && spec.symbol.registered.type == structClass)
1011 args->Add(MkExpIdentifier(MkIdentifier("value")));
1013 args->Add(MkExpIdentifier(MkIdentifier("d")));
1016 idGet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpOp(null, DELETE, MkExpIdentifier(MkIdentifier("r"))))));
1019 if(spec.type == nameSpecifier && spec.symbol && spec.symbol.registered && spec.symbol.registered.type == structClass)
1021 idGet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier("value")), '=',
1022 MkExpIdentifier(MkIdentifier("d"))))));
1025 idGet.compound.statements->Add(MkReturnStmt(MkListOne(MkExpIdentifier(MkIdentifier("d")))));
1028 curContext = idSet.compound.context = Context { parent = globalContext };
1030 // RowContacts r { this };
1032 idSet.compound.declarations->Add(MkDeclarationInst(MkInstantiation(MkSpecifierName(rowClassName), MkExpIdentifier(MkIdentifier("r")),
1033 MkListOne(MkMembersInitList(MkListOne(MkMemberInit(null, MkInitializerAssignment(MkExpIdentifier(MkIdentifier("this"))))))))));
1035 // r.SetData(fieldCNTid, value);
1036 idSet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("r")), MkIdentifier("SetData")),
1037 args = MkList()))));
1038 args->Add(MkExpIdentifier(MkIdentifier(fieldID)));
1039 args->Add(MkExpIdentifier(MkIdentifier("value")));
1042 idSet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpOp(null, DELETE, MkExpIdentifier(MkIdentifier("r"))))));
1044 curContext = globalContext;
1046 def = MkClassDefProperty(MkProperty(
1047 CopyList(entry.dataType.qualifiers, CopySpecifier), CopyDeclarator(entry.dataType.declarator),
1048 CopyIdentifier(entry.id), idSet, idGet));
1049 def.propertyDef.isDBProp = true;
1050 def.memberAccess = publicAccess;
1051 idClassDefs->Add(def);
1055 entry.dataType.qualifiers = null;
1056 entry.dataType.declarator = null;
1063 if(entry.items && entry.items->count)
1068 bool needTable = false;
1070 if(entry.id || indexed)
1072 if(entry.id || entry.items->count == 1)
1075 Identifier id = entry.id ? entry.id : ((DBIndexItem)entry.items->first).id;
1076 sprintf(indexID, "__ecereDBIndex_%s_%s", tableName, id.string);
1077 external = MkExternalDeclaration(MkDeclaration(
1078 MkListOne(MkSpecifierName("Table")),
1079 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(indexID)), null))));
1081 external.declaration.declMode = table.declMode;
1085 Compiler_Error($"Multiple field index requires a name\n");
1090 strcpy(indexID, tableID);
1093 for(c = 0, item = entry.items->first; item; item = item.next, c++)
1096 // indexes[c].field = fieldCLSid;
1097 sprintf(num, "%d", c);
1098 sprintf(fieldID, "__ecereDBField_%s_%s", tableName, item.id.string);
1100 indexStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpMember(MkExpIndex(MkExpIdentifier(MkIdentifier("indexes")),
1101 MkListOne(MkExpConstant(num))), MkIdentifier("field")), '=', MkExpIdentifier(MkIdentifier(fieldID))))));
1102 indexStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpMember(MkExpIndex(MkExpIdentifier(MkIdentifier("indexes")),
1103 MkListOne(MkExpConstant(num))), MkIdentifier("order")), '=', MkExpIdentifier(MkIdentifier((item.order == ascending) ? "ascending" : "descending"))))));
1105 sprintf(num, "%d", c);
1106 numIndexes = Max(numIndexes, c);
1109 // index = db.OpenTable("Classes", { tableRows });
1111 indexStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(indexID)), '=', MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("db")), MkIdentifier("OpenTable")),
1113 args->Add(MkExpString(table.name));
1115 args->Add(MkExpInstance(MkInstantiation(null, null, MkListOne(MkMembersInitList(members)))));
1116 members->Add(MkMemberInit(null, MkInitializerAssignment(MkExpIdentifier(MkIdentifier("tableRows")))));
1118 // tClasses.Index(1, indexes);
1120 indexStatements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier(indexID)), MkIdentifier("Index")), args))));
1121 args->Add(MkExpConstant(num));
1122 args->Add(MkExpIdentifier(MkIdentifier("indexes")));
1131 public void ProcessDBTableDefinitions()
1136 curContext = globalContext;
1138 PrePreProcessClassDefinitions();
1147 for(external = ast->first; external; external = external.next)
1149 curExternal = external;
1151 addAfter = external.prev;
1152 switch(external.type)
1154 case dbtableExternal:
1155 ProcessDBTable(external.table);
1160 for(external = ast->first; external; external = external.next)
1162 curExternal = external;
1164 addAfter = external.prev;
1166 switch(external.type)
1168 case functionExternal:
1169 ProcessFunction(external.function);
1171 case declarationExternal:
1172 ProcessDeclaration(external.declaration);
1175 ProcessClass(external._class);
1180 curContext = globalContext;