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);
65 static void ProcessIdentifier(Identifier id)
70 static void ProcessExpression(Expression exp)
75 ProcessExpression(exp._new.size);
78 ProcessExpression(exp._renew.exp);
79 ProcessExpression(exp._renew.size);
84 ProcessIdentifier(exp.identifier);
87 ProcessInstance(exp.instance);
94 ProcessExpression(exp.op.exp1);
98 ProcessExpression(exp.op.exp2);
103 Expression expression;
104 for(expression = exp.list->first; expression; expression = expression.next)
106 ProcessExpression(expression);
112 Expression expression;
113 ProcessExpression(exp.index.exp);
115 for(expression = exp.index.index->first; expression; expression = expression.next)
117 ProcessExpression(expression);
123 ProcessExpression(exp.call.exp);
125 if(exp.call.arguments)
127 Expression expression;
129 for(expression = exp.call.arguments->first; expression; expression = expression.next)
131 ProcessExpression(expression);
137 ProcessExpression(exp.member.exp);
140 ProcessExpression(exp.member.exp);
145 ProcessExpression(exp.cast.exp);
148 ProcessExpression(exp.cond.cond);
151 Expression expression;
152 for(expression = exp.cond.exp->first; expression; expression = expression.next)
154 ProcessExpression(expression);
157 ProcessExpression(exp.cond.elseExp);
163 char tableName[1024];
165 int len = strlen(exp.db.table);
166 memcpy(tableName, exp.db.table+1, len-2);
167 tableName[len-2] = 0;
168 ChangeCh(tableName, ' ', '_');
169 sprintf(name, "__ecereDBField_%s_%s", tableName, exp.db.id.string);
170 FreeExpContents(exp);
171 exp.type = identifierExp;
172 exp.identifier = MkIdentifier(name);
177 char tableName[1024];
179 int len = strlen(exp.db.table);
180 memcpy(tableName, exp.db.table+1, len-2);
181 tableName[len-2] = 0;
182 ChangeCh(tableName, ' ', '_');
183 sprintf(name, "__ecereDBTable_%s", tableName);
184 FreeExpContents(exp);
185 exp.type = identifierExp;
186 exp.identifier = MkIdentifier(name);
191 char tableName[1024];
193 int len = strlen(exp.db.table);
194 memcpy(tableName, exp.db.table+1, len-2);
195 tableName[len-2] = 0;
196 ChangeCh(tableName, ' ', '_');
197 sprintf(name, "__ecereDBIndex_%s_%s", tableName, exp.db.id.string);
198 FreeExpContents(exp);
199 exp.type = identifierExp;
200 exp.identifier = MkIdentifier(name);
207 Statement databaseOpenStmt = MkCompoundStmt(MkList(), MkList());
208 Statement compound, compound2;
211 char numIndexesString[16];
213 databaseOpenStmt.compound.context = Context { parent = curContext };
215 databaseOpenStmt.compound.declarations->Add(MkDeclaration(MkListOne(MkSpecifierName("Database")),
216 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("db")), null))));
218 // bool createNow = false;
219 databaseOpenStmt.compound.declarations->Add(MkDeclaration(MkListOne(MkSpecifierName("bool")),
220 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("createNow")), MkInitializerAssignment(MkExpIdentifier(MkIdentifier("false")))))));
222 // static bool initialized = false;
224 args->Add(MkSpecifier(STATIC));
225 args->Add(MkSpecifierName("bool"));
226 databaseOpenStmt.compound.declarations->Add(MkDeclaration(args,
227 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("initialized")), MkInitializerAssignment(MkExpIdentifier(MkIdentifier("false")))))));
229 // if(initialized) return;
230 databaseOpenStmt.compound.statements->Add(MkIfStmt(MkListOne(MkExpIdentifier(MkIdentifier("initialized"))), MkReturnStmt(MkListOne(MkExpIdentifier(MkIdentifier("null")))), null));
232 // initialized = true;
233 databaseOpenStmt.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier("initialized")), '=', MkExpIdentifier(MkIdentifier("true"))))));
235 // db = ds.OpenDatabase("med", no);
237 args->Add(CopyExpression(exp.dbopen.name));
238 args->Add(MkExpIdentifier(MkIdentifier("no")));
239 databaseOpenStmt.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier("db")), '=',
240 MkExpCall(MkExpMember(CopyExpression(exp.dbopen.ds), MkIdentifier("OpenDatabase")), args)))));
244 db = ds.OpenDatabase("med", create);
248 databaseOpenStmt.compound.statements->Add(MkIfStmt(MkListOne(MkExpOp(null, '!', MkExpIdentifier(MkIdentifier("db")))),
249 compound = MkCompoundStmt(null, MkList()), null));
250 compound.compound.context = Context { parent = databaseOpenStmt.compound.context };
253 args->Add(exp.dbopen.name);
254 args->Add(MkExpIdentifier(MkIdentifier("create")));
255 compound.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier("db")), '=',
256 MkExpCall(MkExpMember(exp.dbopen.ds, MkIdentifier("OpenDatabase")), args)))));
257 compound.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier("createNow")), '=',
258 MkExpIdentifier(MkIdentifier("true"))))));
260 exp.dbopen.name = null;
261 exp.dbopen.ds = null;
264 databaseOpenStmt.compound.statements->Add(MkIfStmt(MkListOne(MkExpIdentifier(MkIdentifier("db"))),
265 ifDBStmt = MkCompoundStmt(MkList(), MkList()), null));
267 ifDBStmt.compound.context = Context { parent = databaseOpenStmt.compound.context };
269 // FieldIndex indexes[numIndexes] = { null };
270 sprintf(numIndexesString, "%d", numIndexes);
271 ifDBStmt.compound.declarations->Add(MkDeclaration(MkListOne(MkSpecifierName("FieldIndex")), MkListOne(MkInitDeclarator(MkDeclaratorArray(MkDeclaratorIdentifier(MkIdentifier("indexes")),
272 MkExpConstant(numIndexesString)), MkInitializerList(MkListOne(MkInitializerList(MkListOne(MkInitializerAssignment(MkExpIdentifier(MkIdentifier("null")))))))))));
275 ifDBStmt.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("db")), MkIdentifier("Begin")), MkList()))));
277 ifDBStmt.compound.statements->Add(compound = MkCompoundStmt(null, tableStatements));
278 compound.compound.context = Context { parent = ifDBStmt.compound.context };
280 ifDBStmt.compound.statements->Add(MkIfStmt(MkListOne(MkExpIdentifier(MkIdentifier("createNow"))),
281 (compound = MkCompoundStmt(null, addFieldStatements), compound.compound.context = Context { parent = ifDBStmt.compound.context }, compound),
282 (compound2 = MkCompoundStmt(null, findFieldStatements), compound2.compound.context = Context { parent = ifDBStmt.compound.context }, compound2)));
284 ifDBStmt.compound.statements->Add(
285 (compound = MkCompoundStmt(null, addFieldStatements), compound.compound.context = Context { parent = ifDBStmt.compound.context }, compound)
288 ifDBStmt.compound.statements->Add(compound = MkCompoundStmt(null, indexStatements));
289 compound.compound.context = Context { parent = ifDBStmt.compound.context };
292 ifDBStmt.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("db")), MkIdentifier("Commit")), MkList()))));
294 // TODO: Don't make use of extension
295 exp.type = extensionCompoundExp;
296 exp.compound = databaseOpenStmt;
298 databaseOpenStmt.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier("db")))));
300 tableStatements = null;
304 FreeExpContents(exp);
305 Compiler_Error($"No database table defined in this module or database_open already used.\n");
313 static void ProcessStatement(Statement stmt)
318 ProcessStatement(stmt.labeled.stmt);
321 if(stmt.caseStmt.exp)
323 ProcessExpression(stmt.caseStmt.exp);
326 if(stmt.caseStmt.stmt)
328 ProcessStatement(stmt.caseStmt.stmt);
331 case badDeclarationStmt:
333 ProcessDeclaration(stmt.decl);
338 Context oldContext = curContext;
339 curContext = stmt.compound.context;
340 if(stmt.compound.declarations)
343 for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
345 ProcessDeclaration(decl);
348 if(stmt.compound.statements)
351 for(statement = stmt.compound.statements->first; statement; statement = statement.next)
353 ProcessStatement(statement);
356 curContext = oldContext;
364 for(exp = stmt.expressions->first; exp; exp = exp.next)
366 ProcessExpression(exp);
374 for(exp = stmt.ifStmt.exp->first; exp; exp = exp.next)
376 ProcessExpression(exp);
380 ProcessStatement(stmt.ifStmt.stmt);
382 if(stmt.ifStmt.elseStmt)
384 ProcessStatement(stmt.ifStmt.elseStmt);
391 for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
393 ProcessExpression(exp);
395 ProcessStatement(stmt.switchStmt.stmt);
401 if(stmt.whileStmt.exp)
403 for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
405 ProcessExpression(exp);
408 if(stmt.whileStmt.stmt)
409 ProcessStatement(stmt.whileStmt.stmt);
414 ProcessStatement(stmt.doWhile.stmt);
419 for(exp = stmt.doWhile.exp->first; exp; exp = exp.next)
421 ProcessExpression(exp);
430 if(stmt.forStmt.init)
432 ProcessStatement(stmt.forStmt.init);
435 if(stmt.forStmt.check)
437 ProcessStatement(stmt.forStmt.check);
440 if(stmt.forStmt.increment)
442 for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
444 ProcessExpression(exp);
448 if(stmt.forStmt.stmt)
449 ProcessStatement(stmt.forStmt.stmt);
463 for(exp = stmt.expressions->first; exp; exp = exp.next)
465 ProcessExpression(exp);
469 case fireWatchersStmt:
470 case stopWatchingStmt:
473 if(stmt._watch.watcher)
475 ProcessExpression(stmt._watch.watcher);
477 if(stmt._watch.object)
479 ProcessExpression(stmt._watch.object);
481 if(stmt._watch.watches)
483 for(_watch = stmt._watch.watches->first; _watch; _watch = _watch.next)
485 ProcessIdentifier(_watch);
492 PropertyWatch _watch;
493 if(stmt._watch.watcher)
495 ProcessExpression(stmt._watch.watcher);
497 if(stmt._watch.object)
499 ProcessExpression(stmt._watch.object);
501 if(stmt._watch.watches)
503 for(_watch = stmt._watch.watches->first; _watch; _watch = _watch.next)
507 ProcessStatement(_watch.compound);
516 static void ProcessInitializer(Initializer initializer)
518 switch(initializer.type)
520 case listInitializer:
524 for(init = initializer.list->first; init; init = init.next)
526 ProcessInitializer(init);
531 ProcessExpression(initializer.exp);
536 static void ProcessInitDeclarator(InitDeclarator decl)
539 ProcessInitializer(decl.initializer);
542 static void ProcessDeclaration(Declaration decl)
546 case structDeclaration:
551 for(spec = decl.specifiers->first; spec; spec = spec.next)
553 ProcessSpecifier(spec);
558 case initDeclaration:
560 // Need to loop through specifiers to look for :: completion
565 for(s = decl.specifiers->first; s; s = s.next)
571 if(decl.declarators && decl.declarators->first)
574 for(d = decl.declarators->first; d; d = d.next)
576 ProcessInitDeclarator(d);
581 case instDeclaration:
582 ProcessInstance(decl.inst);
587 static void ProcessFunction(FunctionDefinition func)
591 ProcessStatement(func.body);
595 static void ProcessMemberInit(MemberInit init)
599 ProcessInitializer(init.initializer);
603 static void ProcessInstance(Instantiation inst)
608 MemberInit memberInit;
609 for(init = inst.members->first; init; init = init.next)
611 if(init.type == dataMembersInit && init.dataMembers)
613 for(memberInit = init.dataMembers->first; memberInit; memberInit = memberInit.next)
615 ProcessMemberInit(memberInit);
619 if(init.type == methodMembersInit)
621 ProcessClassFunction(init.function);
627 static void ProcessClassFunction(ClassFunction func)
631 ProcessStatement(func.body);
635 static void ProcessProperty(PropertyDef def)
639 ProcessStatement(def.getStmt);
643 ProcessStatement(def.setStmt);
647 static void ProcessClassDef(ClassDef def)
651 case declarationClassDef:
652 ProcessDeclaration(def.decl);
654 case defaultPropertiesClassDef:
657 for(init = def.defProperties->first; init; init = init.next)
659 ProcessMemberInit(init);
663 case functionClassDef:
664 ProcessClassFunction(def.function);
666 case propertyClassDef:
669 ProcessProperty(def.propertyDef);
672 case propertyWatchClassDef:
673 if(def.propertyWatch && def.propertyWatch.compound)
675 ProcessStatement(def.propertyWatch.compound);
681 static void ProcessClass(ClassDefinition _class)
683 if(_class.definitions)
686 for(def = _class.definitions->first; def; def = def.next)
688 ProcessClassDef(def);
693 static int curSymbolID = 0;
695 static void ProcessDBTable(DBTableDef table)
697 OldList * rowClassDefs = MkList(), * idClassDefs = null;
698 char tableName[1024];
699 char rowClassName[1024];
700 int len = strlen(table.name);
701 bool indexed = false;
703 char nameField[1024];
706 int symbolID = curSymbolID; //MAXINT; //globalContext.nextID++;
708 idClassDefs = MkList();
711 memcpy(tableName, table.name+1, len-2);
712 tableName[len-2] = 0;
713 ChangeCh(tableName, ' ', '_');
715 sprintf(tableID, "__ecereDBTable_%s", tableName);
717 sprintf(rowClassName, "Row%s", tableName);
718 ChangeCh(rowClassName, ' ', '_');
722 tableStatements = MkList();
723 indexStatements = MkList();
724 addFieldStatements = MkList();
725 // findFieldStatements = MkList();
731 external = MkExternalDeclaration(MkDeclaration(
732 MkListOne(MkSpecifierName("Table")),
733 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(tableID)), null))));
734 external.declaration.declMode = table.declMode;
735 ast->Insert(addAfter, external);
737 // tClasses = db.OpenTable("Classes", { tableRows, create });
739 tableStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(tableID)), '=', MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("db")), MkIdentifier("OpenTable")),
741 args->Add(MkExpString(table.name));
743 args->Add(MkExpInstance(MkInstantiation(null, null, MkListOne(MkMembersInitList(members)))));
744 members->Add(MkMemberInit(null, MkInitializerAssignment(MkExpIdentifier(MkIdentifier("tableRows")))));
745 members->Add(MkMemberInit(null, MkInitializerAssignment(MkExpIdentifier(MkIdentifier("create")))));
750 ClassDefinition _class;
753 OldList * inheritanceSpecs = MkList();
754 inheritanceSpecs->Add(MkSpecifier(PRIVATE));
755 inheritanceSpecs->Add(MkSpecifierName("Row"));
757 _class = MkClass(DeclClass(globalContext.nextID++, rowClassName), inheritanceSpecs, rowClassDefs);
758 PopContext(curContext);
760 def = MkClassDefDefaultProperty(MkListOne(MkMemberInitExp(MkExpIdentifier(MkIdentifier("tbl")), MkInitializerAssignment(MkExpIdentifier(MkIdentifier(tableID))))));
761 rowClassDefs->Add(def);
763 _class.symbol.idCode = symbolID;
764 _class.declMode = table.declMode;
765 external = MkExternalClass(_class);
766 ast->Insert(addAfter, external);
770 if(table.definitions)
774 for(entry = table.definitions->first; entry; entry = entry.next)
780 bool isIndex = false;
783 Specifier spec = entry.dataType.qualifiers ? (Specifier)entry.dataType.qualifiers->first : null;
785 sprintf(fieldID, "__ecereDBField_%s_%s", tableName, entry.id.string);
789 if(!nameField[0] && spec.type == nameSpecifier && (!strcmp(spec.name, "String") || !strcmp(spec.name, "eda::CIString")))
791 // strcpy(nameField, entry.name);
792 strcpy(nameField, entry.id.string);
794 if(!indexed && spec.type == nameSpecifier && !strcmp(spec.name, table.symbol.string))
796 Statement rowSet = MkCompoundStmt(MkList(), MkList());
800 numIndexes = Max(numIndexes, 1);
803 sprintf(name, "_%s", entry.id.string);
804 curContext = rowSet.compound.context = Context { parent = globalContext };
806 // Find(fieldSECid, middle, nil, value);
807 rowSet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("Find")),
809 args->Add(MkExpIdentifier(MkIdentifier(fieldID)));
810 args->Add(MkExpIdentifier(MkIdentifier("middle")));
811 args->Add(MkExpIdentifier(MkIdentifier("nil")));
812 args->Add(MkExpIdentifier(MkIdentifier("value")));
814 curContext = globalContext;
816 def = MkClassDefProperty(MkProperty(
817 CopyList(entry.dataType.qualifiers, CopySpecifier), CopyDeclarator(entry.dataType.declarator),
818 MkIdentifier(name), rowSet, null));
819 def.propertyDef.symbol.id = def.propertyDef.symbol.idCode = symbolID;
820 def.memberAccess = publicAccess;
821 rowClassDefs->Add(def);
826 Statement rowSet = MkCompoundStmt(MkList(), MkList()), rowGet = MkCompoundStmt(MkList(), MkList());
829 curContext = rowGet.compound.context = Context { parent = globalContext };
833 if(spec.type == nameSpecifier && spec.symbol && spec.symbol.registered && spec.symbol.registered.type == structClass)
835 rowGet.compound.declarations->Add(MkDeclarationInst(MkInstantiation(MkSpecifierName(spec.name), MkExpIdentifier(MkIdentifier("d")), null)));
840 rowGet.compound.declarations->Add(MkDeclaration(CopyList(entry.dataType.qualifiers, CopySpecifier),
841 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("d")), MkInitializerAssignment(exp = MkExpConstant("0"))))));
842 exp.destType = Type { kind = intType, refCount = 1 };
845 // GetData(fieldCNTid, d);
846 rowGet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("GetData")),
848 args->Add(MkExpIdentifier(MkIdentifier(fieldID)));
849 /*if(spec.type == nameSpecifier && spec.symbol && spec.symbol.registered && spec.symbol.registered.type == structClass)
850 args->Add(MkExpIdentifier(MkIdentifier("value")));
852 args->Add(MkExpIdentifier(MkIdentifier("d")));
855 if(spec.type == nameSpecifier && spec.symbol && spec.symbol.registered && spec.symbol.registered.type == structClass)
857 rowGet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier("value")), '=',
858 MkExpIdentifier(MkIdentifier("d"))))));
861 rowGet.compound.statements->Add(MkReturnStmt(MkListOne(MkExpIdentifier(MkIdentifier("d")))));
864 curContext = rowSet.compound.context = Context { parent = globalContext };
866 // SetData(fieldCNTid, value);
867 rowSet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("SetData")),
869 args->Add(MkExpIdentifier(MkIdentifier(fieldID)));
870 args->Add(MkExpIdentifier(MkIdentifier("value")));
872 curContext = globalContext;
873 def = MkClassDefProperty(MkProperty(CopyList(entry.dataType.qualifiers, CopySpecifier), entry.dataType.declarator, CopyIdentifier(entry.id), rowSet, rowGet));
874 def.propertyDef.symbol.id = def.propertyDef.symbol.idCode = symbolID;
875 def.memberAccess = publicAccess;
876 rowClassDefs->Add(def);
881 external = MkExternalDeclaration(MkDeclaration(
882 MkListOne(MkSpecifierName("Field")),
883 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(fieldID)), null))));
885 external.declaration.declMode = table.declMode;
887 // fieldCLSname = tClasses.AddField("name", class(String), 0 );
889 addFieldStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(fieldID)), '=', MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier(tableID)), MkIdentifier("FindField")),
891 args->Add(MkExpString(entry.name));
894 addFieldStatements->Add(
895 MkIfStmt(MkListOne(MkExpOp(null, '!', MkExpIdentifier(MkIdentifier(fieldID)))),
896 MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(fieldID)), '=', MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier(tableID)), MkIdentifier("AddField")),
898 args->Add(MkExpString(entry.name));
899 args->Add(MkExpClass(CopyList(entry.dataType.qualifiers, CopySpecifier), CopyDeclarator(entry.dataType.declarator)));
900 args->Add(MkExpConstant("0"));
902 // fieldCLSname = tClasses.FindField("name");
905 findFieldStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(fieldID)), '=', MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier(tableID)), MkIdentifier("FindField")),
907 args->Add(MkExpString(entry.name));
912 // indexes[0].field = fieldCLSid;
913 indexStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpMember(MkExpIndex(MkExpIdentifier(MkIdentifier("indexes")),
914 MkListOne(MkExpConstant("0"))), MkIdentifier("field")), '=', MkExpIdentifier(MkIdentifier(fieldID))))));
916 // indexes[0].order = ascending;
917 indexStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpMember(MkExpIndex(MkExpIdentifier(MkIdentifier("indexes")),
918 MkListOne(MkExpConstant("0"))), MkIdentifier("order")), '=', MkExpIdentifier(MkIdentifier("ascending"))))));
920 // tClasses.Index(1, indexes);
922 indexStatements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier(tableID)), MkIdentifier("Index")), args))));
923 args->Add(MkExpConstant("1"));
924 args->Add(MkExpIdentifier(MkIdentifier("indexes")));
935 ClassDefinition _class;
940 // table.symbol.id = table.symbol.idCode = globalContext.nextID++;
942 _class = MkClass(table.symbol, MkListOne(MkSpecifierName("Id")), idClassDefs);
943 PopContext(curContext);
944 _class.declMode = table.declMode;
945 external = MkExternalClass(_class);
946 ast->Insert(addAfter, external);
949 def = MkClassDefClassPropertyValue(MkIdentifier("table"), MkInitializerAssignment(exp = MkExpOp(null, '&', MkExpDBTable(CopyString(table.name)))));
950 ProcessExpression(exp);
951 idClassDefs->Add(def);
954 def = MkClassDefClassPropertyValue(MkIdentifier("nameField"), MkInitializerAssignment(exp = MkExpOp(null, '&', MkExpDBField(CopyString(table.name), MkIdentifier(nameField)))));
955 ProcessExpression(exp);
956 idClassDefs->Add(def);
961 if(table.definitions)
965 for(entry = table.definitions->first; entry; entry = entry.next)
973 Specifier spec = entry.dataType.qualifiers ? (Specifier)entry.dataType.qualifiers->first : null;
975 sprintf(fieldID, "__ecereDBField_%s_%s", tableName, entry.id.string);
977 if(idClassDefs && spec)
979 Statement idSet = MkCompoundStmt(MkList(), MkList()), idGet = MkCompoundStmt(MkList(), MkList());
982 curContext = idGet.compound.context = Context { parent = globalContext };
985 // RowContacts r { this };
986 idGet.compound.declarations->Add(MkDeclarationInst(MkInstantiation(MkSpecifierName(rowClassName), MkExpIdentifier(MkIdentifier("r")),
987 MkListOne(MkMembersInitList(MkListOne(MkMemberInit(null, MkInitializerAssignment(MkExpIdentifier(MkIdentifier("this"))))))))));
990 if(spec.type == nameSpecifier && spec.symbol && spec.symbol.registered && spec.symbol.registered.type == structClass)
992 idGet.compound.declarations->Add(MkDeclarationInst(MkInstantiation(MkSpecifierName(spec.name), MkExpIdentifier(MkIdentifier("d")), null)));
997 idGet.compound.declarations->Add(MkDeclaration(CopyList(entry.dataType.qualifiers, CopySpecifier),
998 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("d")), MkInitializerAssignment(exp = MkExpConstant("0"))))));
999 exp.destType = Type { kind = intType, refCount = 1 };
1002 // r.GetData(fieldCNTid, d);
1003 idGet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("r")), MkIdentifier("GetData")),
1004 args = MkList()))));
1005 args->Add(MkExpIdentifier(MkIdentifier(fieldID)));
1006 /*if(spec.type == nameSpecifier && spec.symbol && spec.symbol.registered && spec.symbol.registered.type == structClass)
1007 args->Add(MkExpIdentifier(MkIdentifier("value")));
1009 args->Add(MkExpIdentifier(MkIdentifier("d")));
1012 idGet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpOp(null, DELETE, MkExpIdentifier(MkIdentifier("r"))))));
1015 if(spec.type == nameSpecifier && spec.symbol && spec.symbol.registered && spec.symbol.registered.type == structClass)
1017 idGet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier("value")), '=',
1018 MkExpIdentifier(MkIdentifier("d"))))));
1021 idGet.compound.statements->Add(MkReturnStmt(MkListOne(MkExpIdentifier(MkIdentifier("d")))));
1024 curContext = idSet.compound.context = Context { parent = globalContext };
1026 // RowContacts r { this };
1028 idSet.compound.declarations->Add(MkDeclarationInst(MkInstantiation(MkSpecifierName(rowClassName), MkExpIdentifier(MkIdentifier("r")),
1029 MkListOne(MkMembersInitList(MkListOne(MkMemberInit(null, MkInitializerAssignment(MkExpIdentifier(MkIdentifier("this"))))))))));
1031 // r.SetData(fieldCNTid, value);
1032 idSet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("r")), MkIdentifier("SetData")),
1033 args = MkList()))));
1034 args->Add(MkExpIdentifier(MkIdentifier(fieldID)));
1035 args->Add(MkExpIdentifier(MkIdentifier("value")));
1038 idSet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpOp(null, DELETE, MkExpIdentifier(MkIdentifier("r"))))));
1040 curContext = globalContext;
1042 def = MkClassDefProperty(MkProperty(
1043 CopyList(entry.dataType.qualifiers, CopySpecifier), CopyDeclarator(entry.dataType.declarator),
1044 CopyIdentifier(entry.id), idSet, idGet));
1045 def.propertyDef.symbol.id = def.propertyDef.symbol.idCode = symbolID;
1046 def.memberAccess = publicAccess;
1047 idClassDefs->Add(def);
1051 entry.dataType.qualifiers = null;
1052 entry.dataType.declarator = null;
1059 if(entry.items && entry.items->count)
1064 bool needTable = false;
1066 if(entry.id || indexed)
1068 if(entry.id || entry.items->count == 1)
1071 Identifier id = entry.id ? entry.id : ((DBIndexItem)entry.items->first).id;
1072 sprintf(indexID, "__ecereDBIndex_%s_%s", tableName, id.string);
1073 external = MkExternalDeclaration(MkDeclaration(
1074 MkListOne(MkSpecifierName("Table")),
1075 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(indexID)), null))));
1077 external.declaration.declMode = table.declMode;
1081 Compiler_Error($"Multiple field index requires a name\n");
1086 strcpy(indexID, tableID);
1089 for(c = 0, item = entry.items->first; item; item = item.next, c++)
1092 // indexes[c].field = fieldCLSid;
1093 sprintf(num, "%d", c);
1094 sprintf(fieldID, "__ecereDBField_%s_%s", tableName, item.id.string);
1096 indexStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpMember(MkExpIndex(MkExpIdentifier(MkIdentifier("indexes")),
1097 MkListOne(MkExpConstant(num))), MkIdentifier("field")), '=', MkExpIdentifier(MkIdentifier(fieldID))))));
1098 indexStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpMember(MkExpIndex(MkExpIdentifier(MkIdentifier("indexes")),
1099 MkListOne(MkExpConstant(num))), MkIdentifier("order")), '=', MkExpIdentifier(MkIdentifier((item.order == ascending) ? "ascending" : "descending"))))));
1101 sprintf(num, "%d", c);
1102 numIndexes = Max(numIndexes, c);
1105 // index = db.OpenTable("Classes", { tableRows });
1107 indexStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(indexID)), '=', MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("db")), MkIdentifier("OpenTable")),
1109 args->Add(MkExpString(table.name));
1111 args->Add(MkExpInstance(MkInstantiation(null, null, MkListOne(MkMembersInitList(members)))));
1112 members->Add(MkMemberInit(null, MkInitializerAssignment(MkExpIdentifier(MkIdentifier("tableRows")))));
1114 // tClasses.Index(1, indexes);
1116 indexStatements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier(indexID)), MkIdentifier("Index")), args))));
1117 args->Add(MkExpConstant(num));
1118 args->Add(MkExpIdentifier(MkIdentifier("indexes")));
1127 public void ProcessDBTableDefinitions()
1132 curContext = globalContext;
1134 PrePreProcessClassDefinitions();
1136 DeclClass(0, "Field");
1137 DeclClass(0, "Table");
1138 DeclClass(0, "Row");
1143 for(external = ast->first; external; external = external.next)
1145 curExternal = external;
1147 if(external.symbol) curSymbolID = external.symbol.idCode;
1148 addAfter = external.prev;
1149 switch(external.type)
1151 case dbtableExternal:
1152 ProcessDBTable(external.table);
1157 for(external = ast->first; external; external = external.next)
1159 curExternal = external;
1161 if(external.symbol) curSymbolID = external.symbol.idCode;
1162 addAfter = external.prev;
1164 switch(external.type)
1166 case functionExternal:
1167 ProcessFunction(external.function);
1169 case declarationExternal:
1170 ProcessDeclaration(external.declaration);
1173 ProcessClass(external._class);
1178 curContext = globalContext;