QStringList ModelGenerator::genUserModel(const QString &usernameField, const QString &passwordField) const { QStringList ret; QPair<QStringList, QStringList> p = createModelParams(); QString fileName = dstDir.filePath(modelName.toLower() + ".h"); QString userVar = fieldNameToVariableName(usernameField); p.first << userVar << fieldNameToVariableName(passwordField); p.first << QLatin1String(" QString ") + USER_VIRTUAL_METHOD + "() const { return " + userVar + "(); }\n"; gen(fileName, USER_MODEL_HEADER_FILE_TEMPLATE, p.first); ret << fileName; fileName = dstDir.filePath(modelName.toLower() + ".cpp"); p.second << fieldNameToVariableName(usernameField) << fieldNameToVariableName(passwordField) << fieldNameToEnumName(usernameField); gen(fileName, USER_MODEL_IMPL_TEMPLATE, p.second); ret << fileName; return ret; }
int TableSchema::lockRevisionIndex() const { for (int i = 0; i < tableFields.count(); ++i) { QSqlField f = tableFields.field(i); if (fieldNameToVariableName(f.name()) == "lockRevision") { return i; } } return -1; }
QString ModelGenerator::createParam(const QString &type, const QString &name) { QString string; QString var = fieldNameToVariableName(name); if (type == "int" || type == "float" || type == "double") { string.append(type).append(' ').append(var); } else { string += QString("const %1 &%2").arg(type, var); } return string; }
/*! Returns a map with all properties of this text format. */ QVariantMap TAbstractModel::toVariantMap() const { QVariantMap ret; QVariantMap map = mdata()->toVariantMap(); for (QMapIterator<QString, QVariant> it(map); it.hasNext(); ) { it.next(); ret.insert(fieldNameToVariableName(it.key()), it.value()); } return ret; }
/*! Sets the \a properties. */ void TAbstractModel::setProperties(const QVariantMap &properties) { // Creates a map of the original property name and the converted name QStringList soprops = mdata()->propertyNames(); QMap<QString, QString> sopropMap; for (QStringListIterator it(soprops); it.hasNext(); ) { const QString &orig = it.next(); sopropMap.insert(fieldNameToVariableName(orig), orig); } QVariantMap props; for (QMapIterator<QString, QVariant> it(properties); it.hasNext(); ) { it.next(); const QString &p = sopropMap[it.key()]; if (!p.isEmpty()) { props.insert(p, it.value()); } } mdata()->setProperties(props); }
int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); qsrand(time(NULL)); QStringList args = QCoreApplication::arguments(); int subcmd = subCommands()->value(args.value(1), Invalid); switch (subcmd) { case Invalid: qCritical("invalid argument"); return 1; break; case Help: usage(); break; case New: // Creates new project if (!createNewApplication(args.value(2))) { return 1; } break; case ShowDrivers: printf("Available database drivers for Qt:\n"); for (QStringListIterator i(TableSchema::databaseDrivers()); i.hasNext(); ) { printf(" %s\n", qPrintable(i.next())); } break; case ShowDriverPath: { QString path = QLibraryInfo::location(QLibraryInfo::PluginsPath) + QDir::separator() + "sqldrivers"; QFileInfo fi(path); if (!fi.exists() || !fi.isDir()) { qCritical("Error: database driver's directory not found"); return 1; } printf("%s\n", qPrintable(fi.canonicalFilePath())); break; } case ShowTables: if (checkIniFile()) { QStringList tables = TableSchema::tables(); if (!tables.isEmpty()) { printf("-----------------\nAvailable tables:\n"); for (QStringListIterator i(tables); i.hasNext(); ) { printf(" %s\n", qPrintable(i.next())); } putchar('\n'); } } else { return 2; } break; case ShowCollections: if (checkIniFile()) { // MongoDB settings QString mongoini = appSettings.value("MongoDbSettingsFile").toString().trimmed(); QString mnginipath = QLatin1String("config") + QDir::separator() + mongoini; if (mongoini.isEmpty() || !QFile(mnginipath).exists()) { qCritical("MongoDB settings file not found"); return 2; } MongoCommand mongo(mnginipath); if (!mongo.open("dev")) { return 2; } QStringList colls = mongo.getCollectionNames(); printf("-----------------\nExisting collections:\n"); for (auto &col : colls) { printf(" %s\n", qPrintable(col)); } putchar('\n'); } break; default: { if (argc < 3) { qCritical("invalid argument"); return 1; } if (!checkIniFile()) { return 2; } // Sets codec QTextCodec *codec = QTextCodec::codecForName(appSettings.value("InternalEncoding").toByteArray().trimmed()); codec = (codec) ? codec : QTextCodec::codecForLocale(); QTextCodec::setCodecForLocale(codec); #if QT_VERSION < 0x050000 QTextCodec::setCodecForTr(codec); QTextCodec::setCodecForCStrings(codec); #endif // ERB or Otama templateSystem = devSettings.value("TemplateSystem").toString().toLower(); if (templateSystem.isEmpty()) { templateSystem = appSettings.value("TemplateSystem", "Erb").toString().toLower(); } switch (subcmd) { case Controller: { QString ctrl = args.value(2); ControllerGenerator crtlgen(ctrl, args.mid(3)); crtlgen.generate(D_CTRLS); // Create view directory QDir dir(D_VIEWS + ((ctrl.contains('_')) ? ctrl.toLower() : fieldNameToVariableName(ctrl).toLower())); mkpath(dir, "."); copy(dataDirPath + ".trim_mode", dir); break; } case Model: { ModelGenerator modelgen(ModelGenerator::Sql, args.value(3), args.value(2)); modelgen.generate(D_MODELS); break; } case Helper: { HelperGenerator helpergen(args.value(2)); helpergen.generate(D_HELPERS); break; } case UserModel: { ModelGenerator modelgen(ModelGenerator::Sql, args.value(5), args.value(2), args.mid(3, 2)); modelgen.generate(D_MODELS, true); break; } case SqlObject: { SqlObjGenerator sqlgen(args.value(3), args.value(2)); QString path = sqlgen.generate(D_MODELS); // Generates a project file ProjectFileGenerator progen(D_MODELS + "models.pro"); progen.add(QStringList(path)); break; } case MongoScaffold: { ModelGenerator modelgen(ModelGenerator::Mongo, args.value(2)); bool success = modelgen.generate(D_MODELS); ControllerGenerator crtlgen(modelgen.model(), modelgen.fieldList(), modelgen.primaryKeyIndex(), modelgen.lockRevisionIndex()); success &= crtlgen.generate(D_CTRLS); // Generates view files of the specified template system if (templateSystem == "otama") { OtamaGenerator viewgen(modelgen.model(), modelgen.fieldList(), modelgen.primaryKeyIndex(), modelgen.autoValueIndex()); viewgen.generate(D_VIEWS); } else if (templateSystem == "erb") { ErbGenerator viewgen(modelgen.model(), modelgen.fieldList(), modelgen.primaryKeyIndex(), modelgen.autoValueIndex()); viewgen.generate(D_VIEWS); } else { qCritical("Invalid template system specified: %s", qPrintable(templateSystem)); return 2; } if (success) { printSuccessMessage(modelgen.model()); } break; } case MongoModel: { ModelGenerator modelgen(ModelGenerator::Mongo, args.value(2)); modelgen.generate(D_MODELS); break; } case WebSocketEndpoint: { const QString appendpointfiles[] = { L("controllers") + SEP + "applicationendpoint.h", L("controllers") + SEP + "applicationendpoint.cpp" }; ProjectFileGenerator progen(D_CTRLS + "controllers.pro"); for (auto &dst : appendpointfiles) { if (!QFile::exists(dst)) { QString filename = QFileInfo(dst).fileName(); copy(dataDirPath + filename, dst); progen.add(QStringList(filename)); } } WebSocketGenerator wsgen(args.value(2)); wsgen.generate(D_CTRLS); break; } case Validator: { ValidatorGenerator validgen(args.value(2)); validgen.generate(D_HELPERS); break; } case Mailer: { MailerGenerator mailgen(args.value(2), args.mid(3)); mailgen.generate(D_CTRLS); copy(dataDirPath + "mail.erb", D_VIEWS + "mailer" + SEP +"mail.erb"); break; } case Scaffold: { ModelGenerator modelgen(ModelGenerator::Sql, args.value(3), args.value(2)); bool success = modelgen.generate(D_MODELS); if (!success) return 2; int pkidx = modelgen.primaryKeyIndex(); if (pkidx < 0) { qWarning("Primary key not found. [table name: %s]", qPrintable(args.value(2))); return 2; } ControllerGenerator crtlgen(modelgen.model(), modelgen.fieldList(), pkidx, modelgen.lockRevisionIndex()); success &= crtlgen.generate(D_CTRLS); // Generates view files of the specified template system if (templateSystem == "otama") { OtamaGenerator viewgen(modelgen.model(), modelgen.fieldList(), pkidx, modelgen.autoValueIndex()); viewgen.generate(D_VIEWS); } else if (templateSystem == "erb") { ErbGenerator viewgen(modelgen.model(), modelgen.fieldList(), pkidx, modelgen.autoValueIndex()); viewgen.generate(D_VIEWS); } else { qCritical("Invalid template system specified: %s", qPrintable(templateSystem)); return 2; } if (success) { printSuccessMessage(modelgen.model()); } break; } case Delete: { // Removes files int ret = deleteScaffold(args.value(2)); if (ret) { return ret; } break; } default: qCritical("internal error"); return 1; } break; } } return 0; }
QStringList OtamaGenerator::generateViews(const QString &dstDir) const { QStringList files; if (primaryKeyIndex < 0) { qWarning("Primary key not found. [view name: %s]", qPrintable(viewName)); return files; } QDir dir(dstDir); FileWriter fw; QString output; QString caption = enumNameToCaption(viewName); QString varName = enumNameToVariableName(viewName); const QPair<QString, QVariant::Type> &pkFld = fieldList[primaryKeyIndex]; // Generates index.html QString th ,td, indexOtm, showColumn, showOtm, entryColumn, editColumn, entryOtm, editOtm; for (int i = 0; i < fieldList.count(); ++i) { const QPair<QString, QVariant::Type> &p = fieldList[i]; QString cap = fieldNameToCaption(p.first); QString var = fieldNameToVariableName(p.first); QString mrk = p.first.toLower(); QString readonly; if (!excludedColumn.contains(var, Qt::CaseInsensitive)) { th += " <th>"; th += cap; th += "</th>\n"; td += " <td data-tf=\"@"; td += mrk; td += "\"></td>\n"; indexOtm += QString("@%1 ~= i.%2()\n\n").arg(mrk, var); if (i != autoValueIndex) { // case of not auto-value field entryColumn += QString(" <p>\n <label>%1<br /><input data-tf=\"@%2\" /></label>\n </p>\n").arg(cap, mrk); entryOtm += QString("@%1 |== inputTextTag(\"%2[%3]\", %2[\"%3\"].toString())\n\n").arg(mrk, varName, var); } editColumn += QString(" <p>\n <label>%1<br /><input data-tf=\"@%2\" /></label>\n </p>\n").arg(cap, mrk); if (p.first == pkFld.first) { readonly = QLatin1String(", a(\"readonly\", \"readonly\")"); } editOtm += QString("@%1 |== inputTextTag(\"%2[%3]\", %2[\"%3\"].toString()%4);\n\n").arg(mrk, varName, var, readonly); } showColumn += QString("<dt>%1</dt><dd data-tf=\"@%2\">(%3)</dd><br />\n").arg(cap, mrk, var); showOtm += QString("@%1 ~= %2.%3()\n\n").arg(mrk, varName, var); } output = QString(INDEX_HTML_TEMPLATE).arg(caption, th, td); fw.setFilePath(dir.filePath("index.html")); if (fw.write(output, false)) { files << fw.fileName(); } // Generates index.otm QString pkVarName = fieldNameToVariableName(pkFld.first); output = QString(INDEX_OTM_TEMPLATE).arg(varName.toLower(), viewName, varName, indexOtm, pkVarName); fw.setFilePath(dir.filePath("index.otm")); if (fw.write(output, false)) { files << fw.fileName(); } // Generates show.html output = QString(SHOW_HTML_TEMPLATE).arg(caption, showColumn); fw.setFilePath(dir.filePath("show.html")); if (fw.write(output, false)) { files << fw.fileName(); } // Generates show.otm output = QString(SHOW_OTM_TEMPLATE).arg(varName.toLower(), viewName, varName, showOtm, pkVarName); fw.setFilePath(dir.filePath("show.otm")); if (fw.write(output, false)) { files << fw.fileName(); } // Generates entry.html output = QString(ENTRY_HTML_TEMPLATE).arg(caption, entryColumn); fw.setFilePath(dir.filePath("entry.html")); if (fw.write(output, false)) { files << fw.fileName(); } // Generates entry.otm output = QString(ENTRY_OTM_TEMPLATE).arg(varName.toLower(), varName, entryOtm); fw.setFilePath(dir.filePath("entry.otm")); if (fw.write(output, false)) { files << fw.fileName(); } // Generates edit.html output = QString(EDIT_HTML_TEMPLATE).arg(caption, editColumn); fw.setFilePath(dir.filePath("edit.html")); if (fw.write(output, false)) { files << fw.fileName(); } // Generates edit.otm output = QString(EDIT_OTM_TEMPLATE).arg(varName.toLower(), varName, pkVarName, editOtm); fw.setFilePath(dir.filePath("edit.otm")); if (fw.write(output, false)) { files << fw.fileName(); } return files; }
bool ControllerGenerator::generate(const QString &dstDir) const { // Reserved word check if (ngCtlrName()->contains(tableName.toLower())) { qCritical("Reserved word error. Please use another word. Controller name: %s", qPrintable(tableName)); return false; } QDir dir(dstDir); QStringList files; FileWriter fwh(dir.filePath(controllerName.toLower() + "controller.h")); FileWriter fws(dir.filePath(controllerName.toLower() + "controller.cpp")); if (actionList.isEmpty()) { if (fieldList.isEmpty()) { qCritical("Incorrect parameters."); return false; } QPair<QString, QVariant::Type> pair; if (primaryKeyIndex >= 0) pair = fieldList[primaryKeyIndex]; // Generates a controller source code QString sessInsertStr; QString sessGetStr; QString revStr; QString varName = enumNameToVariableName(controllerName); // Generates a controller header file QString code = QString(CONTROLLER_HEADER_FILE_TEMPLATE).arg(controllerName.toUpper(), controllerName, fieldNameToVariableName(pair.first)); fwh.write(code, false); files << fwh.fileName(); if (lockRevIndex >= 0) { sessInsertStr = QString(" session().insert(\"%1_lockRevision\", model.lockRevision());\n").arg(varName); sessGetStr = QString(" int rev = session().value(\"%1_lockRevision\").toInt();\n").arg(varName); revStr = QLatin1String(", rev"); } code = QString(CONTROLLER_SOURCE_FILE_TEMPLATE).arg(controllerName.toLower(), controllerName, varName, convMethod()->value(pair.second).arg(fieldNameToVariableName(pair.first)), sessInsertStr, sessGetStr, revStr, fieldNameToVariableName(pair.first)); fws.write(code, false); files << fws.fileName(); } else { // Generates a controller header file QString actions; for (QStringListIterator i(actionList); i.hasNext(); ) { actions.append(" void ").append(i.next()).append("();\n"); } QString code = QString(CONTROLLER_TINY_HEADER_FILE_TEMPLATE).arg(controllerName.toUpper(), controllerName, actions); fwh.write(code, false); files << fwh.fileName(); // Generates a controller source code QString actimpl; for (QStringListIterator i(actionList); i.hasNext(); ) { actimpl.append("void ").append(controllerName).append("Controller::").append(i.next()).append("()\n{\n // write code\n}\n\n"); } code = QString(CONTROLLER_TINY_SOURCE_FILE_TEMPLATE).arg(controllerName.toLower(), controllerName, actimpl); fws.write(code, false); files << fws.fileName(); } // Generates a project file ProjectFileGenerator progen(dir.filePath("controllers.pro")); return progen.add(files); }
QPair<QStringList, QStringList> ModelGenerator::createModelParams() const { QString setgetDecl; QString setgetImpl; QString crtparams; QString getOptDecl; QString getOptImpl; QString initParams; QList<QPair<QString, QString> > writableFields; bool optlockMethod = false; TableSchema ts(tableName); QList<QPair<QString, QString> > fieldList = ts.getFieldList(); QString autoFieldName = ts.autoValueFieldName(); for (QListIterator<QPair<QString, QString> > it(fieldList); it.hasNext(); ) { const QPair<QString, QString> &p = it.next(); QString var = fieldNameToVariableName(p.first); // Getter method setgetDecl += QString(" %1 %2() const;\n").arg(p.second, var); setgetImpl += QString("%1 %2::%3() const\n{\n return d->%4;\n}\n\n").arg(p.second, modelName, var, p.first); if (!excludedSetter()->contains(p.first, Qt::CaseInsensitive) && p.first != autoFieldName) { // Setter method QString str = fieldNameToEnumName(p.first); setgetDecl += QString(" void set%1(%2);\n").arg(str, createParam(p.second, p.first)); setgetImpl += QString("void %1::set%2(%3)\n{\n d->%4 = %5;\n}\n\n").arg(modelName, str, createParam(p.second, p.first), p.first, var); // Appends to crtparams-string crtparams += createParam(p.second, p.first); crtparams += ", "; writableFields << QPair<QString, QString>(p.first, p.second); if (p.second == "int" || p.second == "float" || p.second == "double") { initParams += QString("\n d->") + p.first + " = 0;"; } } if (p.first == LOCK_REVISION_FIELD) optlockMethod = true; } crtparams.chop(2); initParams += (initParams.isEmpty()) ? ' ' : '\n'; // Creates parameters of get() method int idx = ts.primaryKeyIndex(); QString getparams; if (idx < 0) { getparams = crtparams; } else { const QPair<QString, QString> &pair = fieldList[idx]; getparams = createParam(pair.second, pair.first); } // Creates a declaration and a implementation of 'get' method for optimistic lock if (idx >= 0 &&optlockMethod) { const QPair<QString, QString> &pair = fieldList[idx]; getOptDecl = QString(" static %1 get(%2, int lockRevision);\n").arg(modelName, createParam(pair.second, pair.first)); getOptImpl = QString("%1 %1::get(%2, int lockRevision)\n" \ "{\n" \ " TSqlORMapper<%1Object> mapper;\n" \ " TCriteria cri;\n" \ " cri.add(%1Object::%3, %4);\n" \ " cri.add(%1Object::LockRevision, lockRevision);\n" \ " return %1(mapper.findFirst(cri));\n" \ "}\n\n").arg(modelName, createParam(pair.second, pair.first), fieldNameToEnumName(pair.first), fieldNameToVariableName(pair.first)); } QStringList headerArgs; headerArgs << modelName.toUpper() << modelName << setgetDecl << crtparams << getparams << getOptDecl; // Creates a model implementation QString createImpl; createImpl += QString(" %1Object obj;\n").arg(modelName); QListIterator<QPair<QString, QString> > fi(writableFields); while (fi.hasNext()) { const QPair<QString, QString> &p = fi.next(); createImpl += QString(" obj.%1 = %2;\n").arg(p.first, fieldNameToVariableName(p.first)); } createImpl += " if (!obj.create()) {\n"; createImpl += " obj.clear();\n"; createImpl += " }\n"; createImpl += QString(" return %1(obj);\n").arg(modelName); // Creates a implementation of get() method QString getImpl; if (idx < 0) { // If no primary index exists getImpl += QString(" TCriteria cri;\n"); fi.toFront(); while (fi.hasNext()) { const QPair<QString, QString> &p = fi.next(); getImpl += QString(" cri.add(%1Object::%2, %3);\n").arg(modelName, fieldNameToEnumName(p.first), fieldNameToVariableName(p.first)); } } getImpl += QString(" TSqlORMapper<%1Object> mapper;\n").arg(modelName); getImpl += QString(" return %1(mapper.").arg(modelName); if (idx < 0) { getImpl += "findFirst(cri));\n"; } else { const QPair<QString, QString> &pair = fieldList[idx]; getImpl += QString("findByPrimaryKey(%1));\n").arg(fieldNameToVariableName(pair.first)); } QStringList implArgs; implArgs << modelName.toLower() << modelName << initParams << setgetImpl << crtparams << createImpl << getparams << getImpl << getOptImpl; return QPair<QStringList, QStringList>(headerArgs, implArgs); }
QStringList ViewGenerator::generateViews() const { QStringList files; TableSchema ts(tableName); if (ts.primaryKeyIndex() < 0) { qWarning("Primary key not found. [table name: %s]", qPrintable(ts.tableName())); return files; } FileWriter fw; QString output; QString caption = fieldNameToCaption(tableName); QString className = fieldNameToEnumName(tableName); QString varName = fieldNameToVariableName(tableName); QPair<QString, QString> pkFld = ts.getPrimaryKeyField(); // Generates index.html QString th ,td, indexOtm, showColumn, showOtm, entryColumn, editColumn, editOtm; QList<QPair<QString, QString> > fields = ts.getFieldList(); for (QListIterator<QPair<QString, QString> > i(fields); i.hasNext(); ) { const QPair<QString, QString> &p = i.next(); QString cap = fieldNameToCaption(p.first); QString var = fieldNameToVariableName(p.first); QString readonly; if (!excludedColumn()->contains(p.first)) { th += " <th>"; th += cap; th += "</th>\n"; td += " <td data-tf=\"#"; td += var; td += "\"></td>\n"; indexOtm += QString("#%1 ~= i.%1()\n\n").arg(var); entryColumn += QString(" <p>\n <label for=\"%1_%2\">%3</label><br />\n <input id=\"%1_%2\" name=\"%1[%2]\" />\n </p>\n").arg(varName, var, cap); if (p.first == pkFld.first) { readonly = QLatin1String("readonly "); } editColumn += QString(" <p>\n <label for=\"%1_%2\">%3</label><br />\n <input id=\"%1_%2\" %4data-tf=\"#%2\" />\n </p>\n").arg(varName, var, cap, readonly); editOtm += QString("#%1 |== inputTextTag(\"%2[%1]\", %2.%1());\n\n").arg(var, varName); } showColumn += QString("<p>\n <b>%1:</b>\n <span data-tf=\"#%2\">(%2)</span>\n</p>\n").arg(cap, var); showOtm += QString("#%1 := %2.%1()\n\n").arg(var, varName); } output = QString(INDEX_HTML_TEMPLATE).arg(caption, th, td); fw.setFileName(dstDir.filePath("index.html")); if (fw.write(output, false)) { files << fw.fileName(); } // Generates index.otm QString pkVarName = fieldNameToVariableName(pkFld.first); output = QString(INDEX_OTM_TEMPLATE).arg(varName.toLower(), className, varName, indexOtm, pkVarName); fw.setFileName(dstDir.filePath("index.otm")); if (fw.write(output, false)) { files << fw.fileName(); } // Generates show.html output = QString(SHOW_HTML_TEMPLATE).arg(showColumn); fw.setFileName(dstDir.filePath("show.html")); if (fw.write(output, false)) { files << fw.fileName(); } // Generates show.otm output = QString(SHOW_OTM_TEMPLATE).arg(varName.toLower(), className, varName, showOtm, pkVarName); fw.setFileName(dstDir.filePath("show.otm")); if (fw.write(output, false)) { files << fw.fileName(); } // Generates entry.html output = QString(ENTRY_HTML_TEMPLATE).arg(caption, entryColumn); fw.setFileName(dstDir.filePath("entry.html")); if (fw.write(output, false)) { files << fw.fileName(); } // Generates entry.otm output = QString(ENTRY_OTM_TEMPLATE).arg(varName.toLower()); fw.setFileName(dstDir.filePath("entry.otm")); if (fw.write(output, false)) { files << fw.fileName(); } // Generates edit.html output = QString(EDIT_HTML_TEMPLATE).arg(caption, editColumn); fw.setFileName(dstDir.filePath("edit.html")); if (fw.write(output, false)) { files << fw.fileName(); } // Generates edit.otm output = QString(EDIT_OTM_TEMPLATE).arg(varName.toLower(), className, varName, pkVarName, editOtm); fw.setFileName(dstDir.filePath("edit.otm")); if (fw.write(output, false)) { files << fw.fileName(); } return files; }
ViewGenerator::ViewGenerator(const QString &view, const QString &dst) { tableName = (view.contains('_')) ? view.toLower() : variableNameToFieldName(view); dstDir.setPath(dst + QDir::separator() + fieldNameToVariableName(tableName).toLower()); }