ジェネレータ
ここでは、ジェネレータコマンド tspawn の説明をします。
スケルトンを生成
なによりもまず最初は、アプリケーションのスケルトンを作成しなければなりません。blogapp という名で作ってみましょう。
コマンドラインから次のコマンドを入力します。Windows の場合は、TreeFrog Command Prompt 上で実行してください。
$ tspawn new blogapp
実行すると、アプリケーションルートディレクトリをトップとしたディレクトリツリー、設定ファイル(ini)、プロジェクトファイル(pro) などが生成されました。ディレクトリはよく見かける名のものばかりです。ディレクトリとしては次のものが生成されます。
- controllers コントローラ
- models モデル
- views ビュー
- heplers ヘルパ
- config 設定ファイル置き場
- db データベースファイル置き場(SQLite)
- lib ライブラリ
- log ログファイル置き場
- plugin プラグイン置き場
- public 静的なファイル置き場(画像やJavascript)
- script スクリプト置き場
- test テスト用
- tmp 一時ディレクトリ(アップロード直後のファイルなど)
スキャフォールドを生成
スキャフォールドとは「足場」という意味で、ここでは CRUD 操作を行える基礎的な実装のことです。スキャフォールドに含まれるものは、コントローラ、モデル、ビューのソースファイルおよびプロジェクトファイル(pro)で、これらをベースに本格的な開発を始めるのが良いでしょう。
ジェネレータコマンドでスキャフォールドを作るためには、あらかじめデータベースにテーブルを定義し、設定ファイルにそのデータベース情報を記述する必要があります。では、テーブルを定義してみましょう。
例:
> CREATE TABLE blog (id INTEGER PRIMARY KEY, title VARCHAR(20), body VARCHAR(200));
データベースとしてSQLite を使用する場合、データベースファイルはアプリケーションルートにある db ディレクトリへ作ってください。
設定ファイル(database.ini)にデータベース情報を設定します。ジェネレータコマンドは dev セクションに設定された情報を参照します。
[dev]
driverType=QMYSQL
databaseName=blogdb
hostName=
port=
userName=root
password=root
connectOptions=
設定一覧
項目 | 意味 | 備考 |
---|---|---|
driverType | ドライバ名 | 選択肢は次のとおり: - QDB2: IBM DB2 - QIBASE: Borland InterBase Driver - QMYSQL: MySQL Driver - QOCI: Oracle Call Interface Driver - QODBC: ODBC Driver - QPSQL: PostgreSQL Driver - QSQLITE: SQLite version 3 or above |
databaseName | データベース名 | SQLite の場合はファイルパスを指定します。 例: db/blogdb |
hostName | ホスト名 | 空欄の場合は localhost |
port | ポート番号 | 空欄の場合は デフォルトポート |
userName | ユーザ名 | |
password | パスワード | |
connectOptions | 接続オプション | 詳細は Qt ドキュメント参照: QSqlDatabase::setConnectOptions() |
データベースドライバが Qt SDK に組み込まれていないとデータベースへアクセスできません。もし組み込まれていなければ、FAQ を参照して組み込んでください。あるいは、ダウンロードページからデータベースドライバをダウンロードし、組み込んでください。
そうしてからジェネレータコマンドを実行すると、足場が生成されます。コマンドは必ずアプリケーションルートディレクトリで実行してください。
$ cd blogapp
$ tspawn scaffold blog
driverType: QMYSQL
databaseName: blogdb
hostName:
Database open successfully
created controllers/blogcontroller.h
created controllers/blogcontroller.cpp
:
結論: データベースにスキーマを定義し、ジェネレータコマンドで足場を作れ。
テーブル名とモデル名/コントローラ名の関係
ジェネレータが生成するクラスの名前はテーブル名に基づいて決められ、次のようなルールになります。
テーブル名 モデル名 コントローラ名 Sqlオブジェクト名
blog_entry → BlogEntry BlogEntryController BlogEntryObject
つまり、モデル名ではアンダースコアが消えて、その次の文字が大文字になります。
単語の単数形/複数形の話は全く考える必要がありません。
ジェネレータのサブコマンド
tspawn コマンドの usage です。
$ tspawn -h
usage: tspawn <subcommand> [args]
Available subcommands:
new (n) <application-name>
scaffold (s) <model-name>
controller (c) <controller-name>
model (m) <table-name>
sqlobject (o) <table-name>
サブコマンドとして controller, model, sqlobject を指定すると、それぞれ、コントローラだけ、モデル(SqlObject 含む)だけ、SqlObject だけを生成することができます。
~~ コラム ~~
TreeFrog には、DB スキーマの変更とその差分管理をするための仕組みであるマイグレーション機能がありません。次の理由であまり必要ないと思っています。
- マイグレーション機能を作ったとして、その学習コストがかかってしまう
- DB の操作は SQL でやった方が全機能を享受できる
- TreeFrog では、テーブルを変更したときに ORM オブジェクトクラスだけを再生成することができる → モデルクラスへも影響がでる場合があるので、それだけじゃ済まないが…
- SQL コマンドの差分管理はフレームワーク側でやるメリットがあまりない(と思う)
どうでしょうかね?
命名規約
TreeFrog にはファイル名やクラス名の命名規約があります。ジェネレータを使うと、以下の規約でファイルやクラスが生成されます。
コントローラの命名規約
コントローラのクラス名は、「テーブル名+Controller」となります。常に大文字で始まり、単語の区切りの’_‘(アンダースコア)を消し、その区切りの先頭文字を大文字にします。例えば、次のようなクラス名になります。
- BlogController
- EntryCommentController
これらのファイルは、controllers ディレクトリに保存されます。その際のファイル名は、クラス名を全て小文字にして、拡張子(.h と .cpp)をつけたものになります。
モデルの命名規約
モデルのクラス名は、コントローラと同様に常に大文字で始まり、単語の区切りの’_‘(アンダースコア)を消し、その区切りの先頭文字を大文字にします。例えば、次のようなクラス名になります。
- Blog
- EntryComment
これらのファイルは、models ディレクトリに保存されます。コントローラと同様に、ファイル名はモデル名を全て小文字にして、拡張子(.h と .cpp)をつけたものになります。
Rails のように単語の単数形・複数形の変換はしません。
ビューの命名規約
ビューのテンプレートは、全て小文字で「アクション名+拡張子」というファイル名で、「views/コントローラ名」 ディレクトリに生成されます。拡張子は、テンプレートシステムによって変わります。
また、ビューをビルドすると、テンプレートを C++ コードに変換し views/_src ディレクトリにソースファイルを出力します。それらをコンパイルして、ビューの共有ライブラリが作られます。
CRUD
CRUD とは、Web アプリケーションにおける主要な4つの機能のことで、「Create (生成)」 「Read (読込)」 「Update (更新)」 「Delete (削除)」の頭文字をとっています。 ジェネレータコマンドで足場を作成すると、次の命名でコードを生成します。
CRUD 対応表
アクション | モデル | ORM | SQL | |
---|---|---|---|---|
C | create | create() [static] create() |
create() | INSERT |
R | index show |
get() [static] getAll() [static] |
find() | SELECT |
U | save | save() update() |
update() | UPDATE |
D | remove | remove() | remove() | DELETE |
T_CONTROLLER_EXPORT マクロについて
ジェネレータで作成したコントローラクラスには、T_CONTROLLER_EXPORTというマクロが追加されています。これは何なのでしょう。
Windowsでは、コントローラはまとめて1つの DLL になりますが、これらのクラスや関数を外部から利用可能にするために、__declspec(dllexport) というキーワードを付けて定義する必要があるのです。T_CONTROLLER_EXPORT マクロは、このキーワードに置換されます。
Mac OS X や Linux では、不要なキーワードなので T_CONTROLLER_EXPORT には何も定義されていません。
#define T_CONTROLLER_EXPORT
このようにすることで、同じソースコードが複数のプラットフォームに対応できているのです。