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")))))))))));
274 ifDBStmt.compound.statements->Add(compound = MkCompoundStmt(null, tableStatements));
275 compound.compound.context = Context { parent = ifDBStmt.compound.context };
277 ifDBStmt.compound.statements->Add(MkIfStmt(MkListOne(MkExpIdentifier(MkIdentifier("createNow"))),
278 (compound = MkCompoundStmt(null, addFieldStatements), compound.compound.context = Context { parent = ifDBStmt.compound.context }, compound),
279 (compound2 = MkCompoundStmt(null, findFieldStatements), compound2.compound.context = Context { parent = ifDBStmt.compound.context }, compound2)));
281 ifDBStmt.compound.statements->Add(
282 (compound = MkCompoundStmt(null, addFieldStatements), compound.compound.context = Context { parent = ifDBStmt.compound.context }, compound)
285 ifDBStmt.compound.statements->Add(compound = MkCompoundStmt(null, indexStatements));
286 compound.compound.context = Context { parent = ifDBStmt.compound.context };
288 // TODO: Don't make use of extension
289 exp.type = extensionCompoundExp;
290 exp.compound = databaseOpenStmt;
292 databaseOpenStmt.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier("db")))));
294 tableStatements = null;
298 FreeExpContents(exp);
299 Compiler_Error($"No database table defined in this module or database_open already used.\n");
307 static void ProcessStatement(Statement stmt)
312 ProcessStatement(stmt.labeled.stmt);
315 if(stmt.caseStmt.exp)
317 ProcessExpression(stmt.caseStmt.exp);
320 if(stmt.caseStmt.stmt)
322 ProcessStatement(stmt.caseStmt.stmt);
325 case badDeclarationStmt:
327 ProcessDeclaration(stmt.decl);
332 Context oldContext = curContext;
333 curContext = stmt.compound.context;
334 if(stmt.compound.declarations)
337 for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
339 ProcessDeclaration(decl);
342 if(stmt.compound.statements)
345 for(statement = stmt.compound.statements->first; statement; statement = statement.next)
347 ProcessStatement(statement);
350 curContext = oldContext;
358 for(exp = stmt.expressions->first; exp; exp = exp.next)
360 ProcessExpression(exp);
368 for(exp = stmt.ifStmt.exp->first; exp; exp = exp.next)
370 ProcessExpression(exp);
374 ProcessStatement(stmt.ifStmt.stmt);
376 if(stmt.ifStmt.elseStmt)
378 ProcessStatement(stmt.ifStmt.elseStmt);
385 for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
387 ProcessExpression(exp);
389 ProcessStatement(stmt.switchStmt.stmt);
395 if(stmt.whileStmt.exp)
397 for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
399 ProcessExpression(exp);
402 if(stmt.whileStmt.stmt)
403 ProcessStatement(stmt.whileStmt.stmt);
408 ProcessStatement(stmt.doWhile.stmt);
413 for(exp = stmt.doWhile.exp->first; exp; exp = exp.next)
415 ProcessExpression(exp);
424 if(stmt.forStmt.init)
426 ProcessStatement(stmt.forStmt.init);
429 if(stmt.forStmt.check)
431 ProcessStatement(stmt.forStmt.check);
434 if(stmt.forStmt.increment)
436 for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
438 ProcessExpression(exp);
442 if(stmt.forStmt.stmt)
443 ProcessStatement(stmt.forStmt.stmt);
457 for(exp = stmt.expressions->first; exp; exp = exp.next)
459 ProcessExpression(exp);
463 case fireWatchersStmt:
464 case stopWatchingStmt:
467 if(stmt._watch.watcher)
469 ProcessExpression(stmt._watch.watcher);
471 if(stmt._watch.object)
473 ProcessExpression(stmt._watch.object);
475 if(stmt._watch.watches)
477 for(_watch = stmt._watch.watches->first; _watch; _watch = _watch.next)
479 ProcessIdentifier(_watch);
486 PropertyWatch _watch;
487 if(stmt._watch.watcher)
489 ProcessExpression(stmt._watch.watcher);
491 if(stmt._watch.object)
493 ProcessExpression(stmt._watch.object);
495 if(stmt._watch.watches)
497 for(_watch = stmt._watch.watches->first; _watch; _watch = _watch.next)
501 ProcessStatement(_watch.compound);
510 static void ProcessInitializer(Initializer initializer)
512 switch(initializer.type)
514 case listInitializer:
518 for(init = initializer.list->first; init; init = init.next)
520 ProcessInitializer(init);
525 ProcessExpression(initializer.exp);
530 static void ProcessInitDeclarator(InitDeclarator decl)
533 ProcessInitializer(decl.initializer);
536 static void ProcessDeclaration(Declaration decl)
540 case structDeclaration:
545 for(spec = decl.specifiers->first; spec; spec = spec.next)
547 ProcessSpecifier(spec);
552 case initDeclaration:
554 // Need to loop through specifiers to look for :: completion
559 for(s = decl.specifiers->first; s; s = s.next)
565 if(decl.declarators && decl.declarators->first)
568 for(d = decl.declarators->first; d; d = d.next)
570 ProcessInitDeclarator(d);
575 case instDeclaration:
576 ProcessInstance(decl.inst);
581 static void ProcessFunction(FunctionDefinition func)
585 ProcessStatement(func.body);
589 static void ProcessMemberInit(MemberInit init)
593 ProcessInitializer(init.initializer);
597 static void ProcessInstance(Instantiation inst)
602 MemberInit memberInit;
603 for(init = inst.members->first; init; init = init.next)
605 if(init.type == dataMembersInit && init.dataMembers)
607 for(memberInit = init.dataMembers->first; memberInit; memberInit = memberInit.next)
609 ProcessMemberInit(memberInit);
613 if(init.type == methodMembersInit)
615 ProcessClassFunction(init.function);
621 static void ProcessClassFunction(ClassFunction func)
625 ProcessStatement(func.body);
629 static void ProcessProperty(PropertyDef def)
633 ProcessStatement(def.getStmt);
637 ProcessStatement(def.setStmt);
641 static void ProcessClassDef(ClassDef def)
645 case declarationClassDef:
646 ProcessDeclaration(def.decl);
648 case defaultPropertiesClassDef:
651 for(init = def.defProperties->first; init; init = init.next)
653 ProcessMemberInit(init);
657 case functionClassDef:
658 ProcessClassFunction(def.function);
660 case propertyClassDef:
663 ProcessProperty(def.propertyDef);
666 case propertyWatchClassDef:
667 if(def.propertyWatch && def.propertyWatch.compound)
669 ProcessStatement(def.propertyWatch.compound);
675 static void ProcessClass(ClassDefinition _class)
677 if(_class.definitions)
680 for(def = _class.definitions->first; def; def = def.next)
682 ProcessClassDef(def);
687 static void ProcessDBTable(DBTableDef table)
689 OldList * rowClassDefs = MkList(), * idClassDefs = null;
690 char tableName[1024];
691 char rowClassName[1024];
692 int len = strlen(table.name);
693 bool indexed = false;
695 char nameField[1024];
698 int symbolID = 0; //MAXINT; //globalContext.nextID++;
700 idClassDefs = MkList();
703 memcpy(tableName, table.name+1, len-2);
704 tableName[len-2] = 0;
705 ChangeCh(tableName, ' ', '_');
707 sprintf(tableID, "__ecereDBTable_%s", tableName);
709 sprintf(rowClassName, "Row%s", tableName);
710 ChangeCh(rowClassName, ' ', '_');
714 tableStatements = MkList();
715 indexStatements = MkList();
716 addFieldStatements = MkList();
717 // findFieldStatements = MkList();
723 external = MkExternalDeclaration(MkDeclaration(
724 MkListOne(MkSpecifierName("Table")),
725 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(tableID)), null))));
726 external.declaration.declMode = table.declMode;
727 ast->Insert(addAfter, external);
729 // tClasses = db.OpenTable("Classes", { tableRows, create });
731 tableStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(tableID)), '=', MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("db")), MkIdentifier("OpenTable")),
733 args->Add(MkExpString(table.name));
735 args->Add(MkExpInstance(MkInstantiation(null, null, MkListOne(MkMembersInitList(members)))));
736 members->Add(MkMemberInit(null, MkInitializerAssignment(MkExpIdentifier(MkIdentifier("tableRows")))));
737 members->Add(MkMemberInit(null, MkInitializerAssignment(MkExpIdentifier(MkIdentifier("create")))));
742 ClassDefinition _class;
745 OldList * inheritanceSpecs = MkList();
746 inheritanceSpecs->Add(MkSpecifier(PRIVATE));
747 inheritanceSpecs->Add(MkSpecifierName("Row"));
749 _class = MkClass(DeclClass(globalContext.nextID++, rowClassName), inheritanceSpecs, rowClassDefs);
750 PopContext(curContext);
752 def = MkClassDefDefaultProperty(MkListOne(MkMemberInitExp(MkExpIdentifier(MkIdentifier("tbl")), MkInitializerAssignment(MkExpIdentifier(MkIdentifier(tableID))))));
753 rowClassDefs->Add(def);
755 _class.symbol.idCode = symbolID;
756 _class.declMode = table.declMode;
757 external = MkExternalClass(_class);
758 ast->Insert(addAfter, external);
762 if(table.definitions)
766 for(entry = table.definitions->first; entry; entry = entry.next)
772 bool isIndex = false;
775 Specifier spec = entry.dataType.qualifiers ? (Specifier)entry.dataType.qualifiers->first : null;
777 sprintf(fieldID, "__ecereDBField_%s_%s", tableName, entry.id.string);
781 if(!nameField[0] && spec.type == nameSpecifier && (!strcmp(spec.name, "String") || !strcmp(spec.name, "eda::CIString")))
783 // strcpy(nameField, entry.name);
784 strcpy(nameField, entry.id.string);
786 if(!indexed && spec.type == nameSpecifier && !strcmp(spec.name, table.symbol.string))
788 Statement rowSet = MkCompoundStmt(MkList(), MkList());
792 numIndexes = Max(numIndexes, 1);
795 sprintf(name, "_%s", entry.id.string);
796 curContext = rowSet.compound.context = Context { parent = globalContext };
798 // Find(fieldSECid, middle, nil, value);
799 rowSet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("Find")),
801 args->Add(MkExpIdentifier(MkIdentifier(fieldID)));
802 args->Add(MkExpIdentifier(MkIdentifier("middle")));
803 args->Add(MkExpIdentifier(MkIdentifier("nil")));
804 args->Add(MkExpIdentifier(MkIdentifier("value")));
806 curContext = globalContext;
808 def = MkClassDefProperty(MkProperty(
809 CopyList(entry.dataType.qualifiers, CopySpecifier), CopyDeclarator(entry.dataType.declarator),
810 MkIdentifier(name), rowSet, null));
811 def.propertyDef.symbol.id = def.propertyDef.symbol.idCode = symbolID;
812 def.memberAccess = publicAccess;
813 rowClassDefs->Add(def);
818 Statement rowSet = MkCompoundStmt(MkList(), MkList()), rowGet = MkCompoundStmt(MkList(), MkList());
821 curContext = rowGet.compound.context = Context { parent = globalContext };
825 if(spec.type == nameSpecifier && spec.symbol && spec.symbol.registered && spec.symbol.registered.type == structClass)
827 rowGet.compound.declarations->Add(MkDeclarationInst(MkInstantiation(MkSpecifierName(spec.name), MkExpIdentifier(MkIdentifier("d")), null)));
832 rowGet.compound.declarations->Add(MkDeclaration(CopyList(entry.dataType.qualifiers, CopySpecifier),
833 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("d")), MkInitializerAssignment(exp = MkExpConstant("0"))))));
834 exp.destType = Type { kind = intType, refCount = 1 };
837 // GetData(fieldCNTid, d);
838 rowGet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("GetData")),
840 args->Add(MkExpIdentifier(MkIdentifier(fieldID)));
841 /*if(spec.type == nameSpecifier && spec.symbol && spec.symbol.registered && spec.symbol.registered.type == structClass)
842 args->Add(MkExpIdentifier(MkIdentifier("value")));
844 args->Add(MkExpIdentifier(MkIdentifier("d")));
847 if(spec.type == nameSpecifier && spec.symbol && spec.symbol.registered && spec.symbol.registered.type == structClass)
849 rowGet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier("value")), '=',
850 MkExpIdentifier(MkIdentifier("d"))))));
853 rowGet.compound.statements->Add(MkReturnStmt(MkListOne(MkExpIdentifier(MkIdentifier("d")))));
856 curContext = rowSet.compound.context = Context { parent = globalContext };
858 // SetData(fieldCNTid, value);
859 rowSet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("SetData")),
861 args->Add(MkExpIdentifier(MkIdentifier(fieldID)));
862 args->Add(MkExpIdentifier(MkIdentifier("value")));
864 curContext = globalContext;
865 def = MkClassDefProperty(MkProperty(CopyList(entry.dataType.qualifiers, CopySpecifier), entry.dataType.declarator, CopyIdentifier(entry.id), rowSet, rowGet));
866 def.propertyDef.symbol.id = def.propertyDef.symbol.idCode = symbolID;
867 def.memberAccess = publicAccess;
868 rowClassDefs->Add(def);
873 external = MkExternalDeclaration(MkDeclaration(
874 MkListOne(MkSpecifierName("Field")),
875 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(fieldID)), null))));
877 external.declaration.declMode = table.declMode;
879 // fieldCLSname = tClasses.AddField("name", class(String), 0 );
881 addFieldStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(fieldID)), '=', MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier(tableID)), MkIdentifier("FindField")),
883 args->Add(MkExpString(entry.name));
886 addFieldStatements->Add(
887 MkIfStmt(MkListOne(MkExpOp(null, '!', MkExpIdentifier(MkIdentifier(fieldID)))),
888 MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(fieldID)), '=', MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier(tableID)), MkIdentifier("AddField")),
890 args->Add(MkExpString(entry.name));
891 args->Add(MkExpClass(CopyList(entry.dataType.qualifiers, CopySpecifier), CopyDeclarator(entry.dataType.declarator)));
892 args->Add(MkExpConstant("0"));
894 // fieldCLSname = tClasses.FindField("name");
897 findFieldStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(fieldID)), '=', MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier(tableID)), MkIdentifier("FindField")),
899 args->Add(MkExpString(entry.name));
904 // indexes[0].field = fieldCLSid;
905 indexStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpMember(MkExpIndex(MkExpIdentifier(MkIdentifier("indexes")),
906 MkListOne(MkExpConstant("0"))), MkIdentifier("field")), '=', MkExpIdentifier(MkIdentifier(fieldID))))));
908 // indexes[0].order = ascending;
909 indexStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpMember(MkExpIndex(MkExpIdentifier(MkIdentifier("indexes")),
910 MkListOne(MkExpConstant("0"))), MkIdentifier("order")), '=', MkExpIdentifier(MkIdentifier("ascending"))))));
912 // tClasses.Index(1, indexes);
914 indexStatements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier(tableID)), MkIdentifier("Index")), args))));
915 args->Add(MkExpConstant("1"));
916 args->Add(MkExpIdentifier(MkIdentifier("indexes")));
927 ClassDefinition _class;
932 // table.symbol.id = table.symbol.idCode = globalContext.nextID++;
934 _class = MkClass(table.symbol, MkListOne(MkSpecifierName("Id")), idClassDefs);
935 PopContext(curContext);
936 _class.declMode = table.declMode;
937 external = MkExternalClass(_class);
938 ast->Insert(addAfter, external);
941 def = MkClassDefClassPropertyValue(MkIdentifier("table"), MkInitializerAssignment(exp = MkExpOp(null, '&', MkExpDBTable(CopyString(table.name)))));
942 ProcessExpression(exp);
943 idClassDefs->Add(def);
946 def = MkClassDefClassPropertyValue(MkIdentifier("nameField"), MkInitializerAssignment(exp = MkExpOp(null, '&', MkExpDBField(CopyString(table.name), MkIdentifier(nameField)))));
947 ProcessExpression(exp);
948 idClassDefs->Add(def);
953 if(table.definitions)
957 for(entry = table.definitions->first; entry; entry = entry.next)
965 Specifier spec = entry.dataType.qualifiers ? (Specifier)entry.dataType.qualifiers->first : null;
967 sprintf(fieldID, "__ecereDBField_%s_%s", tableName, entry.id.string);
969 if(idClassDefs && spec)
971 Statement idSet = MkCompoundStmt(MkList(), MkList()), idGet = MkCompoundStmt(MkList(), MkList());
974 curContext = idGet.compound.context = Context { parent = globalContext };
977 // RowContacts r { this };
978 idGet.compound.declarations->Add(MkDeclarationInst(MkInstantiation(MkSpecifierName(rowClassName), MkExpIdentifier(MkIdentifier("r")),
979 MkListOne(MkMembersInitList(MkListOne(MkMemberInit(null, MkInitializerAssignment(MkExpIdentifier(MkIdentifier("this"))))))))));
982 if(spec.type == nameSpecifier && spec.symbol && spec.symbol.registered && spec.symbol.registered.type == structClass)
984 idGet.compound.declarations->Add(MkDeclarationInst(MkInstantiation(MkSpecifierName(spec.name), MkExpIdentifier(MkIdentifier("d")), null)));
989 idGet.compound.declarations->Add(MkDeclaration(CopyList(entry.dataType.qualifiers, CopySpecifier),
990 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("d")), MkInitializerAssignment(exp = MkExpConstant("0"))))));
991 exp.destType = Type { kind = intType, refCount = 1 };
994 // r.GetData(fieldCNTid, d);
995 idGet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("r")), MkIdentifier("GetData")),
997 args->Add(MkExpIdentifier(MkIdentifier(fieldID)));
998 /*if(spec.type == nameSpecifier && spec.symbol && spec.symbol.registered && spec.symbol.registered.type == structClass)
999 args->Add(MkExpIdentifier(MkIdentifier("value")));
1001 args->Add(MkExpIdentifier(MkIdentifier("d")));
1004 idGet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpOp(null, DELETE, MkExpIdentifier(MkIdentifier("r"))))));
1007 if(spec.type == nameSpecifier && spec.symbol && spec.symbol.registered && spec.symbol.registered.type == structClass)
1009 idGet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier("value")), '=',
1010 MkExpIdentifier(MkIdentifier("d"))))));
1013 idGet.compound.statements->Add(MkReturnStmt(MkListOne(MkExpIdentifier(MkIdentifier("d")))));
1016 curContext = idSet.compound.context = Context { parent = globalContext };
1018 // RowContacts r { this };
1020 idSet.compound.declarations->Add(MkDeclarationInst(MkInstantiation(MkSpecifierName(rowClassName), MkExpIdentifier(MkIdentifier("r")),
1021 MkListOne(MkMembersInitList(MkListOne(MkMemberInit(null, MkInitializerAssignment(MkExpIdentifier(MkIdentifier("this"))))))))));
1023 // r.SetData(fieldCNTid, value);
1024 idSet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("r")), MkIdentifier("SetData")),
1025 args = MkList()))));
1026 args->Add(MkExpIdentifier(MkIdentifier(fieldID)));
1027 args->Add(MkExpIdentifier(MkIdentifier("value")));
1030 idSet.compound.statements->Add(MkExpressionStmt(MkListOne(MkExpOp(null, DELETE, MkExpIdentifier(MkIdentifier("r"))))));
1032 curContext = globalContext;
1034 def = MkClassDefProperty(MkProperty(
1035 CopyList(entry.dataType.qualifiers, CopySpecifier), CopyDeclarator(entry.dataType.declarator),
1036 CopyIdentifier(entry.id), idSet, idGet));
1037 def.propertyDef.symbol.id = def.propertyDef.symbol.idCode = symbolID;
1038 def.memberAccess = publicAccess;
1039 idClassDefs->Add(def);
1043 entry.dataType.qualifiers = null;
1044 entry.dataType.declarator = null;
1051 if(entry.items && entry.items->count)
1056 bool needTable = false;
1058 if(entry.id || indexed)
1060 if(entry.id || entry.items->count == 1)
1063 Identifier id = entry.id ? entry.id : ((DBIndexItem)entry.items->first).id;
1064 sprintf(indexID, "__ecereDBIndex_%s_%s", tableName, id.string);
1065 external = MkExternalDeclaration(MkDeclaration(
1066 MkListOne(MkSpecifierName("Table")),
1067 MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(indexID)), null))));
1069 external.declaration.declMode = table.declMode;
1073 Compiler_Error($"Multiple field index requires a name\n");
1078 strcpy(indexID, tableID);
1081 for(c = 0, item = entry.items->first; item; item = item.next, c++)
1084 // indexes[c].field = fieldCLSid;
1085 sprintf(num, "%d", c);
1086 sprintf(fieldID, "__ecereDBField_%s_%s", tableName, item.id.string);
1088 indexStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpMember(MkExpIndex(MkExpIdentifier(MkIdentifier("indexes")),
1089 MkListOne(MkExpConstant(num))), MkIdentifier("field")), '=', MkExpIdentifier(MkIdentifier(fieldID))))));
1090 indexStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpMember(MkExpIndex(MkExpIdentifier(MkIdentifier("indexes")),
1091 MkListOne(MkExpConstant(num))), MkIdentifier("order")), '=', MkExpIdentifier(MkIdentifier((item.order == ascending) ? "ascending" : "descending"))))));
1093 sprintf(num, "%d", c);
1094 numIndexes = Max(numIndexes, c);
1097 // index = db.OpenTable("Classes", { tableRows });
1099 indexStatements->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(indexID)), '=', MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("db")), MkIdentifier("OpenTable")),
1101 args->Add(MkExpString(table.name));
1103 args->Add(MkExpInstance(MkInstantiation(null, null, MkListOne(MkMembersInitList(members)))));
1104 members->Add(MkMemberInit(null, MkInitializerAssignment(MkExpIdentifier(MkIdentifier("tableRows")))));
1106 // tClasses.Index(1, indexes);
1108 indexStatements->Add(MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier(indexID)), MkIdentifier("Index")), args))));
1109 args->Add(MkExpConstant(num));
1110 args->Add(MkExpIdentifier(MkIdentifier("indexes")));
1119 public void ProcessDBTableDefinitions()
1124 curContext = globalContext;
1126 PrePreProcessClassDefinitions();
1128 DeclClass(0, "Field");
1129 DeclClass(0, "Table");
1130 DeclClass(0, "Row");
1135 for(external = ast->first; external; external = external.next)
1137 curExternal = external;
1138 switch(external.type)
1140 case dbtableExternal:
1141 ProcessDBTable(external.table);
1146 for(external = ast->first; external; external = external.next)
1148 curExternal = external;
1149 switch(external.type)
1151 case functionExternal:
1152 ProcessFunction(external.function);
1154 case declarationExternal:
1155 ProcessDeclaration(external.declaration);
1158 ProcessClass(external._class);
1163 curContext = globalContext;