?? litesql-gen-cpp.cpp
字號:
#include "litesql/split.hpp"#include "litesql/types.hpp"#include "litesql-gen-cpp.hpp"#include "litesql-gen-main.hpp"#include "cppgenerator.hpp"#include "xmlobjects.hpp"#include "md5.hpp"#include <ctype.h>#include <cstdio>#include <map>using namespace std;using namespace gen;using namespace litesql;string quote(string s) { return "\"" + s + "\"";}string brackets(string s) { return "(" + s + ")";}static bool validID(string s) { static char* words[] = {"asm","break","case","catch", "char","class","const","continue","default", "delete","do","double","else","enum","extern", "float","for","friend","goto","if","inline","int", "long","new","operator","private","protected", "public","register","return","short","signed", "sizeof","static","struct","switch","template", "this","throw","try","typedef","union","unsigned", "virtual","void","volatile","while", // LiteSQL specific "initValues", "insert", "addUpdates", "addIDUpdates", "getFieldTypes", "delRecord", "delRelations", "update", "del", "typeIsCorrect", "upcast", "upcastCopy" }; for (size_t i = 0; i < sizeof(words) / sizeof(words[0]); i++) if (s == words[i]) return false; return true; }static void sanityCheck(xml::Database& db, vector<xml::Object>& objects, vector<xml::Relation>& relations) { using namespace litesql; if (!validID(db.name)) throw Except("invalid id: database.name : " + db.name); for (size_t i = 0; i < objects.size(); i++) { xml::Object& o = objects[i]; if (!validID(o.name)) throw Except("invalid id: object.name : " + o.name); for (size_t i2 = 0; i2 < o.fields.size(); i2++) { xml::Field& f = o.fields[i2]; if (!validID(f.name)) throw Except("invalid id: object.field.name : " + f.name); } } for (size_t i = 0; i < relations.size(); i++) { xml::Relation& r = relations[i]; if (!validID(r.getName())) throw Except("invalid id: relation.name : " + r.getName()); for (size_t i2 = 0; i2 < r.fields.size(); i2++) { xml::Field& f = r.fields[i2]; if (!validID(f.name)) throw Except("invalid id: relation.field.name : " + f.name); } for (size_t i2 = 0; i2 < r.related.size(); i2++) { xml::Relate& rel = r.related[i2]; if (!validID(rel.handle) && !rel.handle.empty()) throw Except("invalid id: relation.relate.handle : " + rel.handle); } } }string makeTableName(string s) { if (s.size() > 31) return "_" + md5HexDigest(s); return s;}void writeStaticObjData(Class& cl, const xml::Object& o) { Variable type__("type__", "const std::string", quote(o.name)); type__.static_(); cl.variable(type__); Variable table__("table__", "const std::string", quote(makeTableName(o.getTable()))); table__.static_(); cl.variable(table__); if (!o.parentObject) { Variable sequence__("sequence__", "const std::string", quote(makeTableName(o.name + "_seq"))); sequence__.static_(); cl.variable(sequence__); }}void writeObjFields(Class & cl, const xml::Object & o) { Method init("initValues", "void"); bool hasValues = false; init.static_(); for (size_t i = 0; i < o.fields.size(); i++) { const xml::Field& fld = o.fields[i]; string data = quote(fld.name + "_") + "," + quote(fld.getSQLType()) + "," + "table__"; if (!fld.values.empty()) { data += "," + fld.name + "_values"; Variable values(fld.name + "_values", "std::vector < std::pair< std::string, std::string > >"); values.static_().protected_(); cl.variable(values); hasValues = true; init.body(fld.name + "_values.clear();"); for (size_t i2 = 0; i2 < fld.values.size(); i2++) { const xml::Value& val = fld.values[i2]; init.body(fld.name + "_values.push_back(make_pair(" + quote(val.name) + "," + quote(val.value) + "));"); } } string ftypeClass ="const litesql::FieldType"; if (!fld.values.empty()) { ftypeClass = fld.fieldTypeName + "Type"; Class ftypeCl(ftypeClass, "litesql::FieldType"); Method cons(ftypeClass); ftypeClass = o.name + "::" + ftypeClass; cons.param(Variable("n", "const std::string&")) .param(Variable("t", "const std::string&")) .param(Variable("tbl", "const std::string&")) .param(Variable("vals", "const litesql::FieldType::Values&", "Values()")) .constructor("litesql::FieldType(n,t,tbl,vals)"); ftypeCl.method(cons); for (size_t v = 0; v < fld.values.size(); v++) { const xml::Value& value = fld.values[v]; string v; if (fld.getCPPType() == "std::string") v = quote(value.value); else v = value.value; Variable val(value.name, "const " + fld.getCPPType(), v); val.static_(); ftypeCl.variable(val); } cl.class_(ftypeCl); } Variable ftype(fld.fieldTypeName, ftypeClass, data); ftype.static_(); Variable field(fld.name, "litesql::Field<" + fld.getCPPType() + ">"); cl.variable(ftype); cl.variable(field); if (fld.values.size() > 0) { Class valueHolder(xml::capitalize(fld.name)); for (size_t v = 0; v < fld.values.size(); v++) { const xml::Value& value = fld.values[v]; string v; if (fld.getCPPType() == "std::string") v = quote(value.value); else v = value.value; Variable val(value.name, "const " + fld.getCPPType(), v); val.static_(); valueHolder.variable(val); } cl.class_(valueHolder); } } if (hasValues) cl.method(init);}void writeObjConstructors(Class& cl, const xml::Object& o) { Method defaults("defaults", "void"); defaults.protected_(); bool hasDefaults = false; for (size_t i = 0; i < o.fields.size(); i++) { const xml::Field& f = o.fields[i]; if (!f.default_.empty() || !f.hasQuotedValues()) defaults.body(f.name + " = " + f.getQuotedDefaultValue() + ";"); hasDefaults = true; } Method cons1(o.name); // Object(const Database &) string consParams = o.inherits + "(db)"; string cons2Params = o.inherits + "(db, rec)"; if (o.fields.size() > 0) { Split fieldInst; for (size_t i = 0; i < o.fields.size(); i++) { const xml::Field& f = o.fields[i]; fieldInst.push_back(f.name + brackets(f.fieldTypeName)); } consParams += ", " + fieldInst.join(", "); cons2Params += ", " + fieldInst.join(", "); } cons1.param(Variable("db", "const litesql::Database&")) .constructor(consParams); if (hasDefaults) cons1.body("defaults();"); Method cons2(o.name); // Object(const Database &, const Record& row cons2.param(Variable("db", "const litesql::Database&")) .param(Variable("rec", "const litesql::Record&")) .constructor(cons2Params); if (hasDefaults) cons2.body("defaults();"); if (o.fields.size() > 0) { int last = o.getLastFieldOffset(); cons2.body("size_t size = " "(rec.size() > " + toString(last) + ")" " ? " + toString(last) + " : rec.size();") .body("switch(size) {"); for(int i = o.fields.size() - 1; i >= 0; i--) { int p = last - o.fields.size() + i; cons2.body("case " + toString(p+1) + ": " + o.fields[i].name + " = rec[" + toString(p) + "];"); } cons2.body("}"); } Method cons3(o.name); // Object(const Object& obj); string consParams3 = o.inherits + "(obj)"; if (o.fields.size() > 0) { Split fieldCopy; for (size_t i = 0; i < o.fields.size(); i++) { const xml::Field& f = o.fields[i]; fieldCopy.push_back(f.name + brackets("obj." + f.name)); } consParams3 += ", " + fieldCopy.join(", "); } cons3.param(Variable("obj", "const " + o.name + "&")) .constructor(consParams3); if (hasDefaults) cl.method(defaults); Method assign("operator=", "const " + o.name + "&"); assign.param(Variable("obj", "const " + o.name + "&")); if (o.fields.size() > 0) { assign.body("if (this != &obj) {"); for (size_t i = 0; i < o.fields.size(); i++) { const xml::Field& f = o.fields[i]; assign.body(" " + f.name + " = obj." + f.name + ";"); } assign.body("}"); } assign.body(o.inherits + "::operator=(obj);"); assign.body("return *this;"); cl.method(cons1).method(cons2).method(cons3).method(assign); }void writeObjRelationHandles(Class& cl, xml::Object& o) { for (size_t i = 0; i < o.handles.size(); i++) { xml::RelationHandle& handle = o.handles[i]; xml::Relation* rel = handle.relation; string className = xml::capitalize(handle.name) + "Handle"; Class hcl(className, "litesql::RelationHandle<" + o.name + ">"); Method cons(className); cons.param(Variable("owner", "const " + o.name + "&")). constructor("litesql::RelationHandle<" + o.name + ">(owner)"); Method link("link", "void"); Method unlink("unlink", "void"); Split params; params.push_back("owner->getDatabase()"); params.resize(1 + rel->related.size()); params[1 + handle.relate->paramPos] = "*owner"; for (size_t i2 = 0; i2 < handle.destObjects.size(); i2++) { xml::Object* dest = handle.destObjects[i2].first; xml::Relate * relate = handle.destObjects[i2].second; Variable var("o" + toString(i2), "const " + dest->name + "&"); link.param(var); unlink.param(var); params[1 + relate->paramPos] = "o" + toString(i2); } for (size_t i2 = 0; i2 < rel->fields.size(); i2++) { xml::Field& field = rel->fields[i2]; // FIXME: default-arvoiset parametrit viimeiseksi link.param(Variable(field.name, field.getCPPType(), field.getQuotedDefaultValue())); unlink.param(Variable(field.name, field.getCPPType())); params.push_back(field.name); } link.body(rel->getName() + "::link(" + params.join(", ") + ");"); unlink.body(rel->getName() + "::unlink(" + params.join(", ") + ");"); Variable exprParam("expr", "const litesql::Expr&", "litesql::Expr()"); Variable srcExprParam("srcExpr", "const litesql::Expr&", "litesql::Expr()"); Method del("del", "void"); params.clear();
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -