NotesとQtでWindows、Mac OS X、Ubuntuのデスクトップアプリ(その8 - データベース・基本クラス編)
前回紹介したデータベース関連のAPIを踏まえて、Databaseクラスを定義していきます。 方針としては、Notes/Domino APIプログラミング―C++とSTLによる実践的プログラミングを踏襲して、コピー不可のクラスとします。
<database.h> #ifndef NTLX_DATABASE_H #define NTLX_DATABASE_H #include "ntlx_global.h" #include <QString> #include "status.h" #if defined(NT) #pragma pack(push, 1) #endif #include <nsfdb.h> #if defined(NT) #pragma pack(pop) #endif namespace ntlx { class Lmbcs; /** * @brief データベースクラス */ class NTLXSHARED_EXPORT Database { public: /** * @brief デフォルトコンストラクタ */ explicit Database(); /** * @brief パスによるコンストラクタ * @param path パス * @param server サーバ名(省略時はローカル) * @param port ポート名(省略時はデフォルトポート) */ explicit Database(const QString& path , const QString& server = QString() , const QString& port = QString() , Status* status = nullptr ); /** * @brief デストラクタ */ virtual ~Database(); /** * @brief DBHANDLEキャスト演算子 */ operator DBHANDLE() const { return handle_; } /** * @brief データベースのタイトルを取得する * @param status 関数の実行結果を取得したい場合はSTATUS変数へのポインタ * @return データベースタイトル */ QString getTitle(STATUS* status = nullptr) const; /** * @brief データベースカテゴリ名を取得する * @param status 関数の実行結果を取得したい場合はSTATUS変数へのポインタ * @return データベースカテゴリ名 */ QString getCategories(STATUS* status = nullptr) const; /** * @brief データベースクラス(引き継ぎ元テンプレート名)を取得する * @param status 関数の実行結果を取得したい場合はSTATUS変数へのポインタ * @return データベースクラス(引き継ぎ元テンプレート名) */ QString getClass(STATUS* status = nullptr) const; /** * @brief データベース設計クラス(自身のテンプレート名)を取得する * @param status 関数の実行結果を取得したい場合はSTATUS変数へのポインタ * @return データベース設計クラス(自身のテンプレート名) */ QString getDesignClass(STATUS* status = nullptr) const; /** * @brief データベースを開く * @return 結果ステータス */ Status open( const QString& path , const QString& server , const QString& port ); /** * @brief データベースを閉じる * @return 結果ステータス */ Status close(); /** * @brief パス、サーバ名、ポート名からネットパスを構築する * @param path パス * @param server サーバ名 * @param port ポート名 * @param status 結果ステータス * @return ネットパス */ static Lmbcs constructNetPath( const QString& path , const QString& server , const QString& port , STATUS* status = nullptr ); protected: /** * @brief データベースハンドルを返す * @return データベースハンドル */ DBHANDLE handle() const { return handle_; } /** * @brief ハンドルを設定する * @param handle データベースハンドル */ void setHandle(DBHANDLE handle) { handle_ = handle; } /** * @brief データベース情報を取得する * @param what データベース情報の種類(INFOPARSE_XXX) * @param status 結果ステータス * @return データベース情報 */ QString getInfo(WORD what, STATUS* status = nullptr) const; private: DBHANDLE handle_; Database(const Database&); Database& operator=(const Database&); }; } // namespace ntlx #endif // NTLX_DATABASE_H <database.cpp> #include "database.h" #include "lmbcs.h" #if defined(NT) #pragma pack(push, 1) #endif #include <osfile.h> #if defined(NT) #pragma pack(pop) #endif namespace ntlx { Database::Database() : handle_(NULLHANDLE) { } Database::Database(const QString &path , const QString &server , const QString &port , Status* status ) : handle_(NULLHANDLE) { Status result = open(path, server, port); if (status != nullptr) *status = result; } Database::~Database() { close(); } QString Database::getTitle(STATUS* status) const { return getInfo(INFOPARSE_TITLE, status); } QString Database::getCategories(STATUS* status) const { return getInfo(INFOPARSE_CATEGORIES, status); } QString Database::getClass(STATUS* status) const { return getInfo(INFOPARSE_CLASS, status); } QString Database::getDesignClass(STATUS* status) const { return getInfo(INFOPARSE_DESIGN_CLASS, status); } Status Database::open( const QString& path , const QString& server , const QString& port ) { close(); Lmbcs netPath = constructNetPath(path, server, port); Status result = NSFDbOpen(netPath.constData(), &handle_); if (result.failure()) handle_ = NULLHANDLE; return result; } Status Database::close() { if (handle_ != NULLHANDLE) { Status result = NSFDbClose(handle_); handle_ = NULLHANDLE; return result; } return NOERROR; } Lmbcs Database::constructNetPath(const QString &path , const QString &server , const QString &port , STATUS* status ) { Lmbcs lmPath = Lmbcs::fromQString(path); Lmbcs lmServer = Lmbcs::fromQString(server); Lmbcs lmPort = Lmbcs::fromQString(port); char netPath[MAXPATH]; Status result = OSPathNetConstruct( lmPort.isEmpty() ? 0 : lmPort.constData() , lmServer.constData() , lmPath.constData() , netPath ); if (status != nullptr) *status = result; return result.success() ? Lmbcs(netPath) : Lmbcs(); } /** * @note NSF_INFOは以下のような構成を取る * @note タイトル+改行+カテゴリ+改行+#1+設計クラス+改行+#2+クラス+終端0 * @note 全体で128バイト以内になる */ QString Database::getInfo(WORD what, STATUS* status) const { Q_ASSERT(handle()); char infoData[NSF_INFO_SIZE]; char nameData[NSF_INFO_SIZE]; Status result = NSFDbInfoGet(handle(), infoData); if (status != nullptr) *status = result; if (result.failure()) return QString(); NSFDbInfoParse(infoData, what, nameData, NSF_INFO_SIZE - 1); nameData[NSF_INFO_SIZE - 1] = '\0'; Lmbcs lmbcs(nameData); return lmbcs.toQString(); } } // namespace ntlx