From: caprice Date: Mon, 30 Dec 2013 09:50:35 +0000 (+0900) Subject: 大量変更… (こういう風に書くのは好ましくない〜) X-Git-Url: http://git.osdn.net/view?p=gikomona%2FGikoMona.git;a=commitdiff_plain;h=ee049ed18a6063a0bce1983042173f64b4b7baa4 大量変更… (こういう風に書くのは好ましくない〜) --- diff --git a/core/doc/README.txt b/core/doc/README.txt index 18e957b..928b8f5 100644 --- a/core/doc/README.txt +++ b/core/doc/README.txt @@ -5,6 +5,8 @@ libcore単体でビルドする場合は、ターミナル上で、 pnuts/gikomonaとともにビルドする場合は、 $(GIKOMONA_ROOT)/build/HOW-TO-BUILD.txt を参照してください。 +なお、このビルドによって生成されるライブラリは必ず静的ライブラリ (*.a, *.lib) になります。 +動的ライブラリ (*.so, *.dylib, *.dll) の生成法は用意されていません。 *テスト方法 libcore単体でテストするときは、ターミナル上で、 @@ -16,19 +18,21 @@ pnuts/gikomonaとともにテストする際には、自動でlibcoreのテス *ビルド後の pnuts/gikomona のフォルダの構造 +@ Windows { $(GIKOMONA_ROOT)/ resource/ icon/ ... -==== pnuts のみ ==== - pnuts.xrc - -==== gikomona のみ ==== - gikomona.xrc + pnuts.xrc (pnuts only) + gikomona.xrc(gikomona only) doc/ - README.txt - LICENSE.txt + README.html + LICENSE.html + + pnuts.exe (pnuts only) + gikomona.exe (gikomona only) + update-utility.exe thread/ board-list/ @@ -36,11 +40,25 @@ $(GIKOMONA_ROOT)/ history.db config.xml favorite.xml +} -==== pnuts のみ ==== - pnuts(.exe) +@ Linux { +$(GIKOMONA_ROOT)/ + resource/ + doc/ -==== gikomona のみ ==== - twitter/ - gikomona(.exe) +} +@ Mac OS X { +$(GIKOMONA_ROOT)/ + Contents/ + Frameworks/ + Resources/ + MacOS/ + pnuts + gikomona + update-utility + Info.plist + version.plist + PkgInfo +} diff --git a/core/include/GikoMona.hpp b/core/include/GikoMona.hpp index 31a075d..377c047 100644 --- a/core/include/GikoMona.hpp +++ b/core/include/GikoMona.hpp @@ -23,6 +23,7 @@ extern void *enabler; /// @breif libbbs で string に関わる typedef を抑制する。@link libbbs/settings.hpp @endlink を見よ。 #define LIBBBS_PRAGMA_USED_BY_GIKOMONA +#define LIBSQLITEXX_PRAGMA_USED_BY_GIKOMONA #define PROJECT_NAME "GikoMona project, powered by monazilla.org." #define PROJECT_URL "http://sourceforge.jp/projects/gikomona/" diff --git a/core/include/config.hpp b/core/include/config.hpp index 2aa315a..efe9338 100644 --- a/core/include/config.hpp +++ b/core/include/config.hpp @@ -1,9 +1,9 @@ #ifndef GIKOMONA_CORE_CONFIG_HPP #define GIKOMONA_CORE_CONFIG_HPP -#include #include +#include #include #include @@ -12,25 +12,52 @@ namespace monazilla { namespace GikoMona { namespace core { -class config final { +class config final : public query { public: typedef config self_type; + typedef query base_type; config() noexcept {} ~config() {} - template - void insert(const mona_string& into, - const std::tuple& value) {} - + /** + * @breif query_concept を満たすクラスはこの関数と同じ型、名前を持つ関数を持っていなければならない。 + * @retval true insert 操作が成功した + * false insert 操作に失敗した + * @param[in] into どのテーブルのどの要素に対し insertion query を実行するかを記述する。 + * 記述の仕方は次の通り:(テーブル名)/[(サブテーブル名)/]*(要素名) + * @param[in] value テーブルに対して代入する値を記述する。 + * @note さらに、最大限 multi-threading な環境を考慮しなければならない。 + */ + template + bool insert(const mona_string& into, + const boost::fusion::vector& value) {} + + template + bool insert(const mona_string& into, + const boost::fusion::vector& value) {} + + template + bool insert(const mona_string& into, + const boost::any& value, + base_type::enable_if_T_is_U*& = enabler) {} + + /** + * @brief query_concept を満たすクラスはこの関数と同じ型、名前を持つ関数を持っていなければならない。 + * @return 引数で指定したテーブルの要素から、テンプレートで指定した方に変換された値が返される。 + */ template T select(const mona_string& column, const mona_string& from) const noexcept {} + template + boost::any select(const mona_string& column, + const mona_string& from, + base_type::enable_if_T_is_U*& = enabler) const noexcept {} + template - std::tuple + boost::fusion::vector select_all(const mona_string& from) const noexcept {} - private: std::unordered_map map; }; diff --git a/core/include/database.hpp b/core/include/database.hpp index e2cac3d..161cd5a 100644 --- a/core/include/database.hpp +++ b/core/include/database.hpp @@ -5,29 +5,44 @@ #include +#include #include +#include #include "GikoMona.hpp" #include "query.hpp" namespace monazilla { namespace GikoMona { namespace core { -class database final { -public: - template - class sql_executer final { - friend database; +class database; + +template +class sql_executer final { + friend database; + + typedef ReturnTypeList result_type; + typedef ArgTypeList arg_type; + typedef ::sqlite3 *db_object_type; + typedef ::sqlite3_stmt *sql_stmt_type; + + const ::sqlite3_stmt *stmt; - sql_executer(const mona_string& sql) {} - ~sql_executer() {} + sql_executer(db_object_type db, + const sql_stmt_type stmt, + boost::system::error_code& ec) noexcept {} + ~sql_executer() {} - public: - void operator()() {} - }; +public: + typename + void bind(const mona_string& param_name, const T& val) {} + result_type operator()() {} +}; +class database final : public query { public: typedef ::sqlite3 *db_object_type; typedef database self_type; + typedef query base_type; database() : database("") {} @@ -48,7 +63,7 @@ public: ~database() { close(); } - /// @brief 受け取った SQL を実行する。ただし、実行できる文は返り値の無いものに限られる。 + /// @brief 受け取った SQL を実行する。ただし、実行できる文は引数と返り値が共に無いものに限られる。 /** * @return SQL が正常に実行された場合は true、それ以外の場合は false を返す。 * @note この関数は SQL の実行結果を返さない。したがって、実行結果が必要な場合は、 @@ -64,23 +79,69 @@ public: * 実行した SQL の実行結果が不要である (あるいはそもそも実行結果が無い) 場合は、 * run_sql() を用いるべきである。 */ - template - sql_executer compile_sql(const mona_string& sql) { - return sql_executer(sql); + template + sql_executer compile_sql(const mona_string& sql) { + /** + * @note sqlite3_prepare(db,zSql,nByte,ppStmtpzTail) で nByte に "sql.length() + 1" を + * 渡すのはなぜか?詳しくは次を参照 : http://www.sqlite.org/c3ref/prepare.html + * ページ中程、"If the nByte argument is less than zero, ~" の先、関係あるところを + * かいつまんで訳すと「もしも関数を呼び出した側が、zSql が NULL-terminated な文字列 + * (\0、\u0 が終端であるような文字列) であることを知っている場合、nByte に文字列のバイト長 + * (ただしここで言うバイト長には終端文字である\0または\u0も「含んだ」ものである) を渡すことで、 + * 若干パフォーマンスが上がる」という記述がある。C++のstd::string::length()/size()は文字列の + * 終端文字を除いた長さを返すので、わざわざ1を加えている。 + */ + int result = ::sqlite3_prepare_v2(db.get_sqlite3_obj(), + sql.c_str(), + sql.length() + 1, + &stmt, + NULL); + if (result != ::SQLITE_OK && !stmt) { + + } else { + return sql_executer(sql); + } } - template - void insert(const mona_string& into, - const std::tuple& value) {} + /** + * @brief + * @retval true insert 操作が成功した + * false insert 操作に失敗した + * @param[in] into どのテーブルのどの要素に対し insertion query を実行するかを記述する。 + * 記述の仕方は次の通り:(テーブル名)/[(サブテーブル名)/]*(要素名) + * @param[in] value テーブルに対して代入する値を記述する。 + * @note さらに、最大限 multi-threading な環境を考慮しなければならない。 + */ + template + bool insert(const mona_string& into, + const boost::fusion::vector& value) {} + + template + bool insert(const mona_string& into, + const boost::fusion::vector& value) {} template + bool insert(const mona_string& into, + const boost::any& value, + base_type::enable_if_T_is_U*& = enabler) {} + + /** + * @brief query_concept を満たすクラスはこの関数と同じ型、名前を持つ関数を持っていなければならない。 + * @return 引数で指定したテーブルの要素から、テンプレートで指定した方に変換された値が返される。 + */ + template T select(const mona_string& column, const mona_string& from) const noexcept {} + template + boost::any select(const mona_string& column, + const mona_string& from, + base_type::enable_if_T_is_U*& = enabler) const noexcept {} + template - std::tuple + boost::fusion::vector select_all(const mona_string& from) const noexcept {} - + /// @brief データベースの最適化を行う。 /** * @note 内部では以下のコマンドが実行され、データベースの不要データの圧縮と再構築が行われる。 diff --git a/core/include/extension.hpp b/core/include/extension.hpp index ec45233..b5443d1 100644 --- a/core/include/extension.hpp +++ b/core/include/extension.hpp @@ -1,5 +1,5 @@ -#ifndef core_extension_hpp -#define core_extension_hpp +#ifndef GIKOMONA_CORE_EXTENSION_HPP +#define GIKOMONA_CORE_EXTENSION_HPP #include #include diff --git a/core/include/model.hpp b/core/include/model.hpp index 647d54c..432c6d2 100644 --- a/core/include/model.hpp +++ b/core/include/model.hpp @@ -3,8 +3,8 @@ #include #include -#include +#include #include #include #include @@ -16,11 +16,12 @@ namespace monazilla { namespace GikoMona { namespace core { -class model { +class model : public query { public: typedef model self_type; - typedef std::tuple inserted_query_type; - typedef inserted_query_type *inserted_query_triv_copyable_type; + typedef query base_type; + typedef boost::fusion::vector inserted_value_type; + typedef inserted_value_type *inserted_value_triv_copyable_type; model() noexcept; ~model(); @@ -29,25 +30,47 @@ public: model *get_instance() { return instance; } + + /** + * @breif query_concept を満たすクラスはこの関数と同じ型、名前を持つ関数を持っていなければならない。 + * @retval true insert 操作が成功した + * false insert 操作に失敗した + * @param[in] into どのテーブルのどの要素に対し insertion query を実行するかを記述する。 + * 記述の仕方は次の通り:(テーブル名)/[(サブテーブル名)/]*(要素名) + * @param[in] value テーブルに対して代入する値を記述する。 + * @note さらに、最大限 multi-threading な環境を考慮しなければならない。 + */ + template + bool insert(const mona_string& into, + const boost::fusion::vector& value) {} - template + template bool insert(const mona_string& into, - const std::tuple& values) { - /* - auto any_value = boost::any(values); - auto obj = std::make_tuple(into, any_value); - return inserted_query_queue.push(); - */ - } + const boost::fusion::vector& value) {} template + virtual + bool insert(const mona_string& into, + const boost::any& value, + base_type::enable_if_T_is_U*& = enabler) {} + + /** + * @brief query_concept を満たすクラスはこの関数と同じ型、名前を持つ関数を持っていなければならない。 + * @return 引数で指定したテーブルの要素から、テンプレートで指定した方に変換された値が返される。 + */ + template T select(const mona_string& column, const mona_string& from) const noexcept {} + template + boost::any select(const mona_string& column, + const mona_string& from, + base_type::enable_if_T_is_U*& = enabler) const noexcept {} + template - std::tuple + boost::fusion::vector select_all(const mona_string& from) const noexcept {} - + void exec_inserted_query(); bool load_file(const boost::filesystem::path& file_path, const mona_string& loaded_table_name); @@ -55,11 +78,15 @@ public: const mona_string& saved_table_name); private: + void get_object_expressing_into_path_in_query(const mona_string& src, + const boost::any& value); + void analyze_into_path_in_query(const mona_string& into_path_in_query); + static self_type *instance; struct model_pimpl; std::shared_ptr pimpl; - boost::lockfree::queue inserted_query_queue; + boost::lockfree::queue query_queue; }; template <> diff --git a/core/include/query.hpp b/core/include/query.hpp index a28f09e..b2762e4 100644 --- a/core/include/query.hpp +++ b/core/include/query.hpp @@ -1,9 +1,7 @@ #ifndef GIKOMONA_CORE_QUERY_HPP_INCLUDED #define GIKOMONA_CORE_QUERY_HPP_INCLUDED -#include -#include - +#include #include #include "GikoMona.hpp" @@ -14,20 +12,20 @@ template struct is_satisfied_with_query_concept : public boost::mpl::false_ {}; /** - * @brief このクラスでは query_concept が満たすべき用件が記述されている。 + * @brief このクラスは query_concept を満たす全てのクラスが継承しなければならない。 */ -class query_concept final { +class query { public: /// query_concept を満たすクラスは自分自身の型を self_type として表明しなければならない。 - typedef query_concept self_type; + typedef query self_type; template using enable_if_T_is_U = typename std::enable_if::value>::type; /// query_concept を満たすクラスは外部から構築可能でなければならない。 - query_concept() {} + query() {} /// query_concept を満たすクラスは外部から解体可能でなければならない。 - ~query_concept() {} + ~query() {} /** * @breif query_concept を満たすクラスはこの関数と同じ型、名前を持つ関数を持っていなければならない。 @@ -39,38 +37,42 @@ public: * @note さらに、最大限 multi-threading な環境を考慮しなければならない。 */ template + virtual bool insert(const mona_string& into, - const std::tuple& value) {} + const boost::fusion::vector& value) override {} template + virtual bool insert(const mona_string& into, - const std::tuple& value) {} + const boost::fusion::vector& value) override {} template + virtual bool insert(const mona_string& into, const boost::any& value, - enable_if_T_is_U*& = enabler) {} + enable_if_T_is_U*& = enabler) override {} /** * @brief query_concept を満たすクラスはこの関数と同じ型、名前を持つ関数を持っていなければならない。 * @return 引数で指定したテーブルの要素から、テンプレートで指定した方に変換された値が返される。 */ template + virtual T select(const mona_string& column, - const mona_string& from) const noexcept {} + const mona_string& from) const noexcept override {} template + virtual boost::any select(const mona_string& column, const mona_string& from, - enable_if_T_is_U*& = enabler) {} + enable_if_T_is_U*& = enabler) const noexcept override {} template - std::tuple - select_all(const mona_string& from) const noexcept {} + virtual + boost::fusion::vector + select_all(const mona_string& from) const noexcept override {} }; -template <> - } } } #endif \ No newline at end of file diff --git a/core/include/string.hpp b/core/include/string.hpp index 738409c..d76fb56 100644 --- a/core/include/string.hpp +++ b/core/include/string.hpp @@ -5,8 +5,8 @@ // Created by caprice on 2013/08/05. // -#ifndef core_string_hpp -#define core_string_hpp +#ifndef GIKOMONA_CORE_STRING_HPP +#define GIKOMONA_CORE_STRING_HPP #include @@ -16,11 +16,11 @@ // このコンパイラの char16_t、char32_t を UTF-16/32 を表現するか? #if !(__STDC_UTF_16__) - #error "sorry, this compiler does not support utf-16." + #error "[GikoMona.libcore @pp-time] : sorry, this compiler does not support utf-16." #endif #if !(__STDC_UTF_32__) - #error "sorry, this compiler does not support utf-32." + #error "[GikoMona.libcore @pp-time] : sorry, this compiler does not support utf-32." #endif namespace monazilla { namespace GikoMona { diff --git a/core/src/GikoMona.cpp b/core/src/GikoMona.cpp index 9b0b5c2..74d450c 100644 --- a/core/src/GikoMona.cpp +++ b/core/src/GikoMona.cpp @@ -1,4 +1,8 @@ #include +#include + +#include + #include #include "GikoMona.hpp" @@ -20,8 +24,16 @@ bool init_core() { wxXmlResource::Get()->InitAllHandlers(); wxXmlResource::Get()->LoadAllFiles(wxT("resouce")); + boost::system::error_code reason; + if(!boost::filesystem::create_directory(".tmp", reason) || reason) { + // log + std::terminate(); + } + app_model = new model; app_extension = new extension; + + return true; } void done_core() noexcept { @@ -33,6 +45,11 @@ void done_core() noexcept { void optimize_database(const boost::filesystem::path& db_path) { database db(db_path); + /* + auto value = db.compile(u8"SELECT * FROM file-information;"); + value.execute(); + value.get_result(); + */ if(db.select("count-of-deleting-values", "file-infomation") >= 1000) { db.optimize(); } diff --git a/core/src/model.cpp b/core/src/model.cpp index e72d6e7..de24846 100644 --- a/core/src/model.cpp +++ b/core/src/model.cpp @@ -1,3 +1,4 @@ +#include #include "model.hpp" @@ -5,10 +6,13 @@ namespace monazilla { namespace GikoMona { namespace core { struct model::model_pimpl { // session/tab-window + /* 構造 + * bbs-name(TEXT)|board-name(TEXT)|thread-id(TEXT)|thread-name(TEXT)|is_fixed(INTEGAR) + */ database tab_db; // session/history /* 構造 - * date()|bbs-name()|board-name()|thread-id()|thread-name() + * date(TEXT)|bbs-name(TEXT)|board-name(TEXT)|thread-id(TEXT)|thread-name(TEXT) */ database history_db; // application @@ -18,6 +22,10 @@ struct model::model_pimpl { model::model() noexcept { instance = this; pimpl = std::make_shared(); + + auto config_path = pimpl->app_config.select("config", "file-path"); + + pimpl->tab_db.create(config_path); } model::~model() {} @@ -32,23 +40,25 @@ bool model::load_file(const boost::filesystem::path& file_path, } void model::exec_inserted_query() { - inserted_query_triv_copyable_type q; - if(inserted_query_queue.empty()) { + inserted_value_triv_copyable_type q; + if(query_queue.empty()) { return; } else { - inserted_query_queue.pop(q); + query_queue.pop(q); } mona_string into; - boost::any tup; - std::tie(*q, into, tup); + boost::any value; + std::tie(*q, into, value); + + analyze_into_path_in_query(into); if(into.find_first_of("application", 0, into.length()) != mona_string::npos) { // application/* } else if (into.find_first_of("session", 0, into.length()) != mona_string::npos) { // session/* if(into.find("history", 0, into.length()) != mona_string::npos) { - pimpl->history_db.insert(into, tup); + ; } else if(into.find("tab-window") != mona_string::npos != mona_string::npos) { pimpl->tab_db.insert(into, tup); } diff --git a/core/test/query.cpp b/core/test/query.cpp index 5928d7a..d0a8acb 100644 --- a/core/test/query.cpp +++ b/core/test/query.cpp @@ -12,27 +12,6 @@ BOOST_AUTO_TEST_SUITE(query) namespace gm_core = monazilla::GikoMona::core; -BOOST_AUTO_TEST_CASE(type_concept) { - BOOST_REQUIRE_EQUAL(std::is_trivially_copyable::value, true); -} -/* -BOOST_AUTO_TEST_CASE(selecting) { - BOOST_CHECK_MESSAGE( - false, - gm_core::query().define() - .select(gm_core::all_columnes, "test") - .dump() - ); - BOOST_CHECK_MESSAGE( - false, - gm_core::query().define() - .select({"name", "birthday", "mail"}, "test") - .dump() - ); -} -*/ - - BOOST_AUTO_TEST_SUITE_END // query BOOST_AUTO_TEST_SUITE_END // CORE