├── version ├── .gitignore ├── CHANGES.md ├── .gitmodules ├── test ├── test.cpp ├── ObjectTest.h ├── DateTimeTest.h ├── JSScriptTest.h ├── VariantTest.h ├── SqlTest.h └── StringTest.h ├── src ├── compat │ └── strptime.h ├── db │ ├── nosql │ │ ├── NoSqlStorable.cpp │ │ └── NoSqlStorable.h │ ├── ExpressionAssignment.cpp │ ├── sql │ │ ├── connectors │ │ │ ├── SqlTransactionImpl.cpp │ │ │ ├── sqlite3 │ │ │ │ ├── SqliteStatementImpl.h │ │ │ │ ├── SqliteStatementImpl.cpp │ │ │ │ ├── SqliteTransactionImpl.h │ │ │ │ └── SqliteConnector.h │ │ │ ├── SqlStatementImpl.cpp │ │ │ ├── mysql │ │ │ │ ├── MySqlStatementImpl.h │ │ │ │ ├── MySqlConnector.h │ │ │ │ ├── MySqlTransactionImpl.h │ │ │ │ ├── MySqlStatementImpl.cpp │ │ │ │ └── MySqlConnector.cpp │ │ │ ├── postgres │ │ │ │ ├── PostgresStatementImpl.h │ │ │ │ ├── PostgresConnector.h │ │ │ │ ├── PostgresTransactionImpl.h │ │ │ │ └── PostgresStatementImpl.cpp │ │ │ ├── SqlStatementImpl.h │ │ │ ├── SqlTransactionImpl.h │ │ │ ├── SqlConnectorBase.cpp │ │ │ └── SqlConnectorBase.h │ │ ├── SqlResultIterator.cpp │ │ ├── SqlColumnConstraint.cpp │ │ ├── SqlResultIterator.h │ │ ├── SqlResultSet.h │ │ ├── SqlResultSet.cpp │ │ ├── SqlExpressionTreeWalker.h │ │ ├── SqlTransaction.cpp │ │ └── SqlTransaction.h │ ├── ASTWalkerBase.h │ ├── ASTWalkerBase.cpp │ ├── ExpressionAssignment.h │ └── TypePromotion.h ├── serialization │ ├── TypeResolverFactory.h │ ├── TypeResolverFactory.cpp │ └── json │ │ ├── JsonDeserializerVisitor.h │ │ └── JsonSerializerVisitor.h ├── scripting │ ├── ScriptThreadBase.cpp │ ├── js │ │ ├── JSScriptEngine.h │ │ ├── JSScriptProgram.h │ │ ├── JSScriptEngine.cpp │ │ ├── JSScriptProgram.cpp │ │ └── JSScriptThread.h │ ├── ScriptEngineBase.cpp │ ├── ScriptProgramBase.cpp │ ├── ScriptProgramBase.h │ ├── ScriptEngineBase.h │ └── ScriptThreadBase.h ├── utils │ ├── Array.cpp │ ├── SharedDataPointer.cpp │ ├── Utils.h │ ├── SharedDataBase.cpp │ ├── Nullable.h │ ├── SharedDataBase.h │ └── SharedDataPointer.h └── core │ ├── InitVisitor.h │ ├── VisitorBase.cpp │ ├── VisitorBase.h │ ├── MetaType.h │ ├── Object.cpp │ └── Object.h ├── conanfile.txt ├── config.h.in ├── cmake ├── Macros │ └── ScanSources.cmake └── Modules │ ├── CMakeFindFrameworks.cmake │ ├── FindJsonCpp.cmake │ ├── FindIconv.cmake │ ├── FindMongoDB.cmake │ ├── FindSpiderMonkey.cmake │ ├── FindPackageMessage.cmake │ ├── FindSqlite3.cmake │ ├── SelectLibraryConfigurations.cmake │ ├── FindMySQL.cmake │ └── CMakeParseArguments.cmake ├── README.md ├── appveyor.yml ├── .travis.yml └── examples └── scripting-example.cpp /version: -------------------------------------------------------------------------------- 1 | 0.3 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | CMakeLists.txt.* 2 | /build 3 | /conanbuildinfo.cmake 4 | /conaninfo.txt 5 | -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- 1 | 0.4 (current) 2 | - Added quotation of reserved words in queries 3 | 4 | 0.3 (Prerelease) 5 | - Completed -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "coveralls-cmake"] 2 | path = coveralls-cmake 3 | url = https://github.com/JoakimSoderberg/coveralls-cmake.git 4 | -------------------------------------------------------------------------------- /test/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | ::testing::InitGoogleTest(&argc, argv); 7 | return RUN_ALL_TESTS(); 8 | } 9 | -------------------------------------------------------------------------------- /test/ObjectTest.h: -------------------------------------------------------------------------------- 1 | #ifndef OBJECTTEST_H 2 | #define OBJECTTEST_H 3 | #include 4 | 5 | class ObjectTest : public testing::Test 6 | { 7 | public: 8 | }; 9 | #endif // OBJECTTEST_H 10 | -------------------------------------------------------------------------------- /src/compat/strptime.h: -------------------------------------------------------------------------------- 1 | #ifndef _STRPTIME_H 2 | #define _STRPTIME_H 3 | #include 4 | 5 | extern "C" char * strptime(const char *buf, const char *fmt, struct tm *tm); 6 | 7 | #endif // _STRPTIME_H -------------------------------------------------------------------------------- /conanfile.txt: -------------------------------------------------------------------------------- 1 | [requires] 2 | gtest/1.7.0@lasote/stable 3 | sqlite3/3.10.2@TyRoXx/stable 4 | 5 | [generators] 6 | cmake 7 | 8 | [options] 9 | gtest:shared=False 10 | 11 | [imports] 12 | bin, *.dll -> ./build/bin 13 | lib, *.dylib* -> ./build/bin 14 | -------------------------------------------------------------------------------- /test/DateTimeTest.h: -------------------------------------------------------------------------------- 1 | #ifndef DATETIMETEST_H 2 | #define DATETIMETEST_H 3 | #include 4 | #include "DateTime.h" 5 | #include 6 | #include 7 | 8 | class DateTimeTest : public ::testing::Test 9 | { 10 | }; 11 | 12 | #endif // DATETIMETEST_H 13 | -------------------------------------------------------------------------------- /src/db/nosql/NoSqlStorable.cpp: -------------------------------------------------------------------------------- 1 | #include "NoSqlStorable.h" 2 | 3 | namespace metacpp 4 | { 5 | namespace db 6 | { 7 | namespace nosql 8 | { 9 | 10 | NoSqlStorable::NoSqlStorable() 11 | { 12 | 13 | } 14 | 15 | NoSqlStorable::~NoSqlStorable() 16 | { 17 | 18 | } 19 | 20 | } // namespace nosql 21 | } // namespace db 22 | } // namespace metacpp 23 | -------------------------------------------------------------------------------- /src/db/nosql/NoSqlStorable.h: -------------------------------------------------------------------------------- 1 | #ifndef NOSQLSTORABLE_H 2 | #define NOSQLSTORABLE_H 3 | #include "Variant.h" 4 | 5 | namespace metacpp 6 | { 7 | namespace db 8 | { 9 | namespace nosql 10 | { 11 | 12 | class NoSqlStorable 13 | { 14 | public: 15 | NoSqlStorable(); 16 | ~NoSqlStorable(); 17 | private: 18 | Variant m_objectId; // _id implicit field 19 | }; 20 | 21 | } // namespace nosql 22 | } // namespace db 23 | } // namespace metacpp 24 | 25 | #endif // NOSQLSTORABLE_H 26 | -------------------------------------------------------------------------------- /config.h.in: -------------------------------------------------------------------------------- 1 | #ifndef METACPP_CONFIG_H 2 | #define METACPP_CONFIG_H 3 | 4 | #define METACPP_VERSION_MAJOR @METACPP_VERSION_MAJOR@ 5 | #define METACPP_VERSION_MINOR @METACPP_VERSION_MINOR@ 6 | #define METACPP_VERSION_STRING "@METACPP_VERSION_STRING@" 7 | 8 | #cmakedefine HAVE_JSONCPP 9 | 10 | #cmakedefine HAVE_SQLITE3 11 | 12 | #cmakedefine HAVE_POSTGRES 13 | 14 | #cmakedefine HAVE_MYSQL 15 | 16 | #cmakedefine HAVE_MONGODB 17 | 18 | #cmakedefine HAVE_SPIDERMONKEY 19 | 20 | #endif // METACPP_CONFIG_H 21 | -------------------------------------------------------------------------------- /cmake/Macros/ScanSources.cmake: -------------------------------------------------------------------------------- 1 | 2 | # scans directories for C/C++ source and header files 3 | MACRO(ADD_SOURCE_DIRECTORY SOURCES HEADERS SCAN_DIRS) 4 | FOREACH(DIR ${SCAN_DIRS}) 5 | 6 | file(GLOB SRC_TEMP 7 | "${DIR}/*.cpp" "${DIR}/*.c" "${DIR}/*.cc" 8 | ) 9 | file(GLOB HDR_TEMP 10 | "${DIR}/*.h" "${DIR}/*.hh" "${DIR}/*.hpp" 11 | ) 12 | LIST(APPEND ${SOURCES} ${SRC_TEMP}) 13 | LIST(APPEND ${HEADERS} ${HDR_TEMP}) 14 | ENDFOREACH(DIR) 15 | ENDMACRO(ADD_SOURCE_DIRECTORY) 16 | -------------------------------------------------------------------------------- /test/JSScriptTest.h: -------------------------------------------------------------------------------- 1 | #ifndef JSSCRIPTTEST_H 2 | #define JSSCRIPTTEST_H 3 | 4 | #include 5 | #include "ScriptEngineBase.h" 6 | 7 | class JSScriptTest : public testing::Test 8 | { 9 | public: 10 | void SetUp() override; 11 | void TearDown() override; 12 | 13 | static void SetUpTestCase(); 14 | static void TearDownTestCase(); 15 | 16 | std::unique_ptr m_engine; 17 | metacpp::SharedObjectPointer m_program; 18 | }; 19 | 20 | #endif // JSSCRIPTTEST_H 21 | -------------------------------------------------------------------------------- /test/VariantTest.h: -------------------------------------------------------------------------------- 1 | #ifndef VARIANTTEST_H 2 | #define VARIANTTEST_H 3 | #include 4 | #include "Variant.h" 5 | 6 | class VariantTest : public ::testing::Test 7 | { 8 | }; 9 | 10 | template 11 | class TypedVariantTest : public ::testing::Test 12 | { 13 | }; 14 | 15 | template 16 | class ConvertVariantTest : public ::testing::TestWithParam > 17 | { 18 | }; 19 | 20 | template 21 | class InvalidConvertVariantTest : public ::testing::TestWithParam 22 | { 23 | }; 24 | 25 | #endif // VARIANTTEST_H 26 | -------------------------------------------------------------------------------- /test/SqlTest.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLTEST_H 2 | #define SQLTEST_H 3 | #include 4 | #include "SqlTransaction.h" 5 | 6 | class SqlTest : public testing::TestWithParam 7 | { 8 | public: 9 | void prepareSchema(); 10 | void prepareData(); 11 | void clearData(); 12 | public: 13 | void SetUp() override; 14 | void TearDown() override; 15 | 16 | static void SetUpTestCase(); 17 | static void TearDownTestCase(); 18 | private: 19 | std::unique_ptr m_conn; 20 | }; 21 | 22 | #endif // SQLTEST_H 23 | -------------------------------------------------------------------------------- /src/serialization/TypeResolverFactory.h: -------------------------------------------------------------------------------- 1 | #ifndef TYPERESOLVERFACTORY_H 2 | #define TYPERESOLVERFACTORY_H 3 | #include "config.h" 4 | #include 5 | #include 6 | #include 7 | 8 | namespace metacpp 9 | { 10 | namespace serialization 11 | { 12 | 13 | class TypeResolverFactory : FactoryBase 14 | { 15 | public: 16 | explicit TypeResolverFactory(Array knownTypes); 17 | 18 | Object *createInstance(String typeUri) override; 19 | private: 20 | Array m_knownTypes; 21 | }; 22 | 23 | } // namespace serialization 24 | } // namespace metacpp 25 | 26 | #endif // TYPERESOLVERFACTORY_H 27 | -------------------------------------------------------------------------------- /src/serialization/TypeResolverFactory.cpp: -------------------------------------------------------------------------------- 1 | #include "TypeResolverFactory.h" 2 | 3 | namespace metacpp 4 | { 5 | namespace serialization 6 | { 7 | 8 | TypeResolverFactory::TypeResolverFactory(Array knownTypes) 9 | : m_knownTypes(knownTypes) 10 | { 11 | } 12 | 13 | Object *TypeResolverFactory::createInstance(String typeUri) 14 | { 15 | for (const MetaObject *knownType : m_knownTypes) { 16 | if (knownType->name() == typeUri) { 17 | return knownType->createInstance(); 18 | } 19 | } 20 | throw std::invalid_argument(String("Could not resolve type " + typeUri).c_str()); 21 | } 22 | 23 | } // namespace serialization 24 | } // namespace metacpp 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | metacpp 2 | ======= 3 | [![Build Status](https://travis-ci.org/the-alien/metacpp.svg?branch=master)](https://travis-ci.org/the-alien/metacpp) 4 | [![Build status](https://ci.appveyor.com/api/projects/status/lgl2ckqp6undmsc2?svg=true)](https://ci.appveyor.com/project/the-alien/metacpp) 5 | [![Coverage Status](https://coveralls.io/repos/github/the-alien/metacpp/badge.svg?branch=master)](https://coveralls.io/github/the-alien/metacpp?branch=master) 6 | [![Coverity Scan Build Status](https://scan.coverity.com/projects/7967/badge.svg)](https://scan.coverity.com/projects/metacpp) 7 | 8 | Yet another reflection library for C++. 9 | Base functionality: 10 | * Object reflection and introspection 11 | * Object serialization 12 | * Type-safe C++ ORM 13 | * Javascript bindings (using SpiderMonkey engine) 14 | -------------------------------------------------------------------------------- /src/scripting/ScriptThreadBase.cpp: -------------------------------------------------------------------------------- 1 | #include "ScriptThreadBase.h" 2 | #include 3 | 4 | namespace metacpp { 5 | namespace scripting { 6 | 7 | ScriptThreadBase::ScriptThreadBase() { 8 | } 9 | 10 | ScriptThreadBase::~ScriptThreadBase() { 11 | } 12 | 13 | bool ScriptThreadBase::runAsync(const std::function &onFinished, const std::function &onError) 14 | { 15 | std::async(std::launch::async, 16 | [&]{ 17 | try 18 | { 19 | onFinished(this->run()); 20 | } 21 | catch (...) 22 | { 23 | onError(std::current_exception()); 24 | } 25 | }); 26 | return true; 27 | } 28 | 29 | const char *TerminationException::what() const _NOEXCEPT 30 | { 31 | return "Terminated"; 32 | } 33 | 34 | } // namespace scripting 35 | } // namespace metacpp 36 | -------------------------------------------------------------------------------- /src/scripting/js/JSScriptEngine.h: -------------------------------------------------------------------------------- 1 | #ifndef JSSCRIPTENGINE_H 2 | #define JSSCRIPTENGINE_H 3 | 4 | #include "ScriptEngineBase.h" 5 | #include "JSScriptProgram.h" 6 | #include 7 | #include 8 | 9 | namespace metacpp { 10 | namespace scripting { 11 | namespace js { 12 | 13 | class JSScriptEngine : public ScriptEngineBase 14 | { 15 | public: 16 | explicit JSScriptEngine(); 17 | ~JSScriptEngine(); 18 | 19 | JSRuntime *rootRuntime() const; 20 | const JSClass *globalClass() const; 21 | bool isInMainThread() const; 22 | protected: 23 | ScriptProgramBase *createProgramImpl() override; 24 | void closeProgramImpl(ScriptProgramBase *program) override; 25 | private: 26 | Array m_programs; 27 | mutable std::mutex m_programsMutex; 28 | JSRuntime *m_runtime; 29 | JSClass m_globalClass; 30 | std::thread::id m_mainThreadId; 31 | }; 32 | 33 | } // namespace js 34 | } // namespace scripting 35 | } // namespace metacpp 36 | 37 | #endif // JSSCRIPTENGINE_H 38 | -------------------------------------------------------------------------------- /src/scripting/js/JSScriptProgram.h: -------------------------------------------------------------------------------- 1 | #ifndef JSSCRIPTPROGRAM_H 2 | #define JSSCRIPTPROGRAM_H 3 | #include 4 | #include "ScriptProgramBase.h" 5 | #include "JSScriptThread.h" 6 | #include 7 | #include 8 | 9 | namespace metacpp 10 | { 11 | namespace scripting 12 | { 13 | namespace js 14 | { 15 | 16 | class JSScriptEngine; 17 | 18 | class JSScriptProgram : public ScriptProgramBase 19 | { 20 | public: 21 | explicit JSScriptProgram(JSScriptEngine *engine); 22 | ~JSScriptProgram(); 23 | 24 | void compile(const void *pBuffer, size_t size, const String& filename) override; 25 | protected: 26 | ScriptThreadBase *createThreadImpl(const String& functionName, 27 | const VariantArray& args = VariantArray()) override; 28 | void closeThreadImpl(ScriptThreadBase *thread) override; 29 | private: 30 | JSScriptEngine *m_engine; 31 | ByteArray m_bytecode; 32 | std::mutex m_threadsMutex; 33 | Array m_threads; 34 | }; 35 | 36 | } // namespace js 37 | } // namespace scripting 38 | } // namespace metacpp 39 | 40 | 41 | #endif // JSSCRIPTPROGRAM_H 42 | -------------------------------------------------------------------------------- /src/scripting/ScriptEngineBase.cpp: -------------------------------------------------------------------------------- 1 | #include "ScriptEngineBase.h" 2 | 3 | namespace metacpp { 4 | namespace scripting { 5 | 6 | ScriptEngineBase::ScriptEngineBase() { 7 | } 8 | 9 | ScriptEngineBase::~ScriptEngineBase() { 10 | } 11 | 12 | SharedObjectPointer ScriptEngineBase::createProgram() 13 | { 14 | auto deleter = [this](ScriptProgramBase *program) { closeProgramImpl(program); }; 15 | return SharedObjectPointer(createProgramImpl(), deleter); 16 | } 17 | 18 | void ScriptEngineBase::registerClass(const MetaObject *metaObject) 19 | { 20 | m_registeredClasses.push_back(metaObject); 21 | } 22 | 23 | Array ScriptEngineBase::registeredClasses() const 24 | { 25 | return m_registeredClasses; 26 | } 27 | 28 | ScriptRuntimeError::ScriptRuntimeError(const char *message, const char *filename, uint32_t line, uint32_t column) 29 | { 30 | m_what = String(filename) + ":" + String::fromValue(line) + ":" + String::fromValue(column) + ":" 31 | + message; 32 | } 33 | 34 | const char *ScriptRuntimeError::what() const _NOEXCEPT 35 | { 36 | return m_what.c_str(); 37 | } 38 | 39 | } // namespace scripting 40 | } // namespace metacpp 41 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 1.0.{build} 2 | 3 | image: Visual Studio 2013 4 | 5 | clone_folder: C:\projects\metacpp 6 | 7 | install: 8 | - cmd: '"C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/vcvarsall.bat" amd64_x86' 9 | - cmd: echo Downloading Conan package manager... 10 | - ps: wget http://downloads.conan.io/latest_windows -OutFile conan_installer.exe 11 | - cmd: conan_installer.exe /SILENT 12 | - cmd: set PATH=%PATH%;C:\Program Files (x86)\Conan\conan 13 | - cmd: conan --version 14 | 15 | build_script: 16 | - ps: >- 17 | cd C:\projects\metacpp 18 | 19 | & "C:\Program Files (x86)\Conan\conan\conan.exe" install . 20 | 21 | mkdir build 22 | 23 | cd build 24 | 25 | cmake -LA -G "Visual Studio 12 Win64" -DUSE_CONAN=1 .. 26 | 27 | msbuild metacpp.sln /p:Configuration=Release /toolsversion:12.0 /p:Platform=x64 /p:PlatformToolset=v120 28 | 29 | test_script: 30 | - ps: >- 31 | & "C:\projects\metacpp\build\bin\metacpp-test.exe" --gtest_output=xml 32 | 33 | $wc = New-Object 'System.Net.WebClient' 34 | 35 | $wc.UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path test_detail.xml)) 36 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | sudo: required 3 | dist: trusty 4 | addons: 5 | mariadb: '10.0' 6 | postgresql: '9.4' 7 | apt: 8 | packages: 9 | - lcov 10 | - curl 11 | - libsqlite3-dev 12 | - libgtest-dev 13 | - libpq-dev 14 | - libmysqlclient-dev 15 | 16 | services: 17 | - postgresql 18 | - mysql 19 | 20 | compiler: 21 | # - clang 22 | - gcc 23 | 24 | install: 25 | - sudo apt-get install -y libmozjs-24-dev 26 | - pushd /usr/src/gtest 27 | - sudo cmake -DCMAKE_BUILD_TYPE=Release . 28 | - sudo make VERBOSE=1 29 | - sudo mv libg* /usr/lib/ 30 | - popd 31 | 32 | before_script: 33 | - psql -c 'create database travis_ci_test;' -U postgres 34 | - mysql -e 'create database travis_ci_test;' -uroot 35 | - mkdir -p build 36 | - cd build 37 | - cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=ON -DCOVERALLS=ON -DCOVERALLS_UPLOAD=ON -DTEST_POSTGRES_DBNAME=travis_ci_test -DTEST_POSTGRES_DBUSER=postgres -DTEST_MYSQL_DBNAME=travis_ci_test -DTEST_MYSQL_DBUSER=root .. 38 | 39 | script: 40 | - sqlite3 -version 41 | - make VERBOSE=1 42 | - make test 43 | - cat Testing/Temporary/LastTest.log 44 | - make package 45 | - sudo dpkg -i metacpp-0.3.0-Linux.deb 46 | - make coveralls 47 | -------------------------------------------------------------------------------- /src/utils/Array.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #include "Array.h" -------------------------------------------------------------------------------- /src/utils/SharedDataPointer.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #include "SharedDataPointer.h" 17 | -------------------------------------------------------------------------------- /src/scripting/ScriptProgramBase.cpp: -------------------------------------------------------------------------------- 1 | #include "ScriptProgramBase.h" 2 | #include 3 | #include 4 | 5 | namespace metacpp { 6 | namespace scripting { 7 | 8 | ScriptProgramBase::ScriptProgramBase() { 9 | } 10 | 11 | ScriptProgramBase::~ScriptProgramBase() { 12 | } 13 | 14 | SharedObjectPointer ScriptProgramBase::createThread(const String &functionName, const VariantArray &args) 15 | { 16 | auto deleter = [this](ScriptThreadBase *thread) { closeThreadImpl(thread); }; 17 | return SharedObjectPointer(createThreadImpl(functionName, args), deleter); 18 | } 19 | 20 | void ScriptProgramBase::compile(std::istream &is, const String &filename) 21 | { 22 | is.seekg (0, is.end); 23 | size_t length = is.tellg(); 24 | is.seekg (0, is.beg); 25 | Array buffer; 26 | buffer.resize(length); 27 | is.read(buffer.data(), buffer.size()); 28 | compile(buffer.data(), buffer.size(), filename); 29 | } 30 | 31 | void ScriptProgramBase::compile(const String& sourceFile) { 32 | std::ifstream is(sourceFile.c_str(), std::ios_base::binary | std::ios_base::in); 33 | is.exceptions ( std::ifstream::failbit | std::ifstream::badbit ); 34 | return compile(is, sourceFile); 35 | } 36 | 37 | } // namespace scripting 38 | } // namespace metacpp 39 | -------------------------------------------------------------------------------- /test/StringTest.h: -------------------------------------------------------------------------------- 1 | #ifndef STRINGTEST_H 2 | #define STRINGTEST_H 3 | #include "StringBase.h" 4 | #include 5 | 6 | class StringTest : public testing::Test 7 | { 8 | public: 9 | void testNull(); 10 | void testDetach(); 11 | void testStl(); 12 | void testAppend(const char *a, const char *b, const char *result); 13 | void testArrayOfStrings(); 14 | void testFindSubstr(); 15 | void testSubStr2(); 16 | void testStringBuilder(); 17 | void testAssign(const char *v); 18 | int testToValue(const metacpp::String &s); 19 | void testStreams(); 20 | void testJoin(); 21 | void testReplace(const metacpp::String& inStr, const metacpp::String& from, const metacpp::String& to, const metacpp::String& outStr); 22 | void testUri(const metacpp::String &uri, const metacpp::String& schema, const metacpp::String& hierarchy, 23 | const std::initializer_list >& params = std::initializer_list >(), 24 | const metacpp::String& host = metacpp::String(), const metacpp::String& port = metacpp::String(), const metacpp::String& path = metacpp::String(), 25 | const metacpp::String& username = metacpp::String(), const metacpp::String& password = metacpp::String()); 26 | }; 27 | #endif // STRINGTEST_H 28 | -------------------------------------------------------------------------------- /src/db/ExpressionAssignment.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #include "ExpressionAssignment.h" 17 | 18 | namespace metacpp { 19 | namespace db { 20 | 21 | 22 | } // namespace db 23 | } // namespace metacpp 24 | 25 | -------------------------------------------------------------------------------- /cmake/Modules/CMakeFindFrameworks.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # CMakeFindFrameworks 3 | # ------------------- 4 | # 5 | # helper module to find OSX frameworks 6 | 7 | #============================================================================= 8 | # Copyright 2003-2009 Kitware, Inc. 9 | # 10 | # Distributed under the OSI-approved BSD License (the "License"); 11 | # see accompanying file Copyright.txt for details. 12 | # 13 | # This software is distributed WITHOUT ANY WARRANTY; without even the 14 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 15 | # See the License for more information. 16 | #============================================================================= 17 | # (To distribute this file outside of CMake, substitute the full 18 | # License text for the above reference.) 19 | 20 | if(NOT CMAKE_FIND_FRAMEWORKS_INCLUDED) 21 | set(CMAKE_FIND_FRAMEWORKS_INCLUDED 1) 22 | macro(CMAKE_FIND_FRAMEWORKS fwk) 23 | set(${fwk}_FRAMEWORKS) 24 | if(APPLE) 25 | foreach(dir 26 | ~/Library/Frameworks/${fwk}.framework 27 | /Library/Frameworks/${fwk}.framework 28 | /System/Library/Frameworks/${fwk}.framework 29 | /Network/Library/Frameworks/${fwk}.framework) 30 | if(EXISTS ${dir}) 31 | set(${fwk}_FRAMEWORKS ${${fwk}_FRAMEWORKS} ${dir}) 32 | endif() 33 | endforeach() 34 | endif() 35 | endmacro() 36 | endif() 37 | -------------------------------------------------------------------------------- /cmake/Modules/FindJsonCpp.cmake: -------------------------------------------------------------------------------- 1 | # JSONCPP_FOUND - system has a sqlite3 2 | # JSONCPP_INCLUDE_DIR - where to find header files 3 | # JSONCPP_LIBRARIES - the libraries to link against 4 | 5 | FIND_PATH( 6 | JSONCPP_INCLUDE_DIR 7 | json/json.h 8 | /usr/include 9 | /usr/include/jsoncpp 10 | /usr/local/include 11 | ${JSONCPP_PATH_INCLUDES} 12 | ) 13 | 14 | FIND_LIBRARY( 15 | JSONCPP_LIBRARIES 16 | NAMES 17 | jsoncpp 18 | PATHS 19 | /usr/lib 20 | /usr/local/lib 21 | ${JSONCPP_PATH_LIB} 22 | ) 23 | 24 | IF (JSONCPP_LIBRARIES AND JSONCPP_INCLUDE_DIR) 25 | SET(JSONCPP_FOUND "YES") 26 | ENDIF (JSONCPP_LIBRARIES AND JSONCPP_INCLUDE_DIR) 27 | 28 | IF (JSONCPP_FOUND) 29 | MESSAGE(STATUS "Found JsonCpp: ${JSONCPP_LIBRARIES}") 30 | MESSAGE(STATUS " include: ${JSONCPP_INCLUDE_DIR}") 31 | ELSE (JSONCPP_FOUND) 32 | MESSAGE(STATUS "JsonCpp not found.") 33 | MESSAGE(STATUS "JsonCpp: You can specify includes: -DJSONCPP_PATH_INCLUDES=/opt/include/jsoncpp") 34 | MESSAGE(STATUS " currently found includes: ${JSONCPP_INCLUDE_DIR}") 35 | MESSAGE(STATUS "JsonCpp: You can specify libs: -DJSONCPP_PATH_LIB=/opt/jsoncpp/lib") 36 | MESSAGE(STATUS " currently found libs: ${JSONCPP_LIBRARIES}") 37 | IF (JsonCpp_FIND_REQUIRED) 38 | MESSAGE(FATAL_ERROR "Could not find JsonCpp library") 39 | ENDIF (JsonCpp_FIND_REQUIRED) 40 | ENDIF (JSONCPP_FOUND) 41 | -------------------------------------------------------------------------------- /src/scripting/ScriptProgramBase.h: -------------------------------------------------------------------------------- 1 | #ifndef SCRIPTPROGRAMBASE_H 2 | #define SCRIPTPROGRAMBASE_H 3 | #include "config.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace metacpp { 10 | namespace scripting { 11 | 12 | class ScriptThreadBase; 13 | 14 | class ScriptProgramBase { 15 | public: 16 | ScriptProgramBase(); 17 | virtual ~ScriptProgramBase(); 18 | 19 | SharedObjectPointer createThread(const String& functionName = String(), 20 | const VariantArray& args = VariantArray()); 21 | 22 | template 23 | SharedObjectPointer createThread(const String& functionName, 24 | TArgs... args) 25 | { 26 | return createThread(functionName, {args...}); 27 | } 28 | 29 | public: 30 | virtual void compile(std::istream& is, const String& filename); 31 | 32 | virtual void compile(const String& sourceFile); 33 | virtual void compile(const void *pBuffer, size_t size, const String& fileName) = 0; 34 | protected: 35 | virtual ScriptThreadBase *createThreadImpl(const String& functionName, 36 | const VariantArray& args = VariantArray()) = 0; 37 | virtual void closeThreadImpl(ScriptThreadBase *thread) = 0; 38 | 39 | }; 40 | 41 | } // namespace scripting 42 | } // namespace metacpp 43 | 44 | #endif // SCRIPTPROGRAMBASE_H 45 | -------------------------------------------------------------------------------- /src/utils/Utils.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef UTILS_H 17 | #define UTILS_H 18 | 19 | namespace metacpp 20 | { 21 | 22 | /** \brief Base class for factories */ 23 | template 24 | struct FactoryBase 25 | { 26 | virtual TBaseEntityPtr createInstance(Args... args) = 0; 27 | }; 28 | 29 | } // namespace metacpp 30 | 31 | #endif // UTILS_H 32 | 33 | -------------------------------------------------------------------------------- /src/scripting/ScriptEngineBase.h: -------------------------------------------------------------------------------- 1 | #ifndef SCRIPTENGINEBASE_H 2 | #define SCRIPTENGINEBASE_H 3 | #include "config.h" 4 | #include "ScriptProgramBase.h" 5 | #include 6 | #include 7 | 8 | #ifdef _MSC_VER 9 | #undef _NOEXCEPT 10 | #define _NOEXCEPT 11 | #else 12 | #define _NOEXCEPT noexcept 13 | #endif 14 | 15 | namespace metacpp { 16 | namespace scripting { 17 | 18 | class ScriptRuntimeError 19 | : public std::exception 20 | { 21 | public: 22 | ScriptRuntimeError(const char *message, const char *filename, 23 | uint32_t line, uint32_t column); 24 | 25 | const char *what() const _NOEXCEPT override; 26 | private: 27 | String m_what; 28 | }; 29 | 30 | /** \brief Base class for all script engine VMs */ 31 | class ScriptEngineBase { 32 | public: 33 | ScriptEngineBase(); 34 | virtual ~ScriptEngineBase(); 35 | 36 | SharedObjectPointer createProgram(); 37 | 38 | void registerClass(const MetaObject *metaObject); 39 | 40 | Array registeredClasses() const; 41 | protected: 42 | 43 | /** \brief Create a new instance of ScriptProgramBase corresponding to this type of VM */ 44 | virtual ScriptProgramBase *createProgramImpl() = 0; 45 | /** \brief Finalize and destroy ScriptProgramBase previously created by createProgram */ 46 | virtual void closeProgramImpl(ScriptProgramBase *program) = 0; 47 | private: 48 | Array m_registeredClasses; 49 | }; 50 | 51 | } // namespace scripting 52 | } // namespace metacpp 53 | 54 | #endif // SCRIPTENGINEBASE_H 55 | -------------------------------------------------------------------------------- /src/db/sql/connectors/SqlTransactionImpl.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #include "SqlTransactionImpl.h" 17 | 18 | namespace metacpp 19 | { 20 | namespace db 21 | { 22 | namespace sql 23 | { 24 | namespace connectors 25 | { 26 | 27 | SqlTransactionImpl::SqlTransactionImpl() 28 | { 29 | 30 | } 31 | 32 | SqlTransactionImpl::~SqlTransactionImpl() 33 | { 34 | 35 | } 36 | 37 | } // namespace connectors 38 | } // namespace sql 39 | } // namespace db 40 | } // namespace metacpp 41 | -------------------------------------------------------------------------------- /src/utils/SharedDataBase.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #include "SharedDataBase.h" 17 | #include 18 | 19 | namespace metacpp 20 | { 21 | 22 | SharedDataBase::SharedDataBase() 23 | : m_count(1) 24 | { 25 | } 26 | 27 | SharedDataBase::~SharedDataBase() 28 | { 29 | assert(0 == m_count); 30 | } 31 | 32 | int SharedDataBase::ref() const 33 | { 34 | return ++m_count; 35 | } 36 | 37 | int SharedDataBase::deref() const 38 | { 39 | return --m_count; 40 | } 41 | 42 | int SharedDataBase::count() const 43 | { 44 | return m_count.load(); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /cmake/Modules/FindIconv.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find Iconv 2 | # Once done this will define 3 | # 4 | # ICONV_FOUND - system has Iconv 5 | # ICONV_INCLUDE_DIR - the Iconv include directory 6 | # ICONV_LIBRARIES - Link these to use Iconv 7 | # ICONV_SECOND_ARGUMENT_IS_CONST - the second argument for iconv() is const 8 | # 9 | include(CheckCXXSourceCompiles) 10 | 11 | IF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) 12 | # Already in cache, be silent 13 | SET(ICONV_FIND_QUIETLY TRUE) 14 | ENDIF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) 15 | 16 | FIND_PATH(ICONV_INCLUDE_DIR iconv.h) 17 | 18 | FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv libiconv-2 c) 19 | 20 | IF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) 21 | SET(ICONV_FOUND TRUE) 22 | ENDIF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) 23 | 24 | set(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR}) 25 | set(CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARIES}) 26 | IF(ICONV_FOUND) 27 | check_cxx_source_compiles(" 28 | #include 29 | int main(){ 30 | iconv_t conv = 0; 31 | const char* in = 0; 32 | size_t ilen = 0; 33 | char* out = 0; 34 | size_t olen = 0; 35 | iconv(conv, &in, &ilen, &out, &olen); 36 | return 0; 37 | } 38 | " ICONV_SECOND_ARGUMENT_IS_CONST ) 39 | ENDIF(ICONV_FOUND) 40 | set(CMAKE_REQUIRED_INCLUDES) 41 | set(CMAKE_REQUIRED_LIBRARIES) 42 | 43 | IF(ICONV_FOUND) 44 | IF(NOT ICONV_FIND_QUIETLY) 45 | MESSAGE(STATUS "Found Iconv: ${ICONV_LIBRARIES}") 46 | ENDIF(NOT ICONV_FIND_QUIETLY) 47 | ELSE(ICONV_FOUND) 48 | IF(Iconv_FIND_REQUIRED) 49 | MESSAGE(FATAL_ERROR "Could not find Iconv") 50 | ENDIF(Iconv_FIND_REQUIRED) 51 | ENDIF(ICONV_FOUND) 52 | 53 | MARK_AS_ADVANCED( 54 | ICONV_INCLUDE_DIR 55 | ICONV_LIBRARIES 56 | ICONV_SECOND_ARGUMENT_IS_CONST 57 | ) 58 | -------------------------------------------------------------------------------- /src/core/InitVisitor.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef INITVISITOR_H 17 | #define INITVISITOR_H 18 | #include "config.h" 19 | #include "VisitorBase.h" 20 | 21 | namespace metacpp 22 | { 23 | 24 | /** \brief Visitor used for initialization of object using common introspection mechanism */ 25 | class InitVisitor : 26 | public VisitorBase 27 | { 28 | public: 29 | /** \brief Constructs a new instance of InitVisitor */ 30 | InitVisitor(); 31 | ~InitVisitor(void); 32 | 33 | /** \brief Overrides metacpp::VisitorBase::visitField */ 34 | void visitField(Object *obj, const MetaFieldBase *field) override; 35 | }; 36 | 37 | } // namespace metacpp 38 | 39 | #endif // INITVISITOR_H 40 | -------------------------------------------------------------------------------- /src/core/VisitorBase.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #include "VisitorBase.h" 17 | #include "Object.h" 18 | 19 | namespace metacpp 20 | { 21 | 22 | VisitorBase::VisitorBase() 23 | { 24 | } 25 | 26 | VisitorBase::~VisitorBase(void) 27 | { 28 | } 29 | 30 | void VisitorBase::previsitStruct(Object *obj) 31 | { 32 | (void)obj; 33 | } 34 | 35 | void VisitorBase::postvisitStruct(Object *obj) 36 | { 37 | (void)obj; 38 | } 39 | 40 | void VisitorBase::visit(Object *obj) 41 | { 42 | previsitStruct(obj); 43 | for (size_t i = 0; i < obj->metaObject()->totalFields(); ++i) 44 | visitField(obj, obj->metaObject()->field(i)); 45 | postvisitStruct(obj); 46 | } 47 | 48 | } // namespace metacpp 49 | -------------------------------------------------------------------------------- /cmake/Modules/FindMongoDB.cmake: -------------------------------------------------------------------------------- 1 | # Find the MongoDB includes and client library 2 | # This module defines 3 | # MongoDB_INCLUDE_DIR, where to find mongo/client/dbclient.h 4 | # MongoDB_LIBRARIES, the libraries needed to use MongoDB. 5 | # MongoDB_FOUND, If false, do not try to use MongoDB. 6 | 7 | SET(MongoDB_PossibleIncludePaths 8 | "/usr/include/" 9 | "/usr/local/include/" 10 | "/usr/include/mongo/" 11 | "/usr/local/include/mongo/" 12 | "/opt/mongo/include/" 13 | "$ENV{ProgramFiles}/Mongo/*/include" 14 | "$ENV{SystemDrive}/Mongo/*/include" 15 | ) 16 | 17 | FIND_PATH(MongoDB_INCLUDE_DIR "mongo/client/dbclient.h" 18 | ${MongoDB_PossibleIncludePaths}) 19 | 20 | IF(WIN32) 21 | FIND_LIBRARY(MongoDB_LIBRARIES NAMES mongoclient 22 | PATHS 23 | "$ENV{ProgramFiles}/Mongo/*/lib" 24 | "$ENV{SystemDrive}/Mongo/*/lib" 25 | ) 26 | ELSE(WIN32) 27 | FIND_LIBRARY(MongoDB_LIBRARIES NAMES mongoclient 28 | PATHS 29 | "/usr/lib" 30 | "/usr/lib64" 31 | "/usr/lib/mongo" 32 | "/usr/lib64/mongo" 33 | "/usr/local/lib" 34 | "/usr/local/lib64" 35 | "/usr/local/lib/mongo" 36 | "/usr/local/lib64/mongo" 37 | "/opt/mongo/lib" 38 | "/opt/mongo/lib64" 39 | ) 40 | ENDIF(WIN32) 41 | 42 | IF(MongoDB_INCLUDE_DIR AND MongoDB_LIBRARIES) 43 | SET(MongoDB_FOUND TRUE) 44 | MESSAGE(STATUS "Found MongoDB: ${MongoDB_INCLUDE_DIR}, ${MongoDB_LIBRARIES}") 45 | MESSAGE(STATUS "MongoDB using new interface: ${MongoDB_EXPOSE_MACROS}") 46 | ELSE(MongoDB_INCLUDE_DIR AND MongoDB_LIBRARIES) 47 | SET(MongoDB_FOUND FALSE) 48 | IF(MongoDB_FIND_REQUIRED) 49 | message(FATAL_ERROR "MongoDB not found.") 50 | ELSE(MongoDB_FIND_REQUIRED) 51 | message(STATUS "MongoDB not found.") 52 | ENDIF(MongoDB_FIND_REQUIRED) 53 | ENDIF(MongoDB_INCLUDE_DIR AND MongoDB_LIBRARIES) 54 | 55 | MARK_AS_ADVANCED(MongoDB_INCLUDE_DIR MongoDB_LIBRARIES) 56 | -------------------------------------------------------------------------------- /src/db/sql/connectors/sqlite3/SqliteStatementImpl.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef SQLITESTATEMENT_H 17 | #define SQLITESTATEMENT_H 18 | #include "SqlStatementImpl.h" 19 | #include 20 | 21 | namespace metacpp 22 | { 23 | namespace db 24 | { 25 | namespace sql 26 | { 27 | namespace connectors 28 | { 29 | namespace sqlite 30 | { 31 | 32 | class SqliteStatementImpl : public SqlStatementImpl 33 | { 34 | public: 35 | SqliteStatementImpl(SqlStatementType type, const String& queryText); 36 | ~SqliteStatementImpl(); 37 | 38 | sqlite3_stmt *handle() const; 39 | void setHandle(sqlite3_stmt *handle); 40 | private: 41 | sqlite3_stmt *m_stmt; 42 | }; 43 | 44 | } // namespace sqlite 45 | } // namespace connectors 46 | } // namespace sql 47 | } // namespace db 48 | } // namespace metacpp 49 | 50 | #endif // SQLITESTATEMENT_H 51 | -------------------------------------------------------------------------------- /src/db/sql/connectors/sqlite3/SqliteStatementImpl.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #include "SqliteStatementImpl.h" 17 | 18 | namespace metacpp 19 | { 20 | namespace db 21 | { 22 | namespace sql 23 | { 24 | namespace connectors 25 | { 26 | namespace sqlite 27 | { 28 | 29 | SqliteStatementImpl::SqliteStatementImpl(SqlStatementType type, const String &queryText) 30 | : SqlStatementImpl(type, queryText), m_stmt(nullptr) 31 | { 32 | } 33 | 34 | SqliteStatementImpl::~SqliteStatementImpl() 35 | { 36 | if (m_stmt && prepared()) sqlite3_finalize(m_stmt); 37 | } 38 | 39 | sqlite3_stmt *SqliteStatementImpl::handle() const 40 | { 41 | return m_stmt; 42 | } 43 | 44 | void SqliteStatementImpl::setHandle(sqlite3_stmt *handle) 45 | { 46 | m_stmt = handle; 47 | setPrepared(m_stmt != nullptr); 48 | } 49 | 50 | } // namespace sqlite 51 | } // namespace connectors 52 | } // namespace sql 53 | } // namespace db 54 | } // namespace metacpp 55 | -------------------------------------------------------------------------------- /cmake/Modules/FindSpiderMonkey.cmake: -------------------------------------------------------------------------------- 1 | # Find the javascript header files and libraries 2 | # Once done this will define 3 | # 4 | # SPIDERMONKEY_INCLUDE_DIR - where to find jsapi.h, etc. 5 | # SPIDERMONKEY_LIBRARIES - SpiderMonkey libraries to link against 6 | # SPIDERMONKEY_FOUND - True if SpiderMonkey found. 7 | # SPIDERMONKEY_VERSION - version string of the found library 8 | # 9 | 10 | SET(SPIDERMONKEY_PossibleIncludePaths 11 | "/usr/include/" 12 | "/usr/local/include/" 13 | ) 14 | 15 | find_path(SPIDERMONKEY_INCLUDE_DIR 16 | NAMES jsapi.h 17 | PATHS 18 | ${SPIDERMONKEY_PossibleIncludePaths} 19 | PATH_SUFFIXES 20 | mozjs-38 mozjs-31 mozjs-24 21 | ) 22 | 23 | string(REGEX REPLACE "^.*mozjs-([0-9]+).*" "\\1" SPIDERMONKEY_VERSION ${SPIDERMONKEY_INCLUDE_DIR}) 24 | 25 | find_library( 26 | SPIDERMONKEY_BASE_LIBRARY 27 | NAMES mozjs-${SPIDERMONKEY_VERSION}) 28 | 29 | set(SPIDERMONKEY_LIBRARIES ${SPIDERMONKEY_BASE_LIBRARY}) 30 | set(CMAKE_REQUIRED_INCLUDES ${SPIDERMONKEY_INCLUDE_DIR}) 31 | set(CMAKE_REQUIRED_DEFINITIONS ${SPIDERMONKEY_DEFINITIONS}) 32 | list(APPEND CMAKE_REQUIRED_LIBRARIES ${SPIDERMONKEY_LIBRARIES}) 33 | 34 | list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES ${SPIDERMONKEY_LIBRARIES}) 35 | list(REMOVE_DUPLICATES CMAKE_REQUIRED_LIBRARIES) 36 | 37 | if (SPIDERMONKEY_INCLUDE_DIR AND SPIDERMONKEY_BASE_LIBRARY) 38 | set(SPIDERMONKEY_FOUND TRUE) 39 | message(STATUS "Found SpiderMonkey: ${SPIDERMONKEY_LIBRARIES}") 40 | message(STATUS " version: ${SPIDERMONKEY_VERSION}") 41 | message(STATUS " include: ${SPIDERMONKEY_INCLUDE_DIR}") 42 | else(SPIDERMONKEY_INCLUDE_DIR AND SPIDERMONKEY_BASE_LIBRARY) 43 | set(SPIDERMONKEY_FOUND FALSE) 44 | if(SPIDERMONKEY_FIND_REQUIRED) 45 | message(FATAL_ERROR "SpiderMonkey not found.") 46 | else(SPIDERMONKEY_FIND_REQUIRED) 47 | message(STATUS "SpiderMonkey not found.") 48 | endif(SPIDERMONKEY_FIND_REQUIRED) 49 | endif(SPIDERMONKEY_INCLUDE_DIR AND SPIDERMONKEY_BASE_LIBRARY) 50 | 51 | mark_as_advanced(SPIDERMONKEY_INCLUDE_DIR SPIDERMONKEY_LIBRARIES SPIDERMONKEY_BASE_LIBRARY SPIDERMONKEY_VERSION) 52 | -------------------------------------------------------------------------------- /src/core/VisitorBase.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef VISITOR_BASE_H 17 | #define VISITOR_BASE_H 18 | #include "config.h" 19 | //#include "Object.h" 20 | 21 | namespace metacpp 22 | { 23 | 24 | class Object; 25 | class MetaFieldBase; 26 | 27 | /** \brief Base class for visitors used for object introspection */ 28 | class VisitorBase 29 | { 30 | public: 31 | /** \brief Constructs a new instance of the VisitorBase */ 32 | VisitorBase(); 33 | virtual ~VisitorBase(void); 34 | /** \brief Introspects object using this visitor */ 35 | void visit(Object *object); 36 | protected: 37 | /** \brief Method called before starting introspection */ 38 | virtual void previsitStruct(Object *obj); 39 | /** \brief Method called on each property of the object during introspection */ 40 | virtual void visitField(Object *obj, const MetaFieldBase *) = 0; 41 | /** \brief Method called at the end of introspection */ 42 | virtual void postvisitStruct(Object *obj); 43 | }; 44 | 45 | } // namespace metacpp 46 | #endif // VISITOR_BASE_H 47 | -------------------------------------------------------------------------------- /cmake/Modules/FindPackageMessage.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # FindPackageMessage 3 | # ------------------ 4 | # 5 | # 6 | # 7 | # FIND_PACKAGE_MESSAGE( "message for user" "find result details") 8 | # 9 | # This macro is intended to be used in FindXXX.cmake modules files. It 10 | # will print a message once for each unique find result. This is useful 11 | # for telling the user where a package was found. The first argument 12 | # specifies the name (XXX) of the package. The second argument 13 | # specifies the message to display. The third argument lists details 14 | # about the find result so that if they change the message will be 15 | # displayed again. The macro also obeys the QUIET argument to the 16 | # find_package command. 17 | # 18 | # Example: 19 | # 20 | # :: 21 | # 22 | # if(X11_FOUND) 23 | # FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}" 24 | # "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") 25 | # else() 26 | # ... 27 | # endif() 28 | 29 | #============================================================================= 30 | # Copyright 2008-2009 Kitware, Inc. 31 | # 32 | # Distributed under the OSI-approved BSD License (the "License"); 33 | # see accompanying file Copyright.txt for details. 34 | # 35 | # This software is distributed WITHOUT ANY WARRANTY; without even the 36 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 37 | # See the License for more information. 38 | #============================================================================= 39 | # (To distribute this file outside of CMake, substitute the full 40 | # License text for the above reference.) 41 | 42 | function(FIND_PACKAGE_MESSAGE pkg msg details) 43 | # Avoid printing a message repeatedly for the same find result. 44 | if(NOT ${pkg}_FIND_QUIETLY) 45 | string(REGEX REPLACE "[\n]" "" details "${details}") 46 | set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg}) 47 | if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}") 48 | # The message has not yet been printed. 49 | message(STATUS "${msg}") 50 | 51 | # Save the find details in the cache to avoid printing the same 52 | # message again. 53 | set("${DETAILS_VAR}" "${details}" 54 | CACHE INTERNAL "Details about finding ${pkg}") 55 | endif() 56 | endif() 57 | endfunction() 58 | -------------------------------------------------------------------------------- /src/db/sql/connectors/SqlStatementImpl.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #include "SqlStatementImpl.h" 17 | 18 | namespace metacpp 19 | { 20 | namespace db 21 | { 22 | namespace sql 23 | { 24 | namespace connectors 25 | { 26 | 27 | 28 | SqlStatementImpl::SqlStatementImpl(SqlStatementType type, const String& queryText) 29 | : m_prepared(false), m_queryText(queryText), m_type(type), m_done(false) 30 | { 31 | 32 | } 33 | 34 | SqlStatementImpl::~SqlStatementImpl() 35 | { 36 | 37 | } 38 | 39 | SqlStatementType SqlStatementImpl::type() const 40 | { 41 | return m_type; 42 | } 43 | 44 | bool SqlStatementImpl::prepared() const 45 | { 46 | return m_prepared; 47 | } 48 | 49 | void SqlStatementImpl::setPrepared(bool val) 50 | { 51 | m_prepared = val; 52 | } 53 | 54 | bool SqlStatementImpl::done() const 55 | { 56 | return m_done; 57 | } 58 | 59 | void SqlStatementImpl::setDone(bool val) 60 | { 61 | m_done = val; 62 | } 63 | 64 | const String& SqlStatementImpl::queryText() const 65 | { 66 | return m_queryText; 67 | } 68 | 69 | } // namespace connectors 70 | } // namespace sql 71 | } // namespace db 72 | } // namespace metacpp 73 | -------------------------------------------------------------------------------- /src/scripting/ScriptThreadBase.h: -------------------------------------------------------------------------------- 1 | #ifndef SCRIPTTHREADBASE_H 2 | #define SCRIPTTHREADBASE_H 3 | #include "config.h" 4 | #include "ScriptProgramBase.h" 5 | #include 6 | 7 | namespace metacpp { 8 | namespace scripting { 9 | 10 | #ifdef _MSC_VER 11 | #undef _NOEXCEPT 12 | #define _NOEXCEPT 13 | #else 14 | #define _NOEXCEPT noexcept 15 | #endif 16 | 17 | /** An exception indicating that the script execution being terminated with 18 | * ScriptThreadBase::abort */ 19 | class TerminationException : public std::exception 20 | { 21 | public: 22 | const char *what() const _NOEXCEPT override; 23 | }; 24 | 25 | /** \brief Basic class providing execution methods and context */ 26 | class ScriptThreadBase { 27 | public: 28 | ScriptThreadBase(); 29 | virtual ~ScriptThreadBase(); 30 | 31 | /** \brief Check whether this thread is currently running */ 32 | virtual bool running() const = 0; 33 | /** \brief If supported, enters state signaling thread termination 34 | * and waits for it to finish for the given amount of millisiconds 35 | * \arg timeout_ms wait timeout in milliseconds, 0 for unlimited wait 36 | * \returns true if thread successfully finished or terminated or thread is not currently running, 37 | * false if operations is not supported or timed out 38 | */ 39 | virtual bool abort(unsigned timeout_ms = 0) = 0; 40 | /** \brief If script is currently running wait for it to finish for the given amount of time 41 | * \arg timeout_ms wait timeout in milliseconds, 0 for unlimited wait 42 | * \returns true if successfully joined with running thread or thread is not running, 43 | * false if operation is not supported or timed out 44 | */ 45 | virtual bool wait(unsigned timeout_ms = 0) = 0; 46 | 47 | /** \brief Executes given script thread */ 48 | virtual Variant run() = 0; 49 | 50 | // TODO: Implement worker pool? 51 | /** \brief Executes given script in a separate newly spawned thread and calls 52 | * given callbacks upon execution finish or error */ 53 | bool runAsync(const std::function& onFinished, 54 | const std::function& onError); 55 | }; 56 | 57 | } // namespace scripting 58 | } // namespace metacpp 59 | 60 | #endif // SCRIPTTHREADBASE_H 61 | -------------------------------------------------------------------------------- /src/db/sql/connectors/mysql/MySqlStatementImpl.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef MYSQLSTATEMENTIMPL_H 17 | #define MYSQLSTATEMENTIMPL_H 18 | #include "SqlStatementImpl.h" 19 | #include 20 | 21 | namespace metacpp { 22 | namespace db { 23 | namespace sql { 24 | namespace connectors { 25 | namespace mysql { 26 | 27 | class MySqlStatementImpl : public SqlStatementImpl 28 | { 29 | public: 30 | MySqlStatementImpl(MYSQL_STMT *stmt, SqlStatementType type, const String& queryText); 31 | ~MySqlStatementImpl(); 32 | 33 | MYSQL_STMT *getStmt() const; 34 | MYSQL_RES *getResult() const; 35 | void setResult(MYSQL_RES *result); 36 | bool getExecuted() const; 37 | void setExecuted(bool val = true); 38 | /** Stores bind data which will receive field requirements on the next fetched row */ 39 | void prefetch(); 40 | MYSQL_BIND *bindResult(size_t nField); 41 | private: 42 | MYSQL_STMT *m_stmt; 43 | MYSQL_RES *m_result; 44 | Array m_bindResult; 45 | bool m_executed; 46 | }; 47 | 48 | } // namespace mysql 49 | } // namespace connectors 50 | } // namespace sql 51 | } // namespace db 52 | } // namespace metacpp 53 | 54 | #endif // MYSQLSTATEMENTIMPL_H 55 | -------------------------------------------------------------------------------- /src/db/sql/connectors/postgres/PostgresStatementImpl.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef POSTGRESSTATEMENTIMPL_H 17 | #define POSTGRESSTATEMENTIMPL_H 18 | #include "SqlStatementImpl.h" 19 | #include 20 | #include 21 | 22 | namespace metacpp { 23 | namespace db { 24 | namespace sql { 25 | namespace connectors { 26 | namespace postgres { 27 | 28 | class PostgresStatementImpl : public SqlStatementImpl 29 | { 30 | public: 31 | PostgresStatementImpl(SqlStatementType type, const String& queryText); 32 | ~PostgresStatementImpl(); 33 | 34 | void setResult(PGresult *result, const String& idString); 35 | void setExecResult(PGresult *result); 36 | PGresult *getResult() const; 37 | PGresult *getExecResult() const; 38 | const String& getIdString() const; 39 | int currentRow() const; 40 | void setCurrentRow(int row); 41 | void bindValues(const VariantArray& values); 42 | const VariantArray& boundValues() const; 43 | private: 44 | VariantArray m_boundValues; 45 | PGresult *m_result, *m_execResult; 46 | String m_idString; 47 | int m_currentRow; 48 | }; 49 | 50 | } // namespace postgres 51 | } // namespace connectors 52 | } // namespace sql 53 | } // namespace db 54 | } // namespace metacpp 55 | 56 | #endif // POSTGRESSTATEMENTIMPL_H 57 | -------------------------------------------------------------------------------- /src/serialization/json/JsonDeserializerVisitor.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef JSONDESERIALIZERVISITOR_H 17 | #define JSONDESERIALIZERVISITOR_H 18 | #include "config.h" 19 | #include "VisitorBase.h" 20 | #include "MetaInfo.h" 21 | #include 22 | #include "TypeResolverFactory.h" 23 | 24 | namespace metacpp 25 | { 26 | namespace serialization 27 | { 28 | namespace json 29 | { 30 | 31 | /** \brief Visitor for json deserialization of objects */ 32 | class JsonDeserializerVisitor : 33 | public VisitorBase 34 | { 35 | public: 36 | /** \brief Constructs new instance of JsonDeserializerVisitor with a given value */ 37 | JsonDeserializerVisitor(const Json::Value& value, 38 | TypeResolverFactory *typeResolver = nullptr); 39 | ~JsonDeserializerVisitor(void); 40 | protected: 41 | /** \brief Overrides VisitorBase::visitField */ 42 | void visitField(Object *obj, const MetaFieldBase *desc) override; 43 | private: 44 | void parseValue(const Json::Value& val, EFieldType type, void *pValue, const MetaFieldBase *desc = nullptr); 45 | private: 46 | const Json::Value& m_value; 47 | TypeResolverFactory *m_typeResolver; 48 | }; 49 | 50 | } // namespace json 51 | } // namespace serialization 52 | } // namespace metacpp 53 | #endif // JSONDESERIALIZERVISITOR_H 54 | -------------------------------------------------------------------------------- /src/serialization/json/JsonSerializerVisitor.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef JSONSERIALIZERVISITOR_H 17 | #define JSONSERIALIZERVISITOR_H 18 | #include "config.h" 19 | #include "VisitorBase.h" 20 | #include "MetaInfo.h" 21 | #include 22 | 23 | namespace metacpp 24 | { 25 | class Object; 26 | 27 | namespace serialization 28 | { 29 | namespace json 30 | { 31 | 32 | /** \brief Visitor for json serialization of objects */ 33 | class JsonSerializerVisitor : 34 | public VisitorBase 35 | { 36 | public: 37 | /** \brief Constructs a new instance of JsonSerializerVisitor */ 38 | JsonSerializerVisitor(void); 39 | ~JsonSerializerVisitor(void); 40 | 41 | /** \brief Gets a value containing introspecting object */ 42 | const Json::Value& rootValue() const; 43 | protected: 44 | /** \brief Overrides VisitorBase::previsitStruct */ 45 | void previsitStruct(Object *obj) override; 46 | /** \brief Overrides VisitorBase::visitField */ 47 | void visitField(Object *obj, const MetaFieldBase *field) override; 48 | private: 49 | void appendSubValue(Json::Value& val, EFieldType type, const void *pValue, const MetaFieldBase *field = nullptr); 50 | private: 51 | Json::Value m_value; 52 | }; 53 | 54 | } // namespace json 55 | } // namespace serialization 56 | } // namespace metacpp 57 | #endif // JSONSERIALIZERVISITOR_H 58 | -------------------------------------------------------------------------------- /src/db/sql/SqlResultIterator.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #include "SqlResultIterator.h" 17 | #include "SqlResultSet.h" 18 | #include "SqlTransaction.h" 19 | 20 | namespace metacpp 21 | { 22 | namespace db 23 | { 24 | namespace sql 25 | { 26 | 27 | SqlResultIterator::SqlResultIterator(detail::SqlResultSetData *resultSet, int rowId) 28 | : m_resultSet(resultSet), m_rowId(rowId) 29 | { 30 | } 31 | 32 | SqlResultIterator::SqlResultIterator(const SqlResultIterator &other) 33 | { 34 | *this = other; 35 | } 36 | 37 | SqlResultIterator::~SqlResultIterator() 38 | { 39 | } 40 | 41 | SqlResultIterator &SqlResultIterator::operator=(const SqlResultIterator &rhs) 42 | { 43 | m_resultSet = rhs.m_resultSet; 44 | m_rowId = rhs.m_rowId; 45 | return *this; 46 | } 47 | 48 | bool SqlResultIterator::operator ==(const SqlResultIterator& rhs) 49 | { 50 | return m_resultSet == rhs.m_resultSet && m_rowId == rhs.m_rowId; 51 | } 52 | 53 | bool SqlResultIterator::operator !=(const SqlResultIterator& rhs) 54 | { 55 | return !(*this == rhs); 56 | } 57 | 58 | int SqlResultIterator::operator*() const 59 | { 60 | return m_rowId; 61 | } 62 | 63 | int SqlResultIterator::operator->() const 64 | { 65 | return m_rowId; 66 | } 67 | 68 | SqlResultIterator& SqlResultIterator::operator ++() 69 | { 70 | if (m_resultSet->moveIterator()) 71 | m_rowId++; 72 | else 73 | m_rowId = ROW_ID_PAST_THE_END; 74 | return *this; 75 | } 76 | 77 | } // namespace sql 78 | } // namespace db 79 | } // namespace metacpp 80 | -------------------------------------------------------------------------------- /src/db/sql/connectors/mysql/MySqlConnector.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef MYSQLCONNECTOR_H 17 | #define MYSQLCONNECTOR_H 18 | #include "SqlConnectorBase.h" 19 | #include 20 | #include 21 | #include "Array.h" 22 | #include "Uri.h" 23 | #include "MySqlTransactionImpl.h" 24 | #include 25 | 26 | namespace metacpp { 27 | namespace db { 28 | namespace sql { 29 | namespace connectors { 30 | namespace mysql { 31 | 32 | class MySqlConnector : public SqlConnectorBase 33 | { 34 | public: 35 | MySqlConnector(const Uri& connectionUri); 36 | ~MySqlConnector(); 37 | 38 | bool connect() override; 39 | bool disconnect() override; 40 | SqlTransactionImpl *createTransaction() override; 41 | bool closeTransaction(SqlTransactionImpl *transaction) override; 42 | SqlSyntax sqlSyntax() const override; 43 | void setConnectionPooling(size_t size); 44 | private: 45 | Uri m_connectionUri; 46 | size_t m_poolSize; 47 | Array m_freeDbHandles, m_usedDbHandles; 48 | std::mutex m_poolMutex; 49 | std::condition_variable m_dbHandleFreedEvent; 50 | bool m_connected; 51 | Array m_transactions; 52 | std::mutex m_transactionMutex; 53 | }; 54 | 55 | class MySqlConnectorFactory : public SqlConnectorFactory 56 | { 57 | std::unique_ptr createInstance(const Uri &uri); 58 | }; 59 | 60 | } // namespace mysql 61 | } // namespace connectors 62 | } // namespace sql 63 | } // namespace db 64 | } // namespace metacpp 65 | 66 | #endif // POSTGRESCONNECTOR_H 67 | -------------------------------------------------------------------------------- /src/db/sql/connectors/SqlStatementImpl.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef SQLSTATEMENTIMPL_H 17 | #define SQLSTATEMENTIMPL_H 18 | #include 19 | #include 20 | #include "StringBase.h" 21 | #include "Utils.h" 22 | #include "SqlStatement.h" 23 | 24 | namespace metacpp 25 | { 26 | namespace db 27 | { 28 | namespace sql 29 | { 30 | namespace connectors 31 | { 32 | 33 | /** \brief An abstract base class for statements 34 | * 35 | * This class should never be used directly 36 | */ 37 | class SqlStatementImpl 38 | { 39 | protected: 40 | SqlStatementImpl(SqlStatementType type, const String& queryText); 41 | public: 42 | SqlStatementImpl(const SqlStatementImpl&)=delete; 43 | virtual ~SqlStatementImpl(); 44 | 45 | /** \brief Get statement type */ 46 | virtual SqlStatementType type() const; 47 | /** \brief Check if statement is prepared */ 48 | virtual bool prepared() const; 49 | /** \brief Sets prepared flag */ 50 | virtual void setPrepared(bool val = true); 51 | /** \brief Check if we've done executing this statement (no more rows) */ 52 | virtual bool done() const; 53 | /** \brief Sets done flag */ 54 | virtual void setDone(bool val = true); 55 | /** \brief Gets sql query text of this statement */ 56 | virtual const String& queryText() const; 57 | private: 58 | bool m_prepared; 59 | String m_queryText; 60 | SqlStatementType m_type; 61 | bool m_done; 62 | }; 63 | 64 | } // namespace connectors 65 | } // namespace sql 66 | } // namespace db 67 | } // namespace metacpp 68 | 69 | #endif // SQLSTATEMENTIMPL_H 70 | 71 | -------------------------------------------------------------------------------- /src/db/sql/connectors/postgres/PostgresConnector.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef POSTGRESCONNECTOR_H 17 | #define POSTGRESCONNECTOR_H 18 | #include "SqlConnectorBase.h" 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include "Array.h" 24 | #include "PostgresTransactionImpl.h" 25 | 26 | namespace metacpp { 27 | namespace db { 28 | namespace sql { 29 | namespace connectors { 30 | namespace postgres { 31 | 32 | class PostgresConnector : public SqlConnectorBase 33 | { 34 | public: 35 | PostgresConnector(const String& connectionString); 36 | ~PostgresConnector(); 37 | 38 | bool connect() override; 39 | bool disconnect() override; 40 | SqlTransactionImpl *createTransaction() override; 41 | bool closeTransaction(SqlTransactionImpl *transaction) override; 42 | SqlSyntax sqlSyntax() const override; 43 | void setConnectionPooling(size_t size); 44 | private: 45 | String m_connectionString; 46 | size_t m_poolSize; 47 | Array m_freeDbHandles, m_usedDbHandles; 48 | std::mutex m_poolMutex; 49 | std::condition_variable m_dbHandleFreedEvent; 50 | bool m_connected; 51 | Array m_transactions; 52 | std::mutex m_transactionMutex; 53 | }; 54 | 55 | class PostgresConnectorFactory : public SqlConnectorFactory 56 | { 57 | std::unique_ptr createInstance(const Uri &uri); 58 | }; 59 | 60 | } // namespace postgres 61 | } // namespace connectors 62 | } // namespace sql 63 | } // namespace db 64 | } // namespace metacpp 65 | 66 | #endif // POSTGRESCONNECTOR_H 67 | -------------------------------------------------------------------------------- /src/db/sql/connectors/mysql/MySqlTransactionImpl.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef MYSQLTRANSACTIONIMPL_H 17 | #define MYSQLTRANSACTIONIMPL_H 18 | #include "SqlTransactionImpl.h" 19 | #include "MySqlStatementImpl.h" 20 | #include 21 | 22 | namespace metacpp { 23 | namespace db { 24 | namespace sql { 25 | namespace connectors { 26 | namespace mysql { 27 | 28 | class MySqlTransactionImpl : public SqlTransactionImpl 29 | { 30 | public: 31 | MySqlTransactionImpl(MYSQL *dbConn); 32 | ~MySqlTransactionImpl(); 33 | 34 | bool begin() override; 35 | bool commit() override; 36 | bool rollback() override; 37 | 38 | SqlStatementImpl *createStatement(SqlStatementType type, const String& queryText) override; 39 | bool prepare(SqlStatementImpl *statement, size_t numParams) override; 40 | bool bindValues(SqlStatementImpl *statement, const VariantArray &values) override; 41 | bool execStatement(SqlStatementImpl *statement, int *numRowsAffected = nullptr) override; 42 | bool fetchNext(SqlStatementImpl *statement, SqlStorable *storable) override; 43 | size_t size(SqlStatementImpl *statement) override; 44 | bool getLastInsertId(SqlStatementImpl *statement, SqlStorable *storable) override; 45 | bool closeStatement(SqlStatementImpl *statement) override; 46 | 47 | MYSQL *dbConn() const { return m_dbConn; } 48 | private: 49 | bool execCommand(const char *query, const char *invokeContext); 50 | private: 51 | MYSQL *m_dbConn; 52 | Array m_statements; 53 | std::mutex m_statementsMutex; 54 | }; 55 | 56 | } // namespace mysql 57 | } // namespace connectors 58 | } // namespace sql 59 | } // namespace db 60 | } // namespace metacpp 61 | 62 | #endif // MYSQLTRANSACTIONIMPL_H 63 | -------------------------------------------------------------------------------- /src/db/sql/connectors/sqlite3/SqliteTransactionImpl.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef SQLITETRANSACTIONIMPL_H 17 | #define SQLITETRANSACTIONIMPL_H 18 | #include "SqlTransactionImpl.h" 19 | #include "SqliteStatementImpl.h" 20 | #include "Array.h" 21 | #include 22 | #include 23 | 24 | namespace metacpp 25 | { 26 | namespace db 27 | { 28 | namespace sql 29 | { 30 | namespace connectors 31 | { 32 | namespace sqlite 33 | { 34 | 35 | class SqliteTransactionImpl : public SqlTransactionImpl 36 | { 37 | public: 38 | SqliteTransactionImpl(sqlite3 *dbHandle); 39 | ~SqliteTransactionImpl(); 40 | 41 | bool begin() override; 42 | bool commit() override; 43 | bool rollback() override; 44 | 45 | SqlStatementImpl *createStatement(SqlStatementType type, const String& queryText) override; 46 | bool prepare(SqlStatementImpl *statement, size_t numParams) override; 47 | bool bindValues(SqlStatementImpl *statement, const VariantArray &values) override; 48 | bool execStatement(SqlStatementImpl *statement, int *numRowsAffected = nullptr) override; 49 | bool fetchNext(SqlStatementImpl *statement, SqlStorable *storable) override; 50 | size_t size(SqlStatementImpl *statement) override; 51 | bool getLastInsertId(SqlStatementImpl *statement, SqlStorable *storable) override; 52 | bool closeStatement(SqlStatementImpl *statement) override; 53 | 54 | sqlite3 *dbHandle() const { return m_dbHandle; } 55 | private: 56 | sqlite3 *m_dbHandle; 57 | Array m_statements; 58 | std::mutex m_statementsMutex; 59 | }; 60 | 61 | } // namespace sqlite 62 | } // namespace connectors 63 | } // namespace sql 64 | } // namespace db 65 | } // namespace metacpp 66 | 67 | #endif // SQLITETRANSACTIONIMPL_H 68 | -------------------------------------------------------------------------------- /cmake/Modules/FindSqlite3.cmake: -------------------------------------------------------------------------------- 1 | # - find Sqlite 3 2 | # SQLITE3_INCLUDE_DIR - Where to find Sqlite 3 header files (directory) 3 | # SQLITE3_LIBRARIES - Sqlite 3 libraries 4 | # SQLITE3_LIBRARY_RELEASE - Where the release library is 5 | # SQLITE3_LIBRARY_DEBUG - Where the debug library is 6 | # SQLITE3_FOUND - Set to TRUE if we found everything (library, includes and executable) 7 | 8 | # Copyright (c) 2010 Pau Garcia i Quiles, 9 | # 10 | # Redistribution and use is allowed according to the terms of the BSD license. 11 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file. 12 | # 13 | # Generated by CModuler, a CMake Module Generator - http://gitorious.org/cmoduler 14 | 15 | IF( SQLITE3_INCLUDE_DIR AND SQLITE3_LIBRARY_RELEASE AND SQLITE3_LIBRARY_DEBUG ) 16 | SET(SQLITE3_FIND_QUIETLY TRUE) 17 | ENDIF( SQLITE3_INCLUDE_DIR AND SQLITE3_LIBRARY_RELEASE AND SQLITE3_LIBRARY_DEBUG ) 18 | 19 | FIND_PATH( SQLITE3_INCLUDE_DIR sqlite3.h ) 20 | 21 | FIND_LIBRARY(SQLITE3_LIBRARY_RELEASE NAMES sqlite3 ) 22 | 23 | FIND_LIBRARY(SQLITE3_LIBRARY_DEBUG NAMES sqlite3 sqlite3d HINTS /usr/lib/debug/usr/lib/ ) 24 | 25 | IF( SQLITE3_LIBRARY_RELEASE OR SQLITE3_LIBRARY_DEBUG AND SQLITE3_INCLUDE_DIR ) 26 | SET( SQLITE3_FOUND TRUE ) 27 | ENDIF( SQLITE3_LIBRARY_RELEASE OR SQLITE3_LIBRARY_DEBUG AND SQLITE3_INCLUDE_DIR ) 28 | 29 | IF( SQLITE3_LIBRARY_DEBUG AND SQLITE3_LIBRARY_RELEASE ) 30 | # if the generator supports configuration types then set 31 | # optimized and debug libraries, or if the CMAKE_BUILD_TYPE has a value 32 | IF( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE ) 33 | SET( SQLITE3_LIBRARIES optimized ${SQLITE3_LIBRARY_RELEASE} debug ${SQLITE3_LIBRARY_DEBUG} ) 34 | ELSE( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE ) 35 | # if there are no configuration types and CMAKE_BUILD_TYPE has no value 36 | # then just use the release libraries 37 | SET( SQLITE3_LIBRARIES ${SQLITE3_LIBRARY_RELEASE} ) 38 | ENDIF( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE ) 39 | ELSEIF( SQLITE3_LIBRARY_RELEASE ) 40 | SET( SQLITE3_LIBRARIES ${SQLITE3_LIBRARY_RELEASE} ) 41 | ELSE( SQLITE3_LIBRARY_DEBUG AND SQLITE3_LIBRARY_RELEASE ) 42 | SET( SQLITE3_LIBRARIES ${SQLITE3_LIBRARY_DEBUG} ) 43 | ENDIF( SQLITE3_LIBRARY_DEBUG AND SQLITE3_LIBRARY_RELEASE ) 44 | 45 | IF( SQLITE3_FOUND ) 46 | IF( NOT SQLITE3_FIND_QUIETLY ) 47 | MESSAGE( STATUS "Found Sqlite3 header file in ${SQLITE3_INCLUDE_DIR}") 48 | MESSAGE( STATUS "Found Sqlite3 libraries: ${SQLITE3_LIBRARIES}") 49 | ENDIF( NOT SQLITE3_FIND_QUIETLY ) 50 | ELSE(SQLITE3_FOUND) 51 | IF( SQLITE3_FIND_REQUIRED) 52 | MESSAGE( FATAL_ERROR "Could not find Sqlite3" ) 53 | ELSE( SQLITE3_FIND_REQUIRED) 54 | MESSAGE( STATUS "Optional package Sqlite3 was not found" ) 55 | ENDIF( SQLITE3_FIND_REQUIRED) 56 | ENDIF(SQLITE3_FOUND) 57 | -------------------------------------------------------------------------------- /src/db/sql/connectors/sqlite3/SqliteConnector.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef SQLITECONNECTOR_H 17 | #define SQLITECONNECTOR_H 18 | #include "SqlConnectorBase.h" 19 | #include "SqliteTransactionImpl.h" 20 | #include "Array.h" 21 | #include 22 | #include 23 | #include 24 | 25 | namespace metacpp 26 | { 27 | namespace db 28 | { 29 | namespace sql 30 | { 31 | namespace connectors 32 | { 33 | namespace sqlite 34 | { 35 | 36 | class SqliteConnector : public SqlConnectorBase 37 | { 38 | public: 39 | explicit SqliteConnector(const String& connectionUri); 40 | ~SqliteConnector(); 41 | 42 | // test database connectivity, initialize connection pool 43 | bool connect() override; 44 | bool disconnect() override; 45 | SqlTransactionImpl *createTransaction() override; 46 | bool closeTransaction(SqlTransactionImpl *transaction) override; 47 | SqlSyntax sqlSyntax() const override; 48 | void setConnectionPooling(size_t size) override; 49 | private: 50 | String m_connectionUri; 51 | size_t m_poolSize; 52 | Array m_freeDbHandles, m_usedDbHandles; 53 | std::mutex m_poolMutex; 54 | std::condition_variable m_dbHandleFreedEvent; 55 | bool m_connected; 56 | Array m_transactions; 57 | std::mutex m_transactionMutex; 58 | }; 59 | 60 | /** \brief Get human-readable description of a sqlite3 error */ 61 | const char *describeSqliteError(int errorCode); 62 | 63 | class SqliteConnectorFactory : public SqlConnectorFactory 64 | { 65 | std::unique_ptr createInstance(const Uri &uri); 66 | }; 67 | 68 | } // namespace sqlite 69 | } // namespace connectors 70 | } // namespace sql 71 | } // namespace db 72 | } // namespace metacpp 73 | 74 | #endif // SQLITECONNECTOR_H 75 | -------------------------------------------------------------------------------- /src/db/sql/connectors/postgres/PostgresTransactionImpl.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef POSTGRESTRANSACTIONIMPL_H 17 | #define POSTGRESTRANSACTIONIMPL_H 18 | #include "SqlTransactionImpl.h" 19 | #include "PostgresStatementImpl.h" 20 | #include 21 | #include 22 | 23 | namespace metacpp { 24 | namespace db { 25 | namespace sql { 26 | namespace connectors { 27 | namespace postgres { 28 | 29 | class PostgresTransactionImpl : public SqlTransactionImpl 30 | { 31 | public: 32 | PostgresTransactionImpl(PGconn *dbConn); 33 | ~PostgresTransactionImpl(); 34 | 35 | bool begin() override; 36 | bool commit() override; 37 | bool rollback() override; 38 | 39 | SqlStatementImpl *createStatement(SqlStatementType type, const String& queryText) override; 40 | bool prepare(SqlStatementImpl *statement, size_t numParams) override; 41 | bool bindValues(SqlStatementImpl *statement, const VariantArray &values) override; 42 | bool execStatement(SqlStatementImpl *statement, int *numRowsAffected = nullptr) override; 43 | bool fetchNext(SqlStatementImpl *statement, SqlStorable *storable) override; 44 | size_t size(SqlStatementImpl *statement) override; 45 | bool getLastInsertId(SqlStatementImpl *statement, SqlStorable *storable) override; 46 | bool closeStatement(SqlStatementImpl *statement) override; 47 | 48 | PGconn *dbConn() const { return m_dbConn; } 49 | private: 50 | bool execCommand(const char *query, const char *invokeContext); 51 | private: 52 | PGconn *m_dbConn; 53 | Array m_statements; 54 | std::mutex m_statementsMutex; 55 | }; 56 | 57 | } // namespace postgres 58 | } // namespace connectors 59 | } // namespace sql 60 | } // namespace db 61 | } // namespace metacpp 62 | 63 | #endif // POSTGRESTRANSACTIONIMPL_H 64 | -------------------------------------------------------------------------------- /src/db/sql/connectors/postgres/PostgresStatementImpl.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #include "PostgresStatementImpl.h" 17 | 18 | namespace metacpp { 19 | namespace db 20 | { 21 | namespace sql { 22 | namespace connectors { 23 | namespace postgres { 24 | 25 | PostgresStatementImpl::PostgresStatementImpl(SqlStatementType type, const String &queryText) 26 | : SqlStatementImpl(type, queryText), m_result(nullptr), m_execResult(nullptr), m_currentRow(-1) 27 | { 28 | 29 | } 30 | 31 | PostgresStatementImpl::~PostgresStatementImpl() 32 | { 33 | if (m_execResult) 34 | PQclear(m_execResult); 35 | if (m_result) 36 | PQclear(m_result); 37 | } 38 | 39 | void PostgresStatementImpl::setResult(PGresult *result, const String &idString) 40 | { 41 | m_result = result; 42 | m_idString = idString; 43 | } 44 | 45 | void PostgresStatementImpl::setExecResult(PGresult *result) 46 | { 47 | m_execResult = result; 48 | } 49 | 50 | PGresult *PostgresStatementImpl::getResult() const 51 | { 52 | return m_result; 53 | } 54 | 55 | PGresult *PostgresStatementImpl::getExecResult() const 56 | { 57 | return m_execResult; 58 | } 59 | 60 | const String &PostgresStatementImpl::getIdString() const 61 | { 62 | return m_idString; 63 | } 64 | 65 | int PostgresStatementImpl::currentRow() const 66 | { 67 | return m_currentRow; 68 | } 69 | 70 | void PostgresStatementImpl::setCurrentRow(int row) 71 | { 72 | m_currentRow = row; 73 | } 74 | 75 | void PostgresStatementImpl::bindValues(const VariantArray &values) 76 | { 77 | m_boundValues = values; 78 | } 79 | 80 | const VariantArray &PostgresStatementImpl::boundValues() const 81 | { 82 | return m_boundValues; 83 | } 84 | 85 | } // namespace postgres 86 | } // namespace connectors 87 | } // namespace sql 88 | } // namespace db 89 | } // namespace metacpp 90 | 91 | -------------------------------------------------------------------------------- /src/db/ASTWalkerBase.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef METACPP_DB_ASTWALKERBASE_H 17 | #define METACPP_DB_ASTWALKERBASE_H 18 | #include "config.h" 19 | #include "ExpressionNode.h" 20 | 21 | namespace metacpp { 22 | namespace db { 23 | namespace detail { 24 | 25 | class ASTWalkerBase 26 | { 27 | public: 28 | explicit ASTWalkerBase(const detail::ExpressionNodeImplPtr& rootNode); 29 | 30 | virtual ~ASTWalkerBase(); 31 | 32 | void doWalk(); 33 | protected: 34 | void visitNode(detail::ExpressionNodeImplPtr node); 35 | virtual void visitColumn(std::shared_ptr column) = 0; 36 | virtual void visitLiteral(std::shared_ptr literal) = 0; 37 | virtual void visitNull(std::shared_ptr null) = 0; 38 | virtual void visitUnaryOperator(std::shared_ptr unary) = 0; 39 | virtual void visitCastOperator(std::shared_ptr cast) = 0; 40 | virtual void visitBinaryOperator(std::shared_ptr binary) = 0; 41 | virtual void visitFunctionCall(std::shared_ptr functionCall) = 0; 42 | virtual void visitWhereClauseRelational(std::shared_ptr whereClauseRelational) = 0; 43 | virtual void visitWhereClauseLogical(std::shared_ptr whereClauseLogical) = 0; 44 | virtual void visitWhereClauseConditional(std::shared_ptr whereClauseComplex) = 0; 45 | private: 46 | detail::ExpressionNodeImplPtr m_rootNode; 47 | 48 | }; 49 | 50 | } // namespace detail 51 | } // namespace db 52 | } // namespace metacpp 53 | 54 | #endif // METACPP_DB_ASTWALKERBASE_H 55 | -------------------------------------------------------------------------------- /src/scripting/js/JSScriptEngine.cpp: -------------------------------------------------------------------------------- 1 | #include "JSScriptEngine.h" 2 | #include "JSScriptProgram.h" 3 | #if MOZJS_MAJOR_VERSION >= 46 4 | #include 5 | #endif 6 | 7 | namespace metacpp { 8 | namespace scripting { 9 | namespace js { 10 | 11 | JSScriptEngine::JSScriptEngine() 12 | : m_runtime(nullptr), 13 | m_mainThreadId(std::this_thread::get_id()) 14 | { 15 | static struct SpiderMonkeyInit { 16 | SpiderMonkeyInit() 17 | { 18 | #if MOZJS_MAJOR_VERSION >= 31 19 | JS_Init(); 20 | #endif 21 | 22 | } 23 | 24 | ~SpiderMonkeyInit() 25 | { 26 | JS_ShutDown(); 27 | } 28 | } s_init; 29 | 30 | memset(&m_globalClass, 0, sizeof(JSClass)); 31 | m_globalClass.name = "global"; 32 | m_globalClass.flags = JSCLASS_GLOBAL_FLAGS; 33 | #if MOZJS_MAJOR_VERSION < 38 34 | m_globalClass.addProperty = JS_PropertyStub; 35 | m_globalClass.delProperty = JS_DeletePropertyStub; 36 | m_globalClass.getProperty = JS_PropertyStub; 37 | m_globalClass.setProperty = JS_StrictPropertyStub; 38 | m_globalClass.enumerate = JS_EnumerateStub; 39 | m_globalClass.resolve = JS_ResolveStub; 40 | m_globalClass.convert = JS_ConvertStub; 41 | #endif 42 | 43 | #if MOZJS_MAJOR_VERSION >= 38 44 | m_runtime = JS_NewRuntime(JS::DefaultHeapMaxBytes); 45 | #else 46 | m_runtime = JS_NewRuntime(32 * 1024 * 1024, JS_NO_HELPER_THREADS); 47 | #endif 48 | if (!m_runtime) 49 | throw std::runtime_error("Could not initialize JS runtime"); 50 | } 51 | 52 | JSScriptEngine::~JSScriptEngine() 53 | { 54 | std::lock_guard _guard(m_programsMutex); 55 | if (m_programs.size()) 56 | { 57 | std::cerr << m_programs.size() << " left unclosed" << std::endl; 58 | for (auto program : m_programs) 59 | delete program; 60 | } 61 | if (m_runtime) 62 | JS_DestroyRuntime(m_runtime); 63 | } 64 | 65 | JSRuntime *JSScriptEngine::rootRuntime() const 66 | { 67 | return m_runtime; 68 | } 69 | 70 | const JSClass *JSScriptEngine::globalClass() const 71 | { 72 | return &m_globalClass; 73 | } 74 | 75 | bool JSScriptEngine::isInMainThread() const 76 | { 77 | return std::this_thread::get_id() == m_mainThreadId; 78 | } 79 | 80 | ScriptProgramBase *JSScriptEngine::createProgramImpl() 81 | { 82 | std::lock_guard _guard(m_programsMutex); 83 | m_programs.push_back(new JSScriptProgram(this)); 84 | return m_programs.back(); 85 | } 86 | 87 | void JSScriptEngine::closeProgramImpl(ScriptProgramBase *program) 88 | { 89 | std::lock_guard _guard(m_programsMutex); 90 | auto it = std::find(m_programs.begin(), m_programs.end(), program); 91 | if (it == m_programs.end()) 92 | throw std::invalid_argument("Program not found"); 93 | m_programs.erase(it); 94 | delete program; 95 | } 96 | 97 | } // namespace js 98 | } // namespace scripting 99 | } // namespace metacpp 100 | -------------------------------------------------------------------------------- /src/db/sql/SqlColumnConstraint.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #include "SqlColumnConstraint.h" 17 | #include "SqlExpressionTreeWalker.h" 18 | 19 | namespace metacpp 20 | { 21 | namespace db 22 | { 23 | namespace sql 24 | { 25 | 26 | SqlConstraintBase::~SqlConstraintBase() 27 | { 28 | 29 | } 30 | 31 | const MetaFieldBase *SqlConstraintBase::metaField() const 32 | { 33 | return m_metaField; 34 | } 35 | 36 | const MetaObject *SqlConstraintBase::metaObject() const 37 | { 38 | return m_metaObject; 39 | } 40 | 41 | SqlConstraintPrimaryKey::~SqlConstraintPrimaryKey() 42 | { 43 | } 44 | 45 | SqlConstraintType SqlConstraintPrimaryKey::type() 46 | { 47 | return SqlConstraintTypePrimaryKey; 48 | } 49 | 50 | SqlConstraintForeignKey::~SqlConstraintForeignKey() 51 | { 52 | } 53 | 54 | SqlConstraintType SqlConstraintForeignKey::type() 55 | { 56 | return SqlConstraintTypeForeignKey; 57 | } 58 | 59 | const MetaFieldBase *SqlConstraintForeignKey::referenceMetaField() const 60 | { 61 | return m_refMetaField; 62 | } 63 | 64 | const MetaObject *SqlConstraintForeignKey::referenceMetaObject() const 65 | { 66 | return m_refMetaObject; 67 | } 68 | 69 | SqlConstraintIndex::~SqlConstraintIndex() 70 | { 71 | } 72 | 73 | SqlConstraintType SqlConstraintIndex::type() 74 | { 75 | return SqlConstraintTypeIndex; 76 | } 77 | 78 | bool SqlConstraintIndex::unique() const 79 | { 80 | return m_unique; 81 | } 82 | 83 | SqlConstraintCheck::~SqlConstraintCheck() 84 | { 85 | } 86 | 87 | SqlConstraintType SqlConstraintCheck::type() 88 | { 89 | return SqlConstraintTypeCheck; 90 | } 91 | 92 | String SqlConstraintCheck::checkExpression() const 93 | { 94 | return detail::SqlExpressionTreeWalker(m_checkExpression.impl(), false).evaluate(); 95 | } 96 | 97 | } // namespace sql 98 | } // namespace db 99 | } // namespace metacpp 100 | -------------------------------------------------------------------------------- /src/scripting/js/JSScriptProgram.cpp: -------------------------------------------------------------------------------- 1 | #include "JSScriptProgram.h" 2 | #include "JSScriptThread.h" 3 | #include "JSScriptEngine.h" 4 | 5 | namespace metacpp 6 | { 7 | namespace scripting 8 | { 9 | namespace js 10 | { 11 | 12 | JSScriptProgram::JSScriptProgram(JSScriptEngine *engine) 13 | : m_engine(engine) 14 | { 15 | } 16 | 17 | JSScriptProgram::~JSScriptProgram() 18 | { 19 | } 20 | 21 | void JSScriptProgram::compile(const void *pBuffer, size_t size, const String &filename) 22 | { 23 | JS_AbortIfWrongThread(m_engine->rootRuntime()); 24 | auto deleter = [](JSContext *c) { if (c) JS_DestroyContext(c); }; 25 | std::unique_ptr cx 26 | { JS_NewContext(m_engine->rootRuntime(), 8192), deleter }; 27 | if (!cx) 28 | throw std::runtime_error("Could not create JS context"); 29 | 30 | #if MOZJS_MAJOR_VERSION >= 31 31 | JS::RootedObject global(cx.get(), JS_NewGlobalObject(cx.get(), m_engine->globalClass(), nullptr, 32 | JS::FireOnNewGlobalHook, JS::CompartmentOptions())); 33 | #else 34 | JS::RootedObject global(cx.get(), JS_NewGlobalObject(cx.get(), 35 | const_cast(m_engine->globalClass()), nullptr)); 36 | #endif 37 | JS_EnterCompartment(cx.get(), global); 38 | JS::CompileOptions options(cx.get()); 39 | options.setFileAndLine(filename.c_str(), 1); 40 | #if MOZJS_MAJOR_VERSION >= 38 41 | JS::RootedScript script(cx.get()); 42 | #if MOZJS_MAJOR_VERSION >= 46 43 | if (!JS::CompileForNonSyntacticScope(cx.get(), options, reinterpret_cast(pBuffer), size, &script)) 44 | #else 45 | if (!JS::Compile(cx.get(), global, options, reinterpret_cast(pBuffer), size, &script)) 46 | #endif 47 | throw std::runtime_error("Could not compile"); 48 | #else 49 | JS::RootedScript script(cx.get(), JS::Compile(cx.get(), global, options, 50 | reinterpret_cast(pBuffer), size)); 51 | if (!script) 52 | throw std::runtime_error("Could not compile"); 53 | #endif 54 | uint32_t bytecodeLength = 0; 55 | void *pBytecode = JS_EncodeScript(cx.get(), script, &bytecodeLength); 56 | m_bytecode = ByteArray(reinterpret_cast(pBytecode), bytecodeLength); 57 | JS_free(cx.get(), pBytecode); 58 | } 59 | 60 | ScriptThreadBase *JSScriptProgram::createThreadImpl(const String &functionName, const VariantArray &args) 61 | { 62 | std::lock_guard _guard(m_threadsMutex); 63 | if (m_bytecode.empty()) 64 | throw std::runtime_error("Program must be compiled first"); 65 | JSScriptThread *thread = new JSScriptThread(m_bytecode, m_engine); 66 | thread->setCallFunction(functionName, args); 67 | m_threads.push_back(thread); 68 | return thread; 69 | } 70 | 71 | void JSScriptProgram::closeThreadImpl(ScriptThreadBase *thread) 72 | { 73 | std::lock_guard _guard(m_threadsMutex); 74 | auto it = std::find(m_threads.begin(), m_threads.end(), thread); 75 | if (it == m_threads.end()) 76 | throw std::invalid_argument("Thread not found"); 77 | m_threads.erase(it); 78 | delete thread; 79 | } 80 | 81 | } // namespace js 82 | } // namespace scripting 83 | } // namespace metacpp 84 | -------------------------------------------------------------------------------- /src/db/ASTWalkerBase.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #include "ASTWalkerBase.h" 17 | 18 | namespace metacpp { 19 | namespace db { 20 | namespace detail { 21 | 22 | ASTWalkerBase::ASTWalkerBase(const detail::ExpressionNodeImplPtr &rootNode) 23 | : m_rootNode(rootNode) 24 | { 25 | } 26 | 27 | ASTWalkerBase::~ASTWalkerBase() 28 | { 29 | } 30 | 31 | void ASTWalkerBase::doWalk() 32 | { 33 | return visitNode(m_rootNode); 34 | } 35 | 36 | void ASTWalkerBase::visitNode(detail::ExpressionNodeImplPtr node) 37 | { 38 | switch (node->nodeType()) 39 | { 40 | case eNodeColumn: return visitColumn(std::dynamic_pointer_cast(node)); 41 | case eNodeLiteral: return visitLiteral(std::dynamic_pointer_cast(node)); 42 | case eNodeNull: return visitNull(std::dynamic_pointer_cast(node)); 43 | case eNodeUnaryOperator: return visitUnaryOperator(std::dynamic_pointer_cast(node)); 44 | case eNodeCastOperator: return visitCastOperator(std::dynamic_pointer_cast(node)); 45 | case eNodeBinaryOperator: return visitBinaryOperator(std::dynamic_pointer_cast(node)); 46 | case eNodeFunctionCall: return visitFunctionCall(std::dynamic_pointer_cast(node)); 47 | case eNodeWhereClauseRelational: return visitWhereClauseRelational(std::dynamic_pointer_cast(node)); 48 | case eNodeWhereClauseLogical: return visitWhereClauseLogical(std::dynamic_pointer_cast(node)); 49 | case eNodeWhereClauseComplex: return visitWhereClauseConditional(std::dynamic_pointer_cast(node)); 50 | default: throw std::runtime_error("Unknown node type"); 51 | } 52 | } 53 | 54 | } // namespace detail 55 | } // namespace db 56 | } // namespace metacpp 57 | 58 | -------------------------------------------------------------------------------- /src/db/sql/SqlResultIterator.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef SQLRESULTITERATOR_H 17 | #define SQLRESULTITERATOR_H 18 | #include "config.h" 19 | #include "Object.h" 20 | 21 | namespace metacpp 22 | { 23 | namespace db 24 | { 25 | namespace sql 26 | { 27 | 28 | namespace detail 29 | { 30 | class SqlResultSetData; 31 | } 32 | 33 | class SqlStorable; 34 | 35 | /** \brief Reserved value of the row for iterators pointing to the end of SqlResultSet 36 | * \relates SqlResultIterator 37 | */ 38 | static const int ROW_ID_PAST_THE_END = -1; 39 | /** \brief Reserved value of the row for representing invalid iterators 40 | * \relates SqlResultIterator 41 | */ 42 | static const int ROW_ID_INVALID = -2; 43 | 44 | /** \brief Forward iterator for iterating over sql result set */ 45 | class SqlResultIterator 46 | { 47 | public: 48 | /** Constucts a new instance of SqlResultIterator */ 49 | explicit SqlResultIterator(detail::SqlResultSetData *resultSet, int rowId); 50 | SqlResultIterator(const SqlResultIterator& other); 51 | virtual ~SqlResultIterator(); 52 | 53 | SqlResultIterator& operator=(const SqlResultIterator& rhs); 54 | bool operator==(const SqlResultIterator& rhs); 55 | bool operator!=(const SqlResultIterator& rhs); 56 | 57 | /** \brief Dereferences iterator, returns row id pointing by this iterator */ 58 | int operator*() const; 59 | /** \brief Dereferences iterator, returns row id pointing by this iterator */ 60 | int operator->() const; 61 | 62 | /** \brief Moves cursor one row further in a SqlResultSet */ 63 | SqlResultIterator& operator++(); 64 | /** \brief Returns row id pointed by this iterator */ 65 | inline int rowId() const { return m_rowId; } 66 | private: 67 | inline void setRowId(int rowId) { m_rowId = rowId; } 68 | private: 69 | friend class detail::SqlResultSetData; 70 | detail::SqlResultSetData *m_resultSet; 71 | int m_rowId; 72 | 73 | }; 74 | 75 | } // namespace sql 76 | } // namespace db 77 | } // namespace metacpp 78 | 79 | #endif // SQLRESULTITERATOR_H 80 | -------------------------------------------------------------------------------- /src/db/sql/connectors/mysql/MySqlStatementImpl.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #include "MySqlStatementImpl.h" 17 | 18 | namespace metacpp { 19 | namespace db 20 | { 21 | namespace sql { 22 | namespace connectors { 23 | namespace mysql { 24 | 25 | MySqlStatementImpl::MySqlStatementImpl(MYSQL_STMT *stmt, SqlStatementType type, const String &queryText) 26 | : SqlStatementImpl(type, queryText), m_stmt(stmt), m_result(nullptr), m_executed(false) 27 | { 28 | 29 | } 30 | 31 | MySqlStatementImpl::~MySqlStatementImpl() 32 | { 33 | if (m_stmt) 34 | mysql_stmt_close(m_stmt); 35 | if (m_result) 36 | mysql_free_result(m_result); 37 | } 38 | 39 | MYSQL_STMT *MySqlStatementImpl::getStmt() const 40 | { 41 | return m_stmt; 42 | } 43 | 44 | MYSQL_RES *MySqlStatementImpl::getResult() const 45 | { 46 | return m_result; 47 | } 48 | 49 | void MySqlStatementImpl::setResult(MYSQL_RES *result) 50 | { 51 | m_result = result; 52 | } 53 | 54 | bool MySqlStatementImpl::getExecuted() const 55 | { 56 | return m_executed; 57 | } 58 | 59 | void MySqlStatementImpl::setExecuted(bool val) 60 | { 61 | m_executed = val; 62 | } 63 | 64 | void MySqlStatementImpl::prefetch() 65 | { 66 | if (!m_result) 67 | throw std::runtime_error("Result was not set"); 68 | unsigned int numFields = mysql_num_fields(m_result); 69 | m_bindResult.resize(numFields); 70 | memset(m_bindResult.data(), 0, m_bindResult.size() * sizeof(MYSQL_BIND)); 71 | for (size_t i = 0; i < numFields; ++i) { 72 | m_bindResult[i].length = &(m_bindResult[i].length_value = 0); 73 | m_bindResult[i].is_null = &(m_bindResult[i].is_null_value = false); 74 | } 75 | int res = mysql_stmt_bind_result(m_stmt, m_bindResult.data()); 76 | if (0 != res) 77 | throw std::runtime_error("mysql_stmt_bind_result() failed"); 78 | } 79 | 80 | MYSQL_BIND *MySqlStatementImpl::bindResult(size_t nField) 81 | { 82 | return &m_bindResult[nField]; 83 | } 84 | 85 | } // namespace mysql 86 | } // namespace connectors 87 | } // namespace sql 88 | } // namespace db 89 | } // namespace metacpp 90 | 91 | -------------------------------------------------------------------------------- /src/utils/Nullable.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef NULLABLE_H 17 | #define NULLABLE_H 18 | #include "config.h" 19 | #include 20 | #include 21 | 22 | /** \brief Basic type wrapper for representing optionally set values */ 23 | template 24 | class Nullable 25 | { 26 | public: 27 | template 28 | Nullable(Args&&... args) : m_isSet(sizeof...(args) != 0), m_value(args...) {} 29 | Nullable(const Nullable& other) { *this = other; } 30 | Nullable(const T& value) : m_isSet(true), m_value(value) {} 31 | 32 | typename std::enable_if::value, Nullable>::type& operator=(const Nullable& other) 33 | { 34 | m_isSet = other.m_isSet; 35 | m_value = other.m_value; 36 | return *this; 37 | } 38 | 39 | bool operator==(const Nullable& other) const { 40 | return (m_isSet == other.m_isSet) && 41 | (!m_isSet || m_value == other.m_value); 42 | } 43 | bool operator==(const T& value) const { return m_isSet && value == m_value; } 44 | bool operator==(const std::nullptr_t&) const { return !m_isSet; } 45 | const T& operator *() const { return get(); } 46 | T& operator *() { return get(); } 47 | operator bool() const { return m_isSet; } 48 | bool isSet() const { return m_isSet; } 49 | 50 | const T& get() const 51 | { 52 | if (m_isSet) return m_value; 53 | throw std::logic_error("Value of Nullable is not set."); 54 | } 55 | 56 | T& get() 57 | { 58 | if (m_isSet) return m_value; 59 | throw std::logic_error("Value of Nullable is not set."); 60 | } 61 | 62 | void reset(bool set = false) { m_isSet = set; } 63 | 64 | const T& take(const T& _default = T()) const { return m_isSet ? get() : _default; } 65 | 66 | private: 67 | typename std::enable_if::value, void>::type set(const T& value) { m_value = value; m_isSet = true; } 68 | typename std::enable_if::value, void>::type set(T&& value) { m_value = std::move(value); m_isSet = true; } 69 | 70 | private: 71 | bool m_isSet; 72 | T m_value; 73 | }; 74 | 75 | #endif // NULLABLE_H 76 | -------------------------------------------------------------------------------- /src/db/ExpressionAssignment.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef METACPP_DB_EXPRESSIONASSIGNMENT_H 17 | #define METACPP_DB_EXPRESSIONASSIGNMENT_H 18 | #include "config.h" 19 | #include "StringBase.h" 20 | #include 21 | 22 | namespace metacpp { 23 | namespace db { 24 | 25 | template 26 | class ExpressionNode; 27 | 28 | template 29 | class ExpressionNodeColumn; 30 | 31 | namespace detail 32 | { 33 | class ExpressionNodeImplBase; 34 | } 35 | 36 | /** \brief Base template class representing assignement expressions */ 37 | template 38 | class ExpressionAssignmentBase 39 | { 40 | protected: 41 | ExpressionAssignmentBase() { } 42 | public: 43 | virtual ~ExpressionAssignmentBase() { } 44 | 45 | /** \brief Gets private implementation of the left-hand side expression */ 46 | virtual std::shared_ptr lhs() const = 0; 47 | /** \brief Gets private implementation of the right-hand side expression */ 48 | virtual std::shared_ptr rhs() const = 0; 49 | }; 50 | 51 | /** \brief General implementation for assignments */ 52 | template 53 | class ExpressionAssignment : public ExpressionAssignmentBase 54 | { 55 | public: 56 | /** \brief Constructs a new instance of SqlColumnAssignment with given left hand side and right hand side */ 57 | ExpressionAssignment(const ExpressionNodeColumn& lhs, const ExpressionNode& rhs) 58 | : m_lhs(lhs.impl()), m_rhs(rhs.impl()) 59 | { 60 | 61 | } 62 | 63 | ~ExpressionAssignment() 64 | { 65 | } 66 | 67 | /** \brief Gets private implementation of the left-hand side expression */ 68 | std::shared_ptr lhs() const { return m_lhs; } 69 | /** \brief Gets private implementation of the right-hand side expression */ 70 | std::shared_ptr rhs() const { return m_rhs; } 71 | private: 72 | std::shared_ptr m_lhs, m_rhs; 73 | }; 74 | 75 | } // namespace db 76 | } // namespace metacpp 77 | 78 | #endif // METACPP_DB_EXPRESSIONASSIGNMENT_H 79 | -------------------------------------------------------------------------------- /src/core/MetaType.h: -------------------------------------------------------------------------------- 1 | #ifndef METATYPE 2 | #define METATYPE 3 | #include "config.h" 4 | #include 5 | #include 6 | 7 | /** \brief Type of the fields 8 | * \relates metacpp::FieldInfoDescriptor 9 | */ 10 | enum EFieldType 11 | { 12 | eFieldVoid = 'x', /**< \brief void type (invalid) */ 13 | eFieldBool = 'b', /**< \brief bool type */ 14 | eFieldInt = 'i', /**< \brief int32_t type */ 15 | eFieldUint = 'u', /**< \brief uint32_t type */ 16 | eFieldInt64 = 'i' | ('6' << 8) | ('4' << 16), /**< \brief int64_t type */ 17 | eFieldUint64 = 'u' | ('6' << 8) | ('4' << 16), /**< \brief uint64_t type */ 18 | eFieldFloat = 'f', /**< \brief float type */ 19 | eFieldDouble = 'd', /**< \brief double type */ 20 | eFieldString = 's', /**< \brief metacpp::String type */ 21 | eFieldDateTime = 't', /**< \brief metacpp::DateTime type */ 22 | eFieldEnum = 'e', /**< \brief enum type */ 23 | eFieldObject = 'o', /**< \brief metacpp::Object type */ 24 | eFieldArray = 'a', /**< \brief metacpp::Array type */ 25 | eFieldVariant = 'v' /**< \brief metacpp::Variant type */ 26 | }; 27 | 28 | /** \brief Parameter determines assigning behaviour of the field 29 | * \relates metacpp::FieldInfoDescriptor 30 | */ 31 | enum EMandatoriness 32 | { 33 | eRequired, /**< \brief an exception is thrown if field value was not excplicitly specified */ 34 | eOptional, /**< \brief ignoring omited descriptor */ 35 | eDefaultable /**< \brief field is assigned to default value */ 36 | }; 37 | 38 | /** \brief Type of enumeration 39 | * \relates metacpp::EnumInfoDescriptor 40 | */ 41 | enum EEnumType 42 | { 43 | eEnumNone, /**< \brief Unknown enumeration type */ 44 | eEnumSimple, /**< \brief Simple enumeration type */ 45 | eEnumBitset /**< \brief Enumeration defines a set of bits (bitmask) */ 46 | }; 47 | 48 | namespace metacpp 49 | { 50 | template 51 | class Array; 52 | 53 | template 54 | class StringBase; 55 | 56 | class Object; 57 | class DateTime; 58 | class Variant; 59 | } 60 | 61 | template 62 | struct MayBeField : std::false_type { }; 63 | 64 | template<> struct MayBeField : std::true_type { }; 65 | template<> struct MayBeField : std::true_type { }; 66 | template<> struct MayBeField : std::true_type { }; 67 | template<> struct MayBeField : std::true_type { }; 68 | template<> struct MayBeField : std::true_type { }; 69 | template<> struct MayBeField : std::true_type { }; 70 | template<> struct MayBeField : std::true_type { }; 71 | template<> struct MayBeField > : std::true_type { }; 72 | template<> struct MayBeField : std::true_type { }; 73 | template 74 | struct MayBeField > : std::true_type { }; 75 | template<> struct MayBeField : std::true_type { }; 76 | 77 | 78 | 79 | #endif // METATYPE 80 | 81 | -------------------------------------------------------------------------------- /src/db/sql/SqlResultSet.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef SQLRESULTSET_H 17 | #define SQLRESULTSET_H 18 | #include "config.h" 19 | #include "SqlResultIterator.h" 20 | #include "SharedDataBase.h" 21 | 22 | namespace metacpp 23 | { 24 | namespace db 25 | { 26 | namespace sql 27 | { 28 | 29 | class SqlTransaction; 30 | class SqlStorable; 31 | 32 | namespace connectors 33 | { 34 | class SqlStatementImpl; 35 | } 36 | 37 | namespace detail 38 | { 39 | 40 | class SqlResultSetData : public SharedDataBase 41 | { 42 | public: 43 | SqlResultSetData(SqlTransaction& transaction, 44 | SharedObjectPointer statement, 45 | SqlStorable *storable); 46 | virtual ~SqlResultSetData(); 47 | SqlResultIterator begin(); 48 | SqlResultIterator end(); 49 | SharedDataBase *clone() const override; 50 | bool moveIterator(); 51 | size_t size(); 52 | private: 53 | friend class SqlResultIterator; 54 | 55 | SqlTransaction& m_transaction; 56 | SharedObjectPointer m_statement; 57 | SqlStorable *m_storable; 58 | mutable SqlResultIterator m_endIterator; 59 | mutable SqlResultIterator m_iterator; 60 | }; 61 | 62 | } // namespace detail 63 | 64 | /** \brief Result of an SqlSelectStatement */ 65 | class SqlResultSet : SharedDataPointer 66 | { 67 | public: 68 | /** Construct result set from select statement 69 | * Passes ownership of stmt to the constructed SqlResultSet 70 | */ 71 | SqlResultSet(SqlTransaction& transaction, 72 | SharedObjectPointer statement, 73 | SqlStorable *storable); 74 | virtual ~SqlResultSet(); 75 | /** \brief Returns iterator pointing to the begin of this set */ 76 | SqlResultIterator begin(); 77 | /** \brief Returns iterator pointing to the end of this set */ 78 | SqlResultIterator end(); 79 | /** \brief Returns number of rows in a result set, (size_t)-1 if unavailable */ 80 | size_t size(); 81 | }; 82 | 83 | } // namespace sql 84 | } // namespace db 85 | } // namespace metacpp 86 | 87 | #endif // SQLRESULTSET_H 88 | -------------------------------------------------------------------------------- /src/db/sql/connectors/SqlTransactionImpl.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef SQLTRANSACTIONIMPL_H 17 | #define SQLTRANSACTIONIMPL_H 18 | #include "SqlStorable.h" 19 | #include "SqlStatementImpl.h" 20 | 21 | namespace metacpp 22 | { 23 | namespace db 24 | { 25 | namespace sql 26 | { 27 | namespace connectors 28 | { 29 | 30 | /** \brief An abstract base class for execution of sql-statements in a context of transaction. 31 | * 32 | * This class should never be used directly 33 | */ 34 | class SqlTransactionImpl 35 | { 36 | protected: 37 | SqlTransactionImpl(); 38 | public: 39 | SqlTransactionImpl(const SqlTransactionImpl&)=delete; 40 | SqlTransactionImpl& operator=(const SqlTransactionImpl&)=delete; 41 | 42 | virtual ~SqlTransactionImpl(); 43 | 44 | /** \brief start a transaction */ 45 | virtual bool begin() = 0; 46 | 47 | /** \brief execute all commands and make all changes made within given transaction persistent */ 48 | virtual bool commit() = 0; 49 | 50 | /** \brief cancel all changes made within given transaction */ 51 | virtual bool rollback() = 0; 52 | 53 | /** \brief Create a statement */ 54 | virtual SqlStatementImpl *createStatement(SqlStatementType type, const String& queryText) = 0; 55 | 56 | /** \brief Prepare statement */ 57 | virtual bool prepare(SqlStatementImpl *statement, size_t numParams) = 0; 58 | 59 | /** \brief Bind in sql statement literal values */ 60 | virtual bool bindValues(SqlStatementImpl *statement, const VariantArray& values) = 0; 61 | 62 | /** \brief Execute statement 63 | * \param numRowsAffected pointer to retrieve number of rows affected with update or delete statement 64 | */ 65 | virtual bool execStatement(SqlStatementImpl *statement, int *numRowsAffected = nullptr) = 0; 66 | 67 | /** \brief Write result of select operation into storable and move cursor to the next row */ 68 | virtual bool fetchNext(SqlStatementImpl *statement, SqlStorable *storable) = 0; 69 | 70 | /** \brief Returns number of rows in a result set, returns (size_t)-1 if unavailable */ 71 | virtual size_t size(SqlStatementImpl *statement) = 0; 72 | 73 | /** \brief Retrieve an id of the previously inserted row */ 74 | virtual bool getLastInsertId(SqlStatementImpl *statement, SqlStorable *storable) = 0; 75 | 76 | /** \brief Destroys statement */ 77 | virtual bool closeStatement(SqlStatementImpl *statement) = 0; 78 | 79 | }; 80 | 81 | } // namespace connectors 82 | } // namespace sql 83 | } // namespace db 84 | } // namespace metacpp 85 | 86 | 87 | #endif // SQLTRANSACTIONIMPL_H 88 | -------------------------------------------------------------------------------- /src/db/sql/SqlResultSet.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #include "SqlResultSet.h" 17 | #include "SqlTransaction.h" 18 | 19 | namespace metacpp 20 | { 21 | namespace db 22 | { 23 | namespace sql 24 | { 25 | 26 | namespace detail 27 | { 28 | 29 | SqlResultSetData::SqlResultSetData(SqlTransaction& transaction, 30 | SharedObjectPointer statement, 31 | SqlStorable *storable) 32 | : m_transaction(transaction), m_statement(statement), m_storable(storable), 33 | m_endIterator(this, ROW_ID_PAST_THE_END), m_iterator(this, ROW_ID_INVALID) 34 | { 35 | } 36 | 37 | SharedDataBase *SqlResultSetData::clone() const 38 | { 39 | throw std::runtime_error("SqlResultSetData is not clonable"); 40 | } 41 | 42 | SqlResultSetData::~SqlResultSetData() 43 | { 44 | } 45 | 46 | bool SqlResultSetData::moveIterator() 47 | { 48 | if (m_transaction.impl()->fetchNext(m_statement.get(), m_storable)) { 49 | return true; 50 | } else { 51 | return false; 52 | } 53 | } 54 | 55 | size_t SqlResultSetData::size() 56 | { 57 | return m_transaction.impl()->size(m_statement.get()); 58 | } 59 | 60 | SqlResultIterator SqlResultSetData::begin() 61 | { 62 | if (m_iterator.rowId() != ROW_ID_INVALID) 63 | throw std::runtime_error("SqlResultSet::begin() had already been called"); 64 | 65 | 66 | // try fetch first row 67 | if (moveIterator()) 68 | m_iterator.setRowId(0); 69 | else 70 | m_iterator.setRowId(ROW_ID_PAST_THE_END); 71 | return m_iterator; 72 | } 73 | 74 | SqlResultIterator SqlResultSetData::end() 75 | { 76 | return m_endIterator; 77 | } 78 | 79 | } // namespace detail 80 | 81 | SqlResultSet::SqlResultSet(SqlTransaction &transaction, SharedObjectPointer statement, SqlStorable *storable) 82 | : SharedDataPointer(new detail::SqlResultSetData(transaction, statement, storable)) 83 | { 84 | 85 | } 86 | 87 | SqlResultSet::~SqlResultSet() 88 | { 89 | } 90 | 91 | SqlResultIterator SqlResultSet::begin() 92 | { 93 | return this->data()->begin(); 94 | } 95 | 96 | SqlResultIterator SqlResultSet::end() 97 | { 98 | return this->data()->end(); 99 | } 100 | 101 | size_t SqlResultSet::size() 102 | { 103 | return this->data()->size(); 104 | } 105 | 106 | } // namespace sql 107 | } // namespace db 108 | } // namespace metacpp 109 | -------------------------------------------------------------------------------- /cmake/Modules/SelectLibraryConfigurations.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # SelectLibraryConfigurations 3 | # --------------------------- 4 | # 5 | # 6 | # 7 | # select_library_configurations( basename ) 8 | # 9 | # This macro takes a library base name as an argument, and will choose 10 | # good values for basename_LIBRARY, basename_LIBRARIES, 11 | # basename_LIBRARY_DEBUG, and basename_LIBRARY_RELEASE depending on what 12 | # has been found and set. If only basename_LIBRARY_RELEASE is defined, 13 | # basename_LIBRARY will be set to the release value, and 14 | # basename_LIBRARY_DEBUG will be set to basename_LIBRARY_DEBUG-NOTFOUND. 15 | # If only basename_LIBRARY_DEBUG is defined, then basename_LIBRARY will 16 | # take the debug value, and basename_LIBRARY_RELEASE will be set to 17 | # basename_LIBRARY_RELEASE-NOTFOUND. 18 | # 19 | # If the generator supports configuration types, then basename_LIBRARY 20 | # and basename_LIBRARIES will be set with debug and optimized flags 21 | # specifying the library to be used for the given configuration. If no 22 | # build type has been set or the generator in use does not support 23 | # configuration types, then basename_LIBRARY and basename_LIBRARIES will 24 | # take only the release value, or the debug value if the release one is 25 | # not set. 26 | 27 | #============================================================================= 28 | # Copyright 2009 Will Dicharry 29 | # Copyright 2005-2009 Kitware, Inc. 30 | # 31 | # Distributed under the OSI-approved BSD License (the "License"); 32 | # see accompanying file Copyright.txt for details. 33 | # 34 | # This software is distributed WITHOUT ANY WARRANTY; without even the 35 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 36 | # See the License for more information. 37 | #============================================================================= 38 | # (To distribute this file outside of CMake, substitute the full 39 | # License text for the above reference.) 40 | 41 | # This macro was adapted from the FindQt4 CMake module and is maintained by Will 42 | # Dicharry . 43 | 44 | macro( select_library_configurations basename ) 45 | if(NOT ${basename}_LIBRARY_RELEASE) 46 | set(${basename}_LIBRARY_RELEASE "${basename}_LIBRARY_RELEASE-NOTFOUND" CACHE FILEPATH "Path to a library.") 47 | endif() 48 | if(NOT ${basename}_LIBRARY_DEBUG) 49 | set(${basename}_LIBRARY_DEBUG "${basename}_LIBRARY_DEBUG-NOTFOUND" CACHE FILEPATH "Path to a library.") 50 | endif() 51 | 52 | if( ${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE AND 53 | NOT ${basename}_LIBRARY_DEBUG STREQUAL ${basename}_LIBRARY_RELEASE AND 54 | ( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE ) ) 55 | # if the generator supports configuration types or CMAKE_BUILD_TYPE 56 | # is set, then set optimized and debug options. 57 | set( ${basename}_LIBRARY "" ) 58 | foreach( _libname IN LISTS ${basename}_LIBRARY_RELEASE ) 59 | list( APPEND ${basename}_LIBRARY optimized "${_libname}" ) 60 | endforeach() 61 | foreach( _libname IN LISTS ${basename}_LIBRARY_DEBUG ) 62 | list( APPEND ${basename}_LIBRARY debug "${_libname}" ) 63 | endforeach() 64 | elseif( ${basename}_LIBRARY_RELEASE ) 65 | set( ${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE} ) 66 | elseif( ${basename}_LIBRARY_DEBUG ) 67 | set( ${basename}_LIBRARY ${${basename}_LIBRARY_DEBUG} ) 68 | else() 69 | set( ${basename}_LIBRARY "${basename}_LIBRARY-NOTFOUND") 70 | endif() 71 | 72 | set( ${basename}_LIBRARIES "${${basename}_LIBRARY}" ) 73 | 74 | if( ${basename}_LIBRARY ) 75 | set( ${basename}_FOUND TRUE ) 76 | endif() 77 | 78 | mark_as_advanced( ${basename}_LIBRARY_RELEASE 79 | ${basename}_LIBRARY_DEBUG 80 | ) 81 | endmacro() 82 | -------------------------------------------------------------------------------- /src/utils/SharedDataBase.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef SHAREDDATABASE_H 17 | #define SHAREDDATABASE_H 18 | #include "config.h" 19 | #include 20 | #include 21 | #include 22 | 23 | namespace metacpp 24 | { 25 | 26 | /** 27 | \brief SharedDataBase represents an implicitly shared object 28 | commonly used via SharedDataPointer 29 | */ 30 | class SharedDataBase 31 | { 32 | public: 33 | virtual ~SharedDataBase(); 34 | 35 | /** \brief increment internal reference counter of the object */ 36 | int ref() const; 37 | /** \brief decrement reference counter */ 38 | int deref() const; 39 | /** \brief returns current usage count */ 40 | int count() const; 41 | /** \brief create a deep copy of the object */ 42 | virtual SharedDataBase *clone() const = 0; 43 | protected: 44 | template 45 | friend class SharedDataPointer; 46 | template 47 | friend class SharedObjectPointer; 48 | SharedDataBase(); 49 | SharedDataBase(const SharedDataBase&)=delete; 50 | private: 51 | mutable std::atomic m_count; 52 | }; 53 | 54 | /** Base class for the reference counting owner of the given object */ 55 | template 56 | class SharedObjectDataBase : public SharedDataBase 57 | { 58 | public: 59 | ~SharedObjectDataBase() = default; 60 | 61 | virtual TObj *get() const = 0; 62 | virtual void reset(TObj *) = 0; 63 | virtual TObj *extract() = 0; 64 | }; 65 | 66 | /** Reference counting owner of the given object */ 67 | template > 68 | class SharedObjectData : public SharedObjectDataBase 69 | { 70 | public: 71 | explicit SharedObjectData(TObj *pObj = nullptr, const Deleter deleter = Deleter()) 72 | : m_obj(pObj), m_deleter(deleter) 73 | { 74 | } 75 | 76 | SharedDataBase *clone() const 77 | { 78 | throw std::runtime_error("Cannot clone SharedDataBase"); 79 | //return new SharedObjectData(m_obj, m_deleter); 80 | } 81 | 82 | ~SharedObjectData() 83 | { 84 | if (m_obj) 85 | m_deleter(m_obj); 86 | } 87 | 88 | TObj *get() const override { return m_obj; } 89 | 90 | void reset(TObj *obj) override { 91 | if (m_obj) 92 | m_deleter(m_obj); 93 | m_obj = obj; 94 | } 95 | 96 | TObj *extract() override 97 | { 98 | TObj *result = m_obj; 99 | m_obj = nullptr; 100 | return result; 101 | } 102 | 103 | private: 104 | TObj *m_obj; 105 | Deleter m_deleter; 106 | }; 107 | 108 | } // namespace metacpp 109 | #endif // SHAREDDATABASE_H 110 | -------------------------------------------------------------------------------- /src/db/sql/SqlExpressionTreeWalker.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef SQLEXPRESSIONTREEWALKER_H 17 | #define SQLEXPRESSIONTREEWALKER_H 18 | #include "config.h" 19 | #include "ASTWalkerBase.h" 20 | 21 | namespace metacpp 22 | { 23 | namespace db 24 | { 25 | namespace sql 26 | { 27 | 28 | /** \brief Type of the sql syntax used by SqlStatementBase 29 | * \relates SqlStatementBase */ 30 | enum SqlSyntax 31 | { 32 | SqlSyntaxUnknown, /**< Invalid syntax type */ 33 | SqlSyntaxSqlite, /**< Sqlite syntax */ 34 | SqlSyntaxPostgreSQL, /**< Postgresql syntax */ 35 | SqlSyntaxMySql, /**< Mysql syntax */ 36 | SqlSyntaxMssql, /**< Microsoft SQL Server syntax */ 37 | SqlSyntaxFirebird, /**< Firebird/Interbase syntax */ 38 | SqlSyntaxOracle /**< Oracle RDBMS syntax */ 39 | }; 40 | 41 | namespace detail 42 | { 43 | 44 | class SqlExpressionTreeWalker final : db::detail::ASTWalkerBase 45 | { 46 | public: 47 | explicit SqlExpressionTreeWalker(const db::detail::ExpressionNodeImplPtr& rootNode, 48 | bool fullQualified = true, SqlSyntax sqlSyntax = SqlSyntaxUnknown, size_t startLiteralIndex = 0); 49 | ~SqlExpressionTreeWalker(); 50 | 51 | String evaluate(); 52 | const VariantArray& literals() const; 53 | 54 | protected: 55 | void visitColumn(std::shared_ptr column) override; 56 | void visitLiteral(std::shared_ptr literal) override; 57 | void visitNull(std::shared_ptr null) override; 58 | void visitUnaryOperator(std::shared_ptr unary) override; 59 | void visitCastOperator(std::shared_ptr cast) override; 60 | void visitBinaryOperator(std::shared_ptr binary) override; 61 | void visitFunctionCall(std::shared_ptr functionCall) override; 62 | void visitWhereClauseRelational(std::shared_ptr whereClauseRelational) override; 63 | void visitWhereClauseLogical(std::shared_ptr whereClauseLogical) override; 64 | void visitWhereClauseConditional(std::shared_ptr whereClauseConditional) override; 65 | private: 66 | String evaluateSubnode(const db::detail::ExpressionNodeImplPtr& node, bool bracesRequired = false); 67 | private: 68 | bool m_fullQualified; 69 | SqlSyntax m_sqlSyntax; 70 | Array m_stack; 71 | VariantArray m_bindValues; 72 | size_t m_startLiteralIndex; 73 | }; 74 | 75 | } // namespace detail 76 | } // namespace sql 77 | } // namespace db 78 | } // namespace metacpp 79 | 80 | #endif // SQLEXPRESSIONTREEWALKER_H 81 | 82 | -------------------------------------------------------------------------------- /src/db/sql/SqlTransaction.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #include "SqlTransaction.h" 17 | #include "SqlConnectorBase.h" 18 | #include "SqlTransactionImpl.h" 19 | 20 | namespace metacpp 21 | { 22 | namespace db 23 | { 24 | namespace sql 25 | { 26 | 27 | SqlTransaction::SqlTransaction(SqlTransactionAutoCloseMode autoClose, connectors::SqlConnectorBase *connector) 28 | : m_connector(connector), m_impl(nullptr), m_autoCloseMode(autoClose), 29 | m_transactionStarted(false) 30 | { 31 | if (!m_connector) 32 | throw std::invalid_argument("sql connector cannot be null"); 33 | m_impl = connector->createTransaction(); 34 | if (!m_impl) 35 | throw std::runtime_error("Failed to create transaction"); 36 | if (autoClose != SqlTransactionAutoCloseManual) 37 | begin(); 38 | } 39 | 40 | SqlTransaction::SqlTransaction(const String &connectionName, SqlTransactionAutoCloseMode autoClose) 41 | : SqlTransaction(autoClose, connectors::SqlConnectorBase::getNamedConnector(connectionName)) 42 | { 43 | } 44 | 45 | SqlTransaction::~SqlTransaction() 46 | { 47 | if (m_transactionStarted) 48 | { 49 | switch (m_autoCloseMode) 50 | { 51 | case SqlTransactionAutoCommit: 52 | commit(); 53 | break; 54 | case SqlTransactionAutoRollback: 55 | rollback(); 56 | break; 57 | default: 58 | std::cerr << "Destroying unfinished SqlTransaction" << std::endl; 59 | break; 60 | } 61 | } 62 | if (m_impl) 63 | m_connector->closeTransaction(m_impl); 64 | } 65 | 66 | connectors::SqlConnectorBase *SqlTransaction::connector() const 67 | { 68 | return m_connector; 69 | } 70 | 71 | connectors::SqlTransactionImpl *SqlTransaction::impl() const 72 | { 73 | return m_impl; 74 | } 75 | 76 | bool SqlTransaction::started() const 77 | { 78 | return m_transactionStarted; 79 | } 80 | 81 | void SqlTransaction::begin() 82 | { 83 | if (started()) 84 | throw std::runtime_error("Transaction already started"); 85 | if (m_impl->begin()) 86 | { 87 | m_transactionStarted = true; 88 | } 89 | else 90 | throw std::runtime_error("Begin transaction failed"); 91 | } 92 | 93 | void SqlTransaction::commit() 94 | { 95 | if (!started()) 96 | throw std::runtime_error("Transaction already finished"); 97 | if (m_impl->commit()) 98 | { 99 | m_transactionStarted = false; 100 | } 101 | else 102 | throw std::runtime_error("Commit failed"); 103 | } 104 | 105 | void SqlTransaction::rollback() 106 | { 107 | if (!started()) 108 | throw std::runtime_error("Transaction already finished"); 109 | if (m_impl->rollback()) 110 | { 111 | m_transactionStarted = false; 112 | } 113 | else 114 | throw std::runtime_error("Rollback failed"); 115 | } 116 | 117 | } // namespace sql 118 | } // namespace db 119 | } // namespace metacpp 120 | -------------------------------------------------------------------------------- /src/scripting/js/JSScriptThread.h: -------------------------------------------------------------------------------- 1 | #ifndef JSSCRIPTTHREAD_H 2 | #define JSSCRIPTTHREAD_H 3 | #include "ScriptThreadBase.h" 4 | #include "MetaObject.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace metacpp { 11 | namespace scripting { 12 | namespace js { 13 | 14 | class JSScriptEngine; 15 | 16 | namespace detail 17 | { 18 | 19 | struct ClassInfo 20 | { 21 | JSRuntime *runtime; 22 | JSClass class_; 23 | JS::Heap classObject, ctorObject; 24 | const MetaObject *metaObject; 25 | 26 | explicit ClassInfo(JSRuntime *runtime); 27 | ~ClassInfo(); 28 | static void Trace(JSTracer *trc, void *data); 29 | }; 30 | 31 | Variant fromValue(JSContext *context, const JS::Value& v); 32 | JS::Value toValue(JSContext *context, Variant v); 33 | 34 | } // namespace detail 35 | 36 | class JSScriptThread : public ScriptThreadBase 37 | { 38 | public: 39 | explicit JSScriptThread(const ByteArray& bytecode, 40 | JSScriptEngine *engine); 41 | ~JSScriptThread(); 42 | 43 | void setCallFunction(const String& functionName, const VariantArray& args); 44 | 45 | bool running() const override; 46 | Variant run() override; 47 | bool abort(unsigned timeout_ms) override; 48 | bool wait(unsigned timeout_ms) override; 49 | 50 | static JSScriptThread *getRunningInstance(JSContext *cx); 51 | const detail::ClassInfo *findRegisteredClass(const String& name); 52 | private: 53 | void onError(const char *message, JSErrorReport *report); 54 | static void dispatchError(JSContext *ctx, const char *message, JSErrorReport *report); 55 | #if MOZJS_MAJOR_VERSION >= 31 56 | static bool interruptCallback(JSContext *cx); 57 | #else 58 | static JSBool operationCallback(JSContext *cx); 59 | #endif 60 | 61 | void registerNativeClasses(JSContext *cx, JS::HandleObject global); 62 | void unregisterNativeClasses(); 63 | 64 | static void nativeObjectFinalize(JSFreeOp* fop, JSObject *obj); 65 | #if MOZJS_MAJOR_VERSION >= 31 66 | static bool nativeObjectConstruct(JSContext *cx, unsigned argc, JS::Value *vp); 67 | static bool nativeObjectOwnMethodCall(JSContext *cx, unsigned argc, JS::Value *vp); 68 | static bool nativeObjectStaticMethodCall(JSContext *cx, unsigned argc, JS::Value *vp); 69 | static bool nativeObjectDynamicGetter(JSContext* cx, JS::HandleObject obj, JS::HandleId id, 70 | JS::MutableHandleValue vp); 71 | 72 | #if MOZJS_MAJOR_VERSION >= 46 73 | static bool nativeObjectDynamicSetter(JSContext* cx, JS::HandleObject obj, JS::HandleId id, 74 | JS::MutableHandleValue vp, JS::ObjectOpResult& result); 75 | #else 76 | static bool nativeObjectDynamicSetter(JSContext* cx, JS::HandleObject obj, JS::HandleId id, 77 | bool strict, JS::MutableHandleValue vp); 78 | #endif 79 | #else 80 | static JSBool nativeObjectConstruct(JSContext *cx, unsigned argc, jsval *vp); 81 | static JSBool nativeObjectOwnMethodCall(JSContext *cx, unsigned argc, jsval *vp); 82 | static JSBool nativeObjectStaticMethodCall(JSContext *cx, unsigned argc, jsval *vp); 83 | 84 | static JSBool nativeObjectDynamicGetter(JSContext* cx, JS::HandleObject obj, JS::HandleId id, 85 | JS::MutableHandleValue vp); 86 | static JSBool nativeObjectDynamicSetter(JSContext* cx, JS::HandleObject obj, JS::HandleId id, 87 | JSBool strict, JS::MutableHandleValue vp); 88 | #endif 89 | 90 | private: 91 | ByteArray m_bytecode; 92 | JSScriptEngine *m_engine; 93 | JSRuntime *m_runtime; 94 | String m_functionName; 95 | VariantArray m_arguments; 96 | Variant m_result; 97 | std::mutex m_runMutex; 98 | std::condition_variable m_finishedVariable; 99 | std::atomic m_bRunning; 100 | std::atomic m_bTerminating; 101 | std::exception_ptr m_exception; 102 | 103 | Array m_registeredClasses; 104 | }; 105 | 106 | } // namespace js 107 | } // namespace scripting 108 | } // namespace metacpp 109 | 110 | #endif // JSSCRIPTTHREAD_H 111 | -------------------------------------------------------------------------------- /src/db/sql/connectors/SqlConnectorBase.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #include "SqlConnectorBase.h" 17 | 18 | namespace metacpp 19 | { 20 | namespace db 21 | { 22 | namespace sql 23 | { 24 | namespace connectors 25 | { 26 | 27 | SqlConnectorBase::SqlConnectorBase() 28 | { 29 | } 30 | 31 | SqlConnectorBase::~SqlConnectorBase() 32 | { 33 | } 34 | 35 | void SqlConnectorBase::setDefaultConnector(SqlConnectorBase *connector) 36 | { 37 | ms_defaultConnector.store(connector); 38 | } 39 | 40 | SqlConnectorBase *SqlConnectorBase::getDefaultConnector() 41 | { 42 | return ms_defaultConnector; 43 | } 44 | 45 | void SqlConnectorBase::setNamedConnector(SqlConnectorBase *connector, const String& connectionName) 46 | { 47 | std::lock_guard _guard(ms_namedConnectorsMutex); 48 | auto it = ms_namedConnectors.find(connectionName); 49 | if (connector) 50 | { 51 | if (ms_namedConnectors.end() != it) 52 | throw std::invalid_argument(String("Connector " + connectionName + " has already been set").c_str()); 53 | ms_namedConnectors[connectionName] = connector; 54 | } 55 | else 56 | ms_namedConnectors.erase(it); 57 | } 58 | 59 | SqlConnectorBase *SqlConnectorBase::getNamedConnector(const String& connectionName) 60 | { 61 | std::lock_guard _guard(ms_namedConnectorsMutex); 62 | auto it = ms_namedConnectors.find(connectionName); 63 | if (it == ms_namedConnectors.end()) 64 | throw std::invalid_argument(String("Connector " + connectionName + " was not found").c_str()); 65 | return it->second; 66 | } 67 | 68 | void SqlConnectorBase::registerConnectorFactory(const String &schemaName, std::shared_ptr factory) 69 | { 70 | std::lock_guard _guard(ms_connectorFactoriesMutex); 71 | ms_connectorFactories[schemaName] = factory; 72 | } 73 | 74 | void SqlConnectorBase::unregisterConnectorFactory(const String &schemaName) 75 | { 76 | std::lock_guard _guard(ms_connectorFactoriesMutex); 77 | ms_connectorFactories.erase(schemaName); 78 | } 79 | 80 | std::unique_ptr SqlConnectorBase::createConnector(const Uri &uri) 81 | { 82 | std::lock_guard _guard(ms_connectorFactoriesMutex); 83 | auto it = ms_connectorFactories.find(uri.schemeName()); 84 | if (it == ms_connectorFactories.end()) 85 | { 86 | throw std::invalid_argument(String("Unknown schema: " + uri.schemeName()).c_str()); 87 | } 88 | return it->second->createInstance(uri); 89 | } 90 | 91 | std::atomic SqlConnectorBase::ms_defaultConnector; 92 | std::mutex SqlConnectorBase::ms_namedConnectorsMutex; 93 | std::map SqlConnectorBase::ms_namedConnectors; 94 | std::mutex SqlConnectorBase::ms_connectorFactoriesMutex; 95 | std::map > SqlConnectorBase::ms_connectorFactories; 96 | 97 | } // namespace connectors 98 | } // namespace sql 99 | } // namespace db 100 | } // namespace metacpp 101 | -------------------------------------------------------------------------------- /cmake/Modules/FindMySQL.cmake: -------------------------------------------------------------------------------- 1 | #-------------------------------------------------------- 2 | # Copyright (C) 1995-2007 MySQL AB 3 | # 4 | # This program is free software; you can redistribute it and/or modify 5 | # it under the terms of version 2 of the GNU General Public License as 6 | # published by the Free Software Foundation. 7 | # 8 | # There are special exceptions to the terms and conditions of the GPL 9 | # as it is applied to this software. View the full text of the exception 10 | # in file LICENSE.exceptions in the top-level directory of this software 11 | # distribution. 12 | # 13 | # This program is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program; if not, write to the Free Software 20 | # Foundation, Inc., 21 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 22 | # 23 | # The MySQL Connector/ODBC is licensed under the terms of the 24 | # GPL, like most MySQL Connectors. There are special exceptions 25 | # to the terms and conditions of the GPL as it is applied to 26 | # this software, see the FLOSS License Exception available on 27 | # mysql.com. 28 | 29 | ########################################################################## 30 | 31 | 32 | #-------------- FIND MYSQL_INCLUDE_DIR ------------------ 33 | FIND_PATH(MYSQL_INCLUDE_DIR mysql.h 34 | /usr/include/mysql 35 | /usr/local/include/mysql 36 | /opt/mysql/mysql/include 37 | /opt/mysql/mysql/include/mysql 38 | /opt/mysql/include 39 | /opt/local/include/mysql5 40 | /usr/local/mysql/include 41 | /usr/local/mysql/include/mysql 42 | $ENV{ProgramFiles}/MySQL/*/include 43 | $ENV{SystemDrive}/MySQL/*/include) 44 | 45 | #----------------- FIND MYSQL_LIB_DIR ------------------- 46 | IF (WIN32) 47 | # Set lib path suffixes 48 | # dist = for mysql binary distributions 49 | # build = for custom built tree 50 | IF (CMAKE_BUILD_TYPE STREQUAL Debug) 51 | SET(libsuffixDist debug) 52 | SET(libsuffixBuild Debug) 53 | ELSE (CMAKE_BUILD_TYPE STREQUAL Debug) 54 | SET(libsuffixDist opt) 55 | SET(libsuffixBuild Release) 56 | ADD_DEFINITIONS(-DDBUG_OFF) 57 | ENDIF (CMAKE_BUILD_TYPE STREQUAL Debug) 58 | 59 | FIND_LIBRARY(MYSQL_LIB NAMES mysqlclient 60 | PATHS 61 | $ENV{MYSQL_DIR}/lib/${libsuffixDist} 62 | $ENV{MYSQL_DIR}/libmysql 63 | $ENV{MYSQL_DIR}/libmysql/${libsuffixBuild} 64 | $ENV{MYSQL_DIR}/client/${libsuffixBuild} 65 | $ENV{MYSQL_DIR}/libmysql/${libsuffixBuild} 66 | $ENV{ProgramFiles}/MySQL/*/lib/${libsuffixDist} 67 | $ENV{SystemDrive}/MySQL/*/lib/${libsuffixDist}) 68 | ELSE (WIN32) 69 | FIND_LIBRARY(MYSQL_LIB NAMES mysqlclient_r 70 | PATHS 71 | /usr/lib/mysql 72 | /usr/local/lib/mysql 73 | /usr/local/mysql/lib 74 | /usr/local/mysql/lib/mysql 75 | /opt/local/mysql5/lib 76 | /opt/local/lib/mysql5/mysql 77 | /opt/mysql/mysql/lib/mysql 78 | /opt/mysql/lib/mysql) 79 | ENDIF (WIN32) 80 | 81 | IF(MYSQL_LIB) 82 | GET_FILENAME_COMPONENT(MYSQL_LIB_DIR ${MYSQL_LIB} PATH) 83 | ENDIF(MYSQL_LIB) 84 | 85 | IF (MYSQL_INCLUDE_DIR AND MYSQL_LIB_DIR) 86 | SET(MYSQL_FOUND TRUE) 87 | 88 | INCLUDE_DIRECTORIES(${MYSQL_INCLUDE_DIR}) 89 | LINK_DIRECTORIES(${MYSQL_LIB_DIR}) 90 | 91 | FIND_LIBRARY(MYSQL_ZLIB zlib PATHS ${MYSQL_LIB_DIR}) 92 | FIND_LIBRARY(MYSQL_YASSL yassl PATHS ${MYSQL_LIB_DIR}) 93 | FIND_LIBRARY(MYSQL_TAOCRYPT taocrypt PATHS ${MYSQL_LIB_DIR}) 94 | SET(MYSQL_CLIENT_LIBS mysqlclient_r) 95 | IF (MYSQL_ZLIB) 96 | SET(MYSQL_CLIENT_LIBS ${MYSQL_CLIENT_LIBS} zlib) 97 | ENDIF (MYSQL_ZLIB) 98 | IF (MYSQL_YASSL) 99 | SET(MYSQL_CLIENT_LIBS ${MYSQL_CLIENT_LIBS} yassl) 100 | ENDIF (MYSQL_YASSL) 101 | IF (MYSQL_TAOCRYPT) 102 | SET(MYSQL_CLIENT_LIBS ${MYSQL_CLIENT_LIBS} taocrypt) 103 | ENDIF (MYSQL_TAOCRYPT) 104 | # Added needed mysqlclient dependencies on Windows 105 | IF (WIN32) 106 | SET(MYSQL_CLIENT_LIBS ${MYSQL_CLIENT_LIBS} ws2_32) 107 | ENDIF (WIN32) 108 | 109 | MESSAGE(STATUS "MySQL Include dir: ${MYSQL_INCLUDE_DIR} library dir: ${MYSQL_LIB_DIR}") 110 | MESSAGE(STATUS "MySQL client libraries: ${MYSQL_CLIENT_LIBS}") 111 | ELSE (MYSQL_INCLUDE_DIR AND MYSQL_LIB_DIR) 112 | IF (MySQL_FIND_REQUIRED) 113 | MESSAGE(FATAL_ERROR "Cannot find MySQL. Include dir: ${MYSQL_INCLUDE_DIR} library dir: ${MYSQL_LIB_DIR}") 114 | ENDIF (MySQL_FIND_REQUIRED) 115 | ENDIF (MYSQL_INCLUDE_DIR AND MYSQL_LIB_DIR) -------------------------------------------------------------------------------- /src/db/sql/SqlTransaction.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef SQLTRANSACTION_H 17 | #define SQLTRANSACTION_H 18 | #include "config.h" 19 | #include "SqlConnectorBase.h" 20 | 21 | namespace metacpp 22 | { 23 | namespace db 24 | { 25 | namespace sql 26 | { 27 | 28 | namespace connectors 29 | { 30 | class SqlConnectorBase; 31 | class SqlTransactionImpl; 32 | } 33 | 34 | /** \brief Defines consistency policy of SqlTransaction */ 35 | enum SqlTransactionAutoCloseMode 36 | { 37 | SqlTransactionAutoRollback, /**< Transaction is rollbacked automatically if was not previously closed manually. This is the default policy. */ 38 | SqlTransactionAutoCommit, /**< Transaction is commited automatically if was not closed manually */ 39 | SqlTransactionAutoCloseManual /**< In this mode transaction should always be closed manually */ 40 | }; 41 | 42 | /** \brief Provides ACID garantees on executed sql statements. 43 | * 44 | * All sql statements is only possible to execute in a context of transaction. 45 | * TODO: detailed example 46 | * 47 | * Note: You should avoid recursive instantiation of SqlTransaction since 48 | * each instance is holding a dedicated connection to the database, which 49 | * is freed automatically in SqlTransaction destructor. Having several 50 | * SqlTransaction instances in same thread is possible due to connection pooling, 51 | * but this is an error-prone practice beacause at some point you may 52 | * run out of available connections. In this case your program will become 53 | * dead-locked. 54 | */ 55 | class SqlTransaction 56 | { 57 | public: 58 | /** \brief Constructs a new instance of SqlTransaction 59 | * \param autoClose defines consistency policy. 60 | * \param connector provides connection to database 61 | */ 62 | SqlTransaction(SqlTransactionAutoCloseMode autoClose = SqlTransactionAutoRollback, 63 | connectors::SqlConnectorBase *connector = connectors::SqlConnectorBase::getDefaultConnector()); 64 | /** \brief Constructs a new instance of SqlTransaction 65 | * \param connectionName references connection to the database. \see SqlConnectorBase::getNamedConnector 66 | * \param autoClose defines consistency policy 67 | */ 68 | explicit SqlTransaction(const String& connectionName, 69 | SqlTransactionAutoCloseMode autoClose = SqlTransactionAutoRollback); 70 | 71 | virtual ~SqlTransaction(); 72 | 73 | SqlTransaction(const SqlTransaction&)=delete; 74 | SqlTransaction operator=(const SqlTransaction&)=delete; 75 | 76 | /** \brief Returns the connector used by this transaction */ 77 | connectors::SqlConnectorBase *connector() const; 78 | /** \brief Returns a connector-specific implementation */ 79 | connectors::SqlTransactionImpl *impl() const; 80 | /** \brief Checks whether transaction is started */ 81 | bool started() const; 82 | /** \brief Starts a transaction block 83 | * \throws std::runtime_error 84 | */ 85 | void begin(); 86 | /** \brief Executes all statements in current transaction block and finishes it */ 87 | void commit(); 88 | /** \brief Drp[s all statements in current transaction block and finishes it. 89 | * The database is rollbacked to it's previous consistent state */ 90 | void rollback(); 91 | private: 92 | connectors::SqlConnectorBase *m_connector; 93 | connectors::SqlTransactionImpl *m_impl; 94 | SqlTransactionAutoCloseMode m_autoCloseMode; 95 | bool m_transactionStarted; 96 | }; 97 | 98 | 99 | } // namespace sql 100 | } // namespace db 101 | } // namespace metacpp 102 | 103 | #endif // SQLTRANSACTION_H 104 | -------------------------------------------------------------------------------- /src/db/TypePromotion.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef TYPEPROMOTION_H 17 | #define TYPEPROMOTION_H 18 | #include "config.h" 19 | #include 20 | 21 | namespace metacpp 22 | { 23 | namespace db 24 | { 25 | namespace detail 26 | { 27 | 28 | template 29 | struct TypePromotionPriorityHelper; 30 | 31 | template<> 32 | struct TypePromotionPriorityHelper 33 | { 34 | static const int priority = 0; 35 | }; 36 | 37 | template<> 38 | struct TypePromotionPriorityHelper 39 | { 40 | static const int priority = 1; 41 | }; 42 | 43 | template<> 44 | struct TypePromotionPriorityHelper 45 | { 46 | static const int priority = 2; 47 | }; 48 | 49 | template<> 50 | struct TypePromotionPriorityHelper 51 | { 52 | static const int priority = 3; 53 | }; 54 | 55 | template<> 56 | struct TypePromotionPriorityHelper 57 | { 58 | static const int priority = 4; 59 | }; 60 | 61 | template<> 62 | struct TypePromotionPriorityHelper 63 | { 64 | static const int priority = 5; 65 | }; 66 | 67 | template<> 68 | struct TypePromotionPriorityHelper 69 | { 70 | static const int priority = 6; 71 | }; 72 | 73 | template<> 74 | struct TypePromotionPriorityHelper 75 | { 76 | static const int priority = 7; 77 | }; 78 | 79 | template<> 80 | struct TypePromotionPriorityHelper 81 | { 82 | static const int priority = 8; 83 | }; 84 | 85 | // all others are promoted to int 86 | template 87 | struct TypePromotionPriorityHelper::value>::type> 88 | { 89 | static const int priority = 1000; 90 | }; 91 | 92 | enum _PromotionType 93 | { 94 | _PromoteToFirst, 95 | _PromoteToSecond, 96 | _PromoteToInt 97 | }; 98 | 99 | template 100 | struct TypePromotionHelper; 101 | 102 | template 103 | struct TypePromotionHelper 104 | { 105 | typedef T1 PromotionType; 106 | }; 107 | 108 | template 109 | struct TypePromotionHelper 110 | { 111 | typedef T2 PromotionType; 112 | }; 113 | 114 | template 115 | struct TypePromotionHelper 116 | { 117 | typedef int PromotionType; 118 | }; 119 | 120 | template 121 | struct TypePromotion; 122 | 123 | template 124 | struct TypePromotion 125 | { 126 | typedef TField Type; 127 | }; 128 | 129 | template 130 | struct TypePromotion 131 | { 132 | static_assert(std::is_arithmetic::value && std::is_arithmetic::value, 133 | "Should only be used with arithmetic types"); 134 | typedef typename TypePromotionHelper::priority >= 1000 && 136 | TypePromotionPriorityHelper::priority >= 1000 ? _PromoteToInt : 137 | (TypePromotionPriorityHelper::priority < 138 | TypePromotionPriorityHelper::priority ? 139 | _PromoteToFirst : _PromoteToSecond)>::PromotionType Type; 140 | }; 141 | 142 | template 143 | struct TypePromotion 144 | { 145 | typedef TField Type; 146 | }; 147 | 148 | template 149 | struct TypePromotion 150 | { 151 | typedef TypePromotion::Type> Type; 152 | }; 153 | 154 | } // namespace detail 155 | } // namespace db 156 | } // namespace metacpp 157 | 158 | #endif // TYPEPROMOTION_H 159 | 160 | -------------------------------------------------------------------------------- /examples/scripting-example.cpp: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | #ifdef HAVE_SPIDERMONKEY 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | // That is our program inside a program 10 | const char szScriptProgram[] = R"#( 11 | var pt = new Point(); 12 | pt.x = pt.y = 5 13 | console.printPoint(pt); 14 | var pt2 = new Point(2, 3) 15 | console.printPoint(pt2); 16 | pt.addX(12); 17 | pt.addY(-29); 18 | console.log("Point moved { x = %d, y = %d }", [ pt.x, pt.y ]); 19 | console.log("Distance between points now: %g", [ pt.distanceTo(pt2) ]) 20 | // attempt to call a function with incompatible parameters will raise an exception 21 | try 22 | { 23 | pt.addX('12'); // function can't be called with string parameter 24 | } 25 | catch (err) 26 | { 27 | console.error("Exception raised: %s", [ err.toString() ]); 28 | } 29 | )#"; 30 | 31 | using namespace metacpp; 32 | using namespace metacpp::scripting::js; 33 | 34 | // Define our reflectible classes. 35 | 36 | struct Point : public Object { 37 | explicit Point(int x = 0, int y = 0) 38 | : x(x), y(y) 39 | { 40 | } 41 | 42 | // All properties and methods exposed to the script engine must be public 43 | int x, y; 44 | 45 | void addX(int v) { x += v; } 46 | void addY(int v) { y += v; } 47 | // Euclidean distance between two points 48 | double distanceTo(Point *other) const 49 | { 50 | double dx = x - other->x; 51 | double dy = y - other->y; 52 | return sqrt(pow(dx, 2) + pow(dy, 2)); 53 | } 54 | 55 | // this macro simply declares service function for the object introspection 56 | // and also for dynamic object instantiation and destruction 57 | META_INFO_DECLARE(Point) 58 | }; 59 | 60 | // Declare exposed object methods 61 | METHOD_INFO_BEGIN(Point) 62 | CONSTRUCTOR(Point) 63 | CONSTRUCTOR(Point, int, int) 64 | METHOD(Point, addX) 65 | METHOD(Point, addY) 66 | METHOD(Point, distanceTo) 67 | METHOD_INFO_END(Point) 68 | 69 | // And properties 70 | STRUCT_INFO_BEGIN(Point) 71 | FIELD(Point, x) 72 | FIELD(Point, y) 73 | STRUCT_INFO_END(Point) 74 | 75 | // REFLECTIBLE_FM means that class have both the reflected fields and methods 76 | // Use REFLECTIBLE_F to expose only fields 77 | // and REFLECTIBLE_M to expose only methods 78 | REFLECTIBLE_FM(Point) 79 | // define service methods 80 | META_INFO(Point) 81 | 82 | // The same for another reflectible class 83 | struct console : public Object { 84 | // VariantArray can be used to pass variable number of arguments to the script 85 | static void log(const String& fmt, const VariantArray& args) 86 | { 87 | std::cerr << "Log: " << String::format(fmt.c_str(), args) << std::endl; 88 | } 89 | 90 | static void info(const String& fmt, const VariantArray& args) 91 | { 92 | std::cerr << "Info: " << String::format(fmt.c_str(), args) << std::endl; 93 | } 94 | 95 | static void warn(const String& fmt, const VariantArray& args) 96 | { 97 | std::cerr << "Warn: " << String::format(fmt.c_str(), args) << std::endl; 98 | } 99 | 100 | static void error(const String& fmt, const VariantArray& args) 101 | { 102 | std::cerr << "Error: " << String::format(fmt.c_str(), args) << std::endl; 103 | } 104 | 105 | static void printPoint(const Point *pt) { 106 | std::cout << "Point { x = " << pt->x << ", y = " << pt->y << " }" << std::endl; 107 | } 108 | 109 | META_INFO_DECLARE(console) 110 | }; 111 | 112 | METHOD_INFO_BEGIN(console) 113 | METHOD(console, log) 114 | METHOD(console, info) 115 | METHOD(console, warn) 116 | METHOD(console, error) 117 | METHOD(console, printPoint) 118 | METHOD_INFO_END(console) 119 | 120 | REFLECTIBLE_M(console) 121 | 122 | META_INFO(console) 123 | 124 | int main(int argc, char **argv) 125 | { 126 | try 127 | { 128 | // Instantiate the engine first 129 | JSScriptEngine engine; 130 | // Register bindings to our reflectible classes via their MetaObject 131 | engine.registerClass(Point::staticMetaObject()); 132 | engine.registerClass(console::staticMetaObject()); 133 | // Create a script program 134 | auto program = engine.createProgram(); 135 | // Compile it program 136 | std::istringstream ss(szScriptProgram); 137 | program->compile(ss, "example.js"); 138 | // Create a script thread and run it 139 | auto thread = program->createThread(); 140 | thread->run(); 141 | } 142 | catch (const std::exception& e) 143 | { 144 | std::cerr << e.what() << std::endl; 145 | return 1; 146 | } 147 | 148 | return 0; 149 | } 150 | 151 | #else 152 | 153 | #include 154 | 155 | int main(int argc, char **argv) 156 | { 157 | std::cerr << "The metacpp has been built with no JS support" << std::endl; 158 | return 1; 159 | } 160 | 161 | #endif -------------------------------------------------------------------------------- /src/db/sql/connectors/SqlConnectorBase.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef SQLCONNECTORBASE_H 17 | #define SQLCONNECTORBASE_H 18 | #include "SqlResultSet.h" 19 | #include "SqlStatementImpl.h" 20 | #include "SqlTransactionImpl.h" 21 | #include "SqlStorable.h" 22 | #include 23 | #include 24 | #include "StringBase.h" 25 | #include "Uri.h" 26 | 27 | namespace metacpp 28 | { 29 | namespace db 30 | { 31 | namespace sql 32 | { 33 | namespace connectors 34 | { 35 | 36 | class SqlConnectorBase; 37 | 38 | /** \brief Factory type for SqlConnectorBase 39 | * \relates SqlConnectorBase 40 | */ 41 | typedef FactoryBase, const Uri&> SqlConnectorFactory; 42 | 43 | /** \brief A base abstract class representing database connection 44 | * 45 | * Should never be used directly 46 | */ 47 | class SqlConnectorBase 48 | { 49 | protected: 50 | /** \brief Constructs a new instance of SqlConnectorBase */ 51 | SqlConnectorBase(); 52 | public: 53 | SqlConnectorBase(const SqlConnectorBase&)=delete; 54 | SqlConnectorBase& operator=(const SqlConnectorBase&)=delete; 55 | 56 | virtual ~SqlConnectorBase(); 57 | 58 | /** \brief Perform initial connection to the database */ 59 | virtual bool connect() = 0; 60 | 61 | /** \brief Closes all connections to the database */ 62 | virtual bool disconnect() = 0; 63 | 64 | /** \brief Creates a new transaction implementation using available connection to the database. 65 | * 66 | * After you finish with transaction you should return it back to the connector with closeTransaction 67 | */ 68 | virtual SqlTransactionImpl *createTransaction() = 0; 69 | 70 | /** \brief Destroys the transaction and frees database connection which was occupied by it 71 | * 72 | * \see SqlConnectorBasse::setConnectionPooling 73 | */ 74 | virtual bool closeTransaction(SqlTransactionImpl *transaction) = 0; 75 | 76 | /** \brief Gets type of the sql syntax accepted by this connector */ 77 | virtual SqlSyntax sqlSyntax() const = 0; 78 | 79 | /** \brief Sets number of parallel connections used by this connector for parallel execution 80 | * 81 | * This method should be called before performing actual connection with SqlConnectorBase::connect 82 | */ 83 | virtual void setConnectionPooling(size_t size) = 0; 84 | 85 | /** \brief Sets connector to be used as a default for all transactions */ 86 | static void setDefaultConnector(SqlConnectorBase *connector); 87 | /** \brief Gets default connector previously set by SqlConnectorBase::setDefaultConnector */ 88 | static SqlConnectorBase *getDefaultConnector(); 89 | 90 | /** \brief Sets connector as a named connection */ 91 | static void setNamedConnector(SqlConnectorBase *connector, const String& connectionName); 92 | /** \brief Gets a named connection previously set by SqlConnectorBase::setNamedConnector */ 93 | static SqlConnectorBase *getNamedConnector(const String &connectionName); 94 | 95 | /** \brief Registers schemaName to be used with specified factory for creation of connectors with 96 | * SqlConnectorBase::createConnector 97 | */ 98 | static void registerConnectorFactory(const String& schemaName, std::shared_ptr factory); 99 | /** \brief Unregisters factory for the schemaName previously registered with SqlConnectorBase::registerConnectorFactory */ 100 | static void unregisterConnectorFactory(const String& schemaName); 101 | 102 | /** \brief Creates a new connector with database connection parameters specified by uri 103 | * 104 | * \see SqlConnectorBase::registerConnectorFactory, SqlConnectorBase::unregisterConnectorFactory 105 | */ 106 | static std::unique_ptr createConnector(const Uri& uri); 107 | private: 108 | static std::atomic ms_defaultConnector; 109 | static std::mutex ms_namedConnectorsMutex; 110 | static std::map ms_namedConnectors; 111 | 112 | static std::mutex ms_connectorFactoriesMutex; 113 | static std::map > ms_connectorFactories; 114 | }; 115 | 116 | } // namespace connectors 117 | } // namespace sql 118 | } // namespace db 119 | } // namespace metacpp 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /src/core/Object.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #include "Object.h" 17 | #include "InitVisitor.h" 18 | 19 | #ifdef HAVE_JSONCPP 20 | #include "JsonSerializerVisitor.h" 21 | #include "JsonDeserializerVisitor.h" 22 | #endif 23 | 24 | #ifdef HAVE_MONGODB 25 | #include "BsonSerializerVisitor.h" 26 | #include "BsonDeserializerVisitor.h" 27 | #endif 28 | 29 | namespace metacpp 30 | { 31 | 32 | Object::Object() 33 | { 34 | 35 | } 36 | 37 | Object::Object(const Object &other) 38 | : m_dynamicProperties(other.m_dynamicProperties) 39 | { 40 | } 41 | 42 | Object::~Object() 43 | { 44 | } 45 | 46 | void Object::deleteThis() 47 | { 48 | metaObject()->destroyInstance(this); 49 | } 50 | 51 | void Object::init() 52 | { 53 | InitVisitor vis; 54 | vis.visit(this); 55 | } 56 | 57 | Object &Object::operator=(const Object &rhs) 58 | { 59 | m_dynamicProperties = rhs.m_dynamicProperties; 60 | return *this; 61 | } 62 | 63 | #ifdef HAVE_JSONCPP 64 | String Object::toJson(bool prettyFormatted) const 65 | { 66 | using namespace serialization::json; 67 | JsonSerializerVisitor vis; 68 | vis.visit(const_cast(this)); 69 | if (prettyFormatted) 70 | { 71 | Json::StyledWriter writer; 72 | return String(writer.write(vis.rootValue()).c_str()); 73 | } 74 | else 75 | { 76 | Json::FastWriter writer; 77 | return String(writer.write(vis.rootValue()).c_str()); 78 | } 79 | } 80 | 81 | void Object::fromJson(const String& s, const Array &knownTypes) 82 | { 83 | using namespace serialization::json; 84 | Json::Reader reader; 85 | Json::Value root; 86 | if (!reader.parse(s.begin(), s.end(), root, false)) 87 | throw std::invalid_argument("Json::Reader::parse failed"); 88 | metacpp::serialization::TypeResolverFactory typeResolver(knownTypes); 89 | JsonDeserializerVisitor vis(root, &typeResolver); 90 | vis.visit(this); 91 | } 92 | 93 | #endif // HAVE_JSONCPP 94 | 95 | #ifdef HAVE_MONGODB 96 | 97 | ByteArray Object::toBson() const 98 | { 99 | using namespace serialization::bson; 100 | BsonSerializerVisitor vis; 101 | vis.visit(const_cast(this)); 102 | mongo::BSONObj bsonObj = vis.doneObj(); 103 | return ByteArray(reinterpret_cast(bsonObj.objdata()), bsonObj.objsize()); 104 | } 105 | 106 | void Object::fromBson(const void *data) 107 | { 108 | using namespace serialization::bson; 109 | mongo::BSONObj bsonObj(reinterpret_cast(data)); 110 | BsonDeserializerVisitor vis(bsonObj); 111 | vis.visit(this); 112 | } 113 | 114 | #endif // HAVE_MONGODB 115 | 116 | Variant Object::invoke(const String &methodName, const VariantArray &args) 117 | { 118 | return doInvoke(methodName, args, false); 119 | } 120 | 121 | Variant Object::invoke(const String &methodName, const VariantArray &args) const 122 | { 123 | return doInvoke(methodName, args, true); 124 | } 125 | 126 | void Object::setProperty(const String &propName, const Variant &val) 127 | { 128 | auto field = metaObject()->fieldByName(propName); 129 | if (field) 130 | field->setValue(val, this); 131 | else 132 | m_dynamicProperties[propName] = val; 133 | } 134 | 135 | Variant Object::getProperty(const String &propName) const 136 | { 137 | auto field = metaObject()->fieldByName(propName); 138 | if (field) 139 | return field->getValue(this); 140 | auto it = m_dynamicProperties.find(propName); 141 | if (it != m_dynamicProperties.end()) 142 | return it->second; 143 | return Variant(); 144 | } 145 | 146 | const MetaObject *Object::staticMetaObject() 147 | { 148 | return &ms_metaObject; 149 | } 150 | 151 | Variant Object::doInvoke(const String &methodName, const VariantArray &args, bool constness) const 152 | { 153 | for (size_t i = 0; i < metaObject()->totalMethods(); ++i) 154 | { 155 | auto method = metaObject()->method(i); 156 | if (eMethodOwn == method->type() && args.size() == method->numArguments() && methodName.equals(method->name())) 157 | { 158 | // cannot call non-const methods on const objects 159 | if (constness && !method->constness()) 160 | continue; 161 | try 162 | { 163 | return method->invoker()->invoke(const_cast(this), args); 164 | } 165 | catch (const BindArgumentException& /*ex*/) 166 | { 167 | continue; 168 | } 169 | } 170 | } 171 | throw MethodNotFoundException(String("Cannot find own method " + methodName + " compatible with arguments provided").c_str()); 172 | } 173 | 174 | 175 | STRUCT_INFO_BEGIN(Object) 176 | STRUCT_INFO_END(Object) 177 | 178 | REFLECTIBLE_F(Object) 179 | 180 | const MetaObject Object::ms_metaObject(&REFLECTIBLE_DESCRIPTOR(Object)); 181 | 182 | } // namespace metacpp 183 | -------------------------------------------------------------------------------- /cmake/Modules/CMakeParseArguments.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # CMakeParseArguments 3 | # ------------------- 4 | # 5 | # 6 | # 7 | # CMAKE_PARSE_ARGUMENTS( 8 | # args...) 9 | # 10 | # CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions 11 | # for parsing the arguments given to that macro or function. It 12 | # processes the arguments and defines a set of variables which hold the 13 | # values of the respective options. 14 | # 15 | # The argument contains all options for the respective macro, 16 | # i.e. keywords which can be used when calling the macro without any 17 | # value following, like e.g. the OPTIONAL keyword of the install() 18 | # command. 19 | # 20 | # The argument contains all keywords for this macro 21 | # which are followed by one value, like e.g. DESTINATION keyword of the 22 | # install() command. 23 | # 24 | # The argument contains all keywords for this 25 | # macro which can be followed by more than one value, like e.g. the 26 | # TARGETS or FILES keywords of the install() command. 27 | # 28 | # When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the 29 | # keywords listed in , and 30 | # a variable composed of the given 31 | # followed by "_" and the name of the respective keyword. These 32 | # variables will then hold the respective value from the argument list. 33 | # For the keywords this will be TRUE or FALSE. 34 | # 35 | # All remaining arguments are collected in a variable 36 | # _UNPARSED_ARGUMENTS, this can be checked afterwards to see 37 | # whether your macro was called with unrecognized parameters. 38 | # 39 | # As an example here a my_install() macro, which takes similar arguments 40 | # as the real install() command: 41 | # 42 | # :: 43 | # 44 | # function(MY_INSTALL) 45 | # set(options OPTIONAL FAST) 46 | # set(oneValueArgs DESTINATION RENAME) 47 | # set(multiValueArgs TARGETS CONFIGURATIONS) 48 | # cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) 49 | # ... 50 | # 51 | # 52 | # 53 | # Assume my_install() has been called like this: 54 | # 55 | # :: 56 | # 57 | # my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub) 58 | # 59 | # 60 | # 61 | # After the cmake_parse_arguments() call the macro will have set the 62 | # following variables: 63 | # 64 | # :: 65 | # 66 | # MY_INSTALL_OPTIONAL = TRUE 67 | # MY_INSTALL_FAST = FALSE (this option was not used when calling my_install() 68 | # MY_INSTALL_DESTINATION = "bin" 69 | # MY_INSTALL_RENAME = "" (was not used) 70 | # MY_INSTALL_TARGETS = "foo;bar" 71 | # MY_INSTALL_CONFIGURATIONS = "" (was not used) 72 | # MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL" 73 | # 74 | # 75 | # 76 | # You can then continue and process these variables. 77 | # 78 | # Keywords terminate lists of values, e.g. if directly after a 79 | # one_value_keyword another recognized keyword follows, this is 80 | # interpreted as the beginning of the new option. E.g. 81 | # my_install(TARGETS foo DESTINATION OPTIONAL) would result in 82 | # MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION 83 | # would be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor. 84 | 85 | #============================================================================= 86 | # Copyright 2010 Alexander Neundorf 87 | # 88 | # Distributed under the OSI-approved BSD License (the "License"); 89 | # see accompanying file Copyright.txt for details. 90 | # 91 | # This software is distributed WITHOUT ANY WARRANTY; without even the 92 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 93 | # See the License for more information. 94 | #============================================================================= 95 | # (To distribute this file outside of CMake, substitute the full 96 | # License text for the above reference.) 97 | 98 | 99 | if(__CMAKE_PARSE_ARGUMENTS_INCLUDED) 100 | return() 101 | endif() 102 | set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE) 103 | 104 | 105 | function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames) 106 | # first set all result variables to empty/FALSE 107 | foreach(arg_name ${_singleArgNames} ${_multiArgNames}) 108 | set(${prefix}_${arg_name}) 109 | endforeach() 110 | 111 | foreach(option ${_optionNames}) 112 | set(${prefix}_${option} FALSE) 113 | endforeach() 114 | 115 | set(${prefix}_UNPARSED_ARGUMENTS) 116 | 117 | set(insideValues FALSE) 118 | set(currentArgName) 119 | 120 | # now iterate over all arguments and fill the result variables 121 | foreach(currentArg ${ARGN}) 122 | list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword 123 | list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword 124 | list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword 125 | 126 | if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1) 127 | if(insideValues) 128 | if("${insideValues}" STREQUAL "SINGLE") 129 | set(${prefix}_${currentArgName} ${currentArg}) 130 | set(insideValues FALSE) 131 | elseif("${insideValues}" STREQUAL "MULTI") 132 | list(APPEND ${prefix}_${currentArgName} ${currentArg}) 133 | endif() 134 | else() 135 | list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg}) 136 | endif() 137 | else() 138 | if(NOT ${optionIndex} EQUAL -1) 139 | set(${prefix}_${currentArg} TRUE) 140 | set(insideValues FALSE) 141 | elseif(NOT ${singleArgIndex} EQUAL -1) 142 | set(currentArgName ${currentArg}) 143 | set(${prefix}_${currentArgName}) 144 | set(insideValues "SINGLE") 145 | elseif(NOT ${multiArgIndex} EQUAL -1) 146 | set(currentArgName ${currentArg}) 147 | set(${prefix}_${currentArgName}) 148 | set(insideValues "MULTI") 149 | endif() 150 | endif() 151 | 152 | endforeach() 153 | 154 | # propagate the result variables to the caller: 155 | foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames}) 156 | set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE) 157 | endforeach() 158 | set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE) 159 | 160 | endfunction() 161 | -------------------------------------------------------------------------------- /src/db/sql/connectors/mysql/MySqlConnector.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #include "MySqlConnector.h" 17 | 18 | namespace metacpp { 19 | namespace db { 20 | namespace sql { 21 | namespace connectors { 22 | namespace mysql { 23 | 24 | MySqlConnector::MySqlConnector(const Uri &connectionUri) 25 | : m_connectionUri(connectionUri), m_poolSize(1), m_connected(false) 26 | { 27 | } 28 | 29 | MySqlConnector::~MySqlConnector() 30 | { 31 | if (m_connected) 32 | disconnect(); 33 | } 34 | 35 | bool MySqlConnector::connect() 36 | { 37 | 38 | if (m_connected) 39 | { 40 | std::cerr << "MySqlConnector::connect(): database connection seems to be already opened" 41 | << std::endl; 42 | return true; 43 | } 44 | 45 | const char *host = m_connectionUri.host().isNullOrEmpty() ? NULL : m_connectionUri.host().c_str(); 46 | const char *user = m_connectionUri.username().isNullOrEmpty() ? NULL : m_connectionUri.username().c_str(); 47 | const char *password = m_connectionUri.password().isNullOrEmpty() ? NULL : m_connectionUri.password().c_str(); 48 | const char *dbName = m_connectionUri.path().isNullOrEmpty() ? NULL : m_connectionUri.path().c_str(); 49 | unsigned int port = m_connectionUri.port().isNullOrEmpty() ? 0 : m_connectionUri.port().toValue(); 50 | 51 | m_freeDbHandles.reserve(m_poolSize); 52 | m_usedDbHandles.reserve(m_poolSize); 53 | for (size_t i = 0; i < m_poolSize; ++i) 54 | { 55 | MYSQL *mysql = mysql_init(NULL); 56 | MYSQL *dbConn = mysql_real_connect(mysql, host, user, password, dbName, port, NULL, 0); 57 | if (!dbConn) 58 | { 59 | mysql_close(mysql); 60 | std::cerr << "mysql_real_connect(): failed to establish connection to database. "; 61 | std::cerr << m_connectionUri << std::endl; 62 | disconnect(); 63 | return false; 64 | } 65 | m_freeDbHandles.push_back(dbConn); 66 | } 67 | return m_connected = true; 68 | } 69 | 70 | bool MySqlConnector::disconnect() 71 | { 72 | if (!m_connected) 73 | { 74 | std::cerr << "MySqlConnector::disconnect(): database connection was not previously successfully created" << std::endl; 75 | return true; 76 | } 77 | 78 | { 79 | std::lock_guard _guard(m_transactionMutex); 80 | if (m_transactions.size()) 81 | { 82 | std::cerr << "MySqlConnector::disconnect(): there is still non-closed transaction connections left" << std::endl; 83 | return false; 84 | } 85 | } 86 | 87 | { 88 | std::lock_guard _guard(m_poolMutex); 89 | assert(m_usedDbHandles.empty()); 90 | for (size_t i = 0; i < m_freeDbHandles.size(); ++i) 91 | mysql_close(m_freeDbHandles[i]); 92 | m_freeDbHandles.clear(); 93 | 94 | } 95 | return true; 96 | } 97 | 98 | SqlTransactionImpl *MySqlConnector::createTransaction() 99 | { 100 | MYSQL *dbConn = nullptr; 101 | { 102 | std::unique_lock _guard(m_poolMutex); 103 | // check if there's already any free 104 | if (m_freeDbHandles.size()) 105 | { 106 | dbConn = m_freeDbHandles.back(); 107 | m_freeDbHandles.pop_back(); 108 | } 109 | else 110 | { 111 | // predicate against spurious wakes 112 | m_dbHandleFreedEvent.wait(_guard, [this](){ return !m_freeDbHandles.empty(); }); 113 | dbConn = m_freeDbHandles.back(); 114 | m_freeDbHandles.pop_back(); 115 | } 116 | m_usedDbHandles.push_back(dbConn); 117 | } 118 | 119 | MySqlTransactionImpl *result = new MySqlTransactionImpl(dbConn); 120 | { 121 | std::lock_guard _guard(m_transactionMutex); 122 | m_transactions.push_back(result); 123 | } 124 | return result; 125 | } 126 | 127 | bool MySqlConnector::closeTransaction(SqlTransactionImpl *transaction) 128 | { 129 | MYSQL *dbConn = nullptr; 130 | { 131 | std::lock_guard _guard(m_transactionMutex); 132 | MySqlTransactionImpl *mysqlTransaction = reinterpret_cast(transaction); 133 | dbConn = mysqlTransaction->dbConn(); 134 | auto it = std::find(m_transactions.begin(), m_transactions.end(), mysqlTransaction); 135 | if (it == m_transactions.end()) 136 | return false; 137 | m_transactions.erase(it); 138 | delete mysqlTransaction; 139 | } 140 | 141 | { 142 | std::lock_guard _guard(m_poolMutex); 143 | auto it = std::find(m_usedDbHandles.begin(), m_usedDbHandles.end(), dbConn); 144 | if (it == m_usedDbHandles.end()) 145 | throw std::runtime_error("MySqlConnector: No such used dbConn in connection pool"); 146 | m_usedDbHandles.erase(it); 147 | m_freeDbHandles.push_back(dbConn); 148 | m_dbHandleFreedEvent.notify_all(); 149 | } 150 | return true; 151 | } 152 | 153 | SqlSyntax MySqlConnector::sqlSyntax() const 154 | { 155 | return SqlSyntaxMySql; 156 | } 157 | 158 | void MySqlConnector::setConnectionPooling(size_t size) 159 | { 160 | if (size == 0 || size > 10) 161 | throw std::invalid_argument("size"); 162 | m_poolSize = size; 163 | } 164 | 165 | std::unique_ptr MySqlConnectorFactory::createInstance(const Uri &uri) 166 | { 167 | return std::unique_ptr(new MySqlConnector(uri)); 168 | } 169 | 170 | } // namespace mysql 171 | } // namespace connectors 172 | } // namespace sql 173 | } // namespace db 174 | } // namespace metacpp 175 | 176 | -------------------------------------------------------------------------------- /src/core/Object.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef OBJECT_H 17 | #define OBJECT_H 18 | #include "config.h" 19 | #include "MetaObject.h" 20 | #include 21 | 22 | namespace metacpp 23 | { 24 | 25 | namespace detail 26 | { 27 | class VariantData; 28 | } 29 | 30 | /** \brief Base class for objects supporting property and method reflection via MetaObject. 31 | * 32 | * All other object should derive from this class, must be default constructible and have 33 | * metainformation descriptor, generated using special macros. 34 | * 35 | * TODO: need detailed usage example here 36 | */ 37 | class Object 38 | { 39 | public: 40 | Object(); 41 | Object(const Object& other); 42 | 43 | virtual ~Object(); 44 | 45 | /** 46 | \brief Destroys object previously created using MetaObject::createInstance 47 | */ 48 | void deleteThis(); 49 | 50 | /** 51 | \brief initializes object with default values from metainfo 52 | \throws std::invalid_argument 53 | */ 54 | void init(); 55 | 56 | #ifdef HAVE_JSONCPP 57 | /** 58 | \brief Performs json object serialization 59 | \throws std::invalid_argument 60 | */ 61 | String toJson(bool prettyFormatted = true) const; 62 | 63 | /** 64 | \brief Performs json object deserialization 65 | \throws std::invalid_argument 66 | */ 67 | void fromJson(const String &s, const Array& knownTypes = Array()); 68 | #endif 69 | 70 | #ifdef HAVE_MONGODB 71 | /** 72 | \brief Performs bson object serialization 73 | \throws std::invalid_argument 74 | */ 75 | ByteArray toBson() const; 76 | 77 | /** 78 | \brief Performs bson object deserialization 79 | \throws std::invalid_argument 80 | */ 81 | void fromBson(const void *data); 82 | #endif 83 | 84 | /** \brief Calls reflection own method on this object 85 | * \param methodName - case-sensetive name of the method 86 | * \param args - array of arguments to pass to the calling function 87 | */ 88 | Variant invoke(const String& methodName, const VariantArray& args); 89 | 90 | /** \brief Calls reflection const own method on this object 91 | * \param methodName - case-sensetive name of the method 92 | * \param args - array of arguments to pass to the calling function 93 | */ 94 | Variant invoke(const String& methodName, const VariantArray& args) const; 95 | 96 | /** \brief Calls reflection const own method on this object 97 | * \param methodName - case-sensetive name of the method 98 | * \param args - array of arguments to pass to the calling function 99 | */ 100 | template 101 | TRet invoke(const String& methodName, TArgs... args) 102 | { 103 | return variant_cast(invoke(methodName, { args... })); 104 | } 105 | 106 | /** \brief Calls reflection const own method on this object 107 | * \param methodName - case-sensetive name of the method 108 | * \param args - array of arguments to pass to the calling function 109 | */ 110 | template 111 | TRet invoke(const String& methodName, TArgs... args) const 112 | { 113 | return variant_cast(invoke(methodName, { args... })); 114 | } 115 | 116 | /** \brief Sets a static or dynamic field of the object */ 117 | void setProperty(const String& propName, const Variant& val); 118 | /** \brief Gets object's static or dynamic field */ 119 | Variant getProperty(const String& propName) const; 120 | /** \brief Returns the MetaObject instance for the object */ 121 | virtual const MetaObject *metaObject() const = 0; 122 | /** \brief Returns the MetaObject instance for the class */ 123 | static const MetaObject *staticMetaObject(); 124 | protected: 125 | Object& operator=(const Object& rhs); 126 | private: 127 | Variant doInvoke(const String& methodName, const VariantArray& args, bool constness) const; 128 | private: 129 | std::map m_dynamicProperties; 130 | static const MetaObject ms_metaObject; 131 | friend class MetaObject; 132 | friend class detail::VariantData; 133 | }; 134 | 135 | /** \brief Macro which must be presented in declaration of classes derived from metacpp::Object 136 | * \relates metacpp::Object 137 | */ 138 | #define META_INFO_DECLARE(ObjName) \ 139 | public: \ 140 | const ::metacpp::MetaObject *metaObject() const override; \ 141 | static const ::metacpp::MetaObject *staticMetaObject(); \ 142 | private: \ 143 | static const ::metacpp::MetaObject ms_metaObject; 144 | 145 | /** \brief Macro which must be presented in definition of classes derived from metacpp::Object 146 | * \relates metacpp::Object 147 | */ 148 | #define META_INFO(ObjName) \ 149 | const ::metacpp::MetaObject ObjName::ms_metaObject(&REFLECTIBLE_DESCRIPTOR(ObjName)); \ 150 | const ::metacpp::MetaObject *ObjName::metaObject() const { return &ms_metaObject; } \ 151 | const ::metacpp::MetaObject *ObjName::staticMetaObject() { return &ms_metaObject; } 152 | 153 | /** \brief Get offset of the field into the struct */ 154 | template 155 | static constexpr ptrdiff_t getMemberOffset(const TField TObj::*member) 156 | { 157 | return reinterpret_cast(&(reinterpret_cast(NULL)->*member)); 158 | } 159 | 160 | /** \brief Get a correspondig MetaFieldBase for the specified public field. 161 | * Usage: getMetaField(&Object::field); */ 162 | template 163 | static constexpr const MetaFieldBase *getMetaField(const TField TObj::*member) 164 | { 165 | return TObj::staticMetaObject()->fieldByOffset(getMemberOffset(member)); 166 | } 167 | 168 | REFLECTIBLE_DESCRIPTOR_DECLARE(Object) 169 | 170 | } // namespace metacpp 171 | #endif // OBJECT_H 172 | -------------------------------------------------------------------------------- /src/utils/SharedDataPointer.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright 2014-2015 Trefilov Dmitrij * 3 | * * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); * 5 | * you may not use this file except in compliance with the License. * 6 | * You may obtain a copy of the License at * 7 | * * 8 | * http://www.apache.org/licenses/LICENSE-2.0 * 9 | * * 10 | * Unless required by applicable law or agreed to in writing, software * 11 | * distributed under the License is distributed on an "AS IS" BASIS, * 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 13 | * See the License for the specific language governing permissions and * 14 | * limitations under the License. * 15 | ****************************************************************************/ 16 | #ifndef SHAREDDATAPOINTER_H 17 | #define SHAREDDATAPOINTER_H 18 | #include "config.h" 19 | #include "SharedDataBase.h" 20 | #include 21 | 22 | namespace metacpp 23 | { 24 | namespace detail 25 | { 26 | class VariantData; 27 | } 28 | /** \brief Template class holding a shared reference to SharedDataBase */ 29 | template 30 | class SharedDataPointer { 31 | 32 | public: 33 | typedef T Type; 34 | 35 | SharedDataPointer() 36 | : m_d(nullptr) 37 | { 38 | } 39 | 40 | SharedDataPointer(const SharedDataPointer& other) 41 | : m_d(other.m_d) 42 | { 43 | if (m_d) m_d->ref(); 44 | } 45 | 46 | SharedDataPointer(SharedDataPointer&& other) 47 | { 48 | *this = std::move(other); 49 | } 50 | 51 | SharedDataPointer& operator=(SharedDataPointer&& rhs) 52 | { 53 | clear(); 54 | m_d = rhs.m_d; 55 | rhs.clear(); 56 | return *this; 57 | } 58 | 59 | virtual ~SharedDataPointer() 60 | { 61 | clear(); 62 | } 63 | 64 | inline bool operator==(const SharedDataPointer& rhs) const { return m_d == rhs.m_d; } 65 | inline bool operator!=(const SharedDataPointer& rhs) const { return m_d == rhs.m_d; } 66 | inline bool operator==(const T *rhs) const { return m_d == rhs; } 67 | inline bool operator!=(const T *rhs) const { return m_d == rhs; } 68 | 69 | // use copy-on-write technique 70 | inline T& operator*() { detach(); return *m_d; } 71 | inline const T& operator*() const { return *m_d; } 72 | inline T& operator->() { detach(); return *m_d; } 73 | inline const T& operator->() const { return *m_d; } 74 | 75 | SharedDataPointer& operator=(const SharedDataPointer& o) 76 | { 77 | if (o.m_d != m_d) 78 | { 79 | if (m_d && ! m_d->deref()) delete m_d; 80 | m_d = o.m_d; 81 | if (m_d) m_d->ref(); 82 | } 83 | return *this; 84 | } 85 | 86 | SharedDataPointer& operator=(const T *d) 87 | { 88 | if (d != m_d) 89 | { 90 | if (m_d && ! m_d->deref()) delete m_d; 91 | m_d = d; 92 | if (m_d) m_d->ref(); 93 | } 94 | return *this; 95 | } 96 | 97 | int refCount() const { return m_d ? m_d->count() : 0; } 98 | 99 | protected: 100 | explicit SharedDataPointer(T *data) : m_d(data) 101 | { 102 | } 103 | 104 | T *data() const { return m_d; } 105 | 106 | SharedDataPointer& swap(const SharedDataPointer& o) 107 | { 108 | std::swap(m_d, o.m_d); 109 | return *this; 110 | } 111 | 112 | void clear() 113 | { 114 | if (m_d && !m_d->deref()) 115 | delete m_d; 116 | m_d = nullptr; 117 | } 118 | 119 | /** 120 | \brief performs a deep copy of the shared data and sets it as a private data 121 | */ 122 | void detach() 123 | { 124 | if (m_d) 125 | { 126 | if (m_d->count() == 1) return; 127 | T *new_d = reinterpret_cast(m_d->clone()); 128 | if (!m_d->deref()) delete m_d; 129 | m_d = new_d; 130 | } 131 | } 132 | 133 | template 134 | void detachOrInitialize(TArgs... args) 135 | { 136 | if (m_d) 137 | { 138 | if (m_d->count() == 1) return; 139 | T *new_d = reinterpret_cast(m_d->clone()); 140 | if (!m_d->deref()) delete m_d; 141 | m_d = new_d; 142 | } 143 | else 144 | m_d = new T(args...); 145 | } 146 | 147 | T *m_d; 148 | }; 149 | 150 | template 151 | class SharedObjectPointer : protected SharedDataPointer > 152 | { 153 | public: 154 | SharedObjectPointer() = default; 155 | 156 | template > 157 | explicit SharedObjectPointer(T *pObj, const Deleter& deleter = Deleter()) 158 | : SharedDataPointer >(new SharedObjectData(pObj, deleter)) 159 | { 160 | } 161 | 162 | ~SharedObjectPointer() = default; 163 | 164 | T *get() const { 165 | return this->m_d ? this->m_d->get() : nullptr; 166 | } 167 | 168 | void reset(T *pObj) { 169 | if (this->m_d) 170 | { 171 | this->detach(); 172 | this->m_d->reset(pObj); 173 | } 174 | else 175 | this->m_d = new SharedObjectData(pObj); 176 | } 177 | 178 | void swap(const SharedObjectPointer& other) 179 | { 180 | std::swap(this->m_d, other.m_d); 181 | } 182 | 183 | operator bool() const { 184 | return get() != nullptr; 185 | } 186 | 187 | T& operator*() const { 188 | assert(this->m_d); 189 | return *this->m_d->get(); 190 | } 191 | 192 | T *operator->() const { 193 | return get(); 194 | } 195 | private: 196 | 197 | T *extract() { 198 | this->detach(); // will throw an exception if there's more than one instance pointing to the object 199 | return this->m_d ? this->m_d->extract() : nullptr; 200 | } 201 | 202 | friend class detail::VariantData; 203 | }; 204 | 205 | } // namespace metacpp 206 | #endif // SHAREDDATAPOINTER_H 207 | --------------------------------------------------------------------------------