Skip to content

Commit

Permalink
Merge pull request #208 from fnc12/dev
Browse files Browse the repository at this point in the history
Dev to master for 1.3
  • Loading branch information
fnc12 authored Apr 9, 2019
2 parents 8ee3d47 + 0803e96 commit 24283f6
Show file tree
Hide file tree
Showing 71 changed files with 6,401 additions and 2,178 deletions.
14 changes: 12 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ script:
- clang -c sqlite-amalgamation-3190300/sqlite3.c -o sqlite.static
- clang++ -std=c++1y tests/tests.cpp sqlite.static -I include/ -I sqlite_amalgamation/ -ldl -lpthread -stdlib=libc++ -o tests.out
- ./tests.out
- clang++ -std=c++1y tests/tests.cpp sqlite.static -I include/ -I sqlite_amalgamation/ -ldl -lpthread -stdlib=libc++ -D SQLITE_ORM_OMITS_CODECVT -o tests_without_codecvt.out
- ./tests_without_codecvt.out
- clang++ -std=c++1y tests/static_tests.cpp sqlite.static -I include/ -I sqlite_amalgamation/ -ldl -lpthread -stdlib=libc++ -o static_tests.out
- ./static_tests.out
- clang++ -std=c++1y examples/core_functions.cpp sqlite.static -I include/ -I sqlite_amalgamation/ -ldl -lpthread -o a.out
Expand Down Expand Up @@ -49,8 +51,6 @@ script:
- ./a.out
- clang++ -std=c++1y examples/blob.cpp sqlite.static -I include/ -I sqlite_amalgamation/ -ldl -lpthread -o a.out
- ./a.out
- clang++ -std=c++1y examples/private_class_members.cpp sqlite.static -I include/ -I sqlite_amalgamation/ -ldl -lpthread -o a.out
- ./a.out
- clang++ -std=c++1y examples/foreign_key.cpp sqlite.static -I include/ -I sqlite_amalgamation/ -ldl -lpthread -o a.out
- ./a.out
- clang++ -std=c++1y examples/index.cpp sqlite.static -I include/ -I sqlite_amalgamation/ -ldl -lpthread -o a.out
Expand All @@ -69,3 +69,13 @@ script:
- ./a.out
- clang++ -std=c++1y examples/union.cpp sqlite.static -I include/ -I sqlite_amalgamation/ -ldl -lpthread -o a.out
- ./a.out
- clang++ -std=c++1y examples/subquery.cpp sqlite.static -I include/ -I sqlite_amalgamation/ -ldl -lpthread -o a.out
- ./a.out
- clang++ -std=c++1y examples/having.cpp sqlite.static -I include/ -I sqlite_amalgamation/ -ldl -lpthread -o a.out
- ./a.out
- clang++ -std=c++1y examples/exists.cpp sqlite.static -I include/ -I sqlite_amalgamation/ -ldl -lpthread -o a.out
- ./a.out
- clang++ -std=c++1y examples/except_intersection.cpp sqlite.static -I include/ -I sqlite_amalgamation/ -ldl -lpthread -o a.out
- ./a.out
- clang++ -std=c++1y examples/custom_aliases.cpp sqlite.static -I include/ -I sqlite_amalgamation/ -ldl -lpthread -o a.out
- ./a.out
61 changes: 59 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,55 @@ cmake_minimum_required (VERSION 3.2)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

project(sqlite_orm)
# PACKAGE_VERSION is used by cpack scripts currently
# Both sqlite_orm_VERSION and PACKAGE_VERSION should be the same for now

set(sqlite_orm_VERSION "1.3.0")
set(PACKAGE_VERSION ${sqlite_orm_VERSION})

project("sqlite_orm" VERSION ${PACKAGE_VERSION})

message(STATUS "Configuring ${CMAKE_PROJECT_NAME} ${sqlite_orm_VERSION}")

set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${CMAKE_CURRENT_SOURCE_DIR}/build/cmake")

# Build time options are defined here
include(DefineInstallationPaths)

# Generate the SqliteOrmConfig.cmake module
include(GenerateConfigModule)

set(ProjectName "SqliteOrm")

option(SqliteOrm_BuildTests "Build sqlite_orm unit tests" ON)

set(SqliteOrm_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/include")
add_library(sqlite_orm INTERFACE)
target_include_directories(sqlite_orm INTERFACE include)

target_sources(sqlite_orm INTERFACE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include/sqlite_orm/sqlite_orm.h>
$<INSTALL_INTERFACE:include/sqlite_orm/sqlite_orm.h>)

target_include_directories(sqlite_orm INTERFACE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)

include(ucm)

if (MSVC)
string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
add_compile_options(/EHsc)

if ("${CMAKE_GENERATOR}" MATCHES "(Win64|x64)")
message(STATUS "Add /bigobj flag to compiler")
add_compile_options(/bigobj)
endif()
endif()

ucm_print_flags()
message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")

# Tests
include(CTest)
Expand All @@ -19,3 +61,18 @@ endif()

add_subdirectory(examples)

install(TARGETS sqlite_orm EXPORT "${ProjectName}Targets"
INCLUDES DESTINATION "${INCLUDE_INSTALL_DIR}" COMPONENT Development
PUBLIC_HEADER DESTINATION "${INCLUDE_INSTALL_DIR}" COMPONENT Development)

install(FILES "include/sqlite_orm/sqlite_orm.h"
DESTINATION "${INCLUDE_INSTALL_DIR}" COMPONENT Development)

export(EXPORT "${ProjectName}Targets"
FILE "${CMAKE_CURRENT_BINARY_DIR}/${ProjectName}/${ProjectName}Targets.cmake"
NAMESPACE "sqlite_orm::")

install(EXPORT "${ProjectName}Targets"
FILE "${ProjectName}Targets.cmake"
NAMESPACE "sqlite_orm::"
DESTINATION "${CMAKE_INSTALL_DIR}/sqlite_orm")
30 changes: 19 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,19 @@
</p>

[![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
[![Build Status](https://travis-ci.org/fnc12/sqlite_orm.svg?branch=master)](https://travis-ci.org/fnc12/sqlite_orm)
[![Donate using PayPal](https://img.shields.io/badge/donate-PayPal-brightgreen.svg)](https://paypal.me/fnc12)
[![Twitter URL](https://img.shields.io/twitter/url/https/twitter.com/fold_left.svg?style=social&label=Follow%20%40sqlite_orm)](https://twitter.com/sqlite_orm)


# SQLite ORM
SQLite ORM light header only library for modern C++

# Status
| Branch | Travis | Appveyor | Coverity Scan | codecov.io | Website |
| :----- | :----- | :------- | :------------ | :--------- | :------ |
| [`master`](https://github.com/fcn12/sqlite_orm/tree/master) | [![Build Status](https://travis-ci.org/fnc12/sqlite_orm.svg?branch=master)](https://travis-ci.org/fcn12/sqlite_orm) | [![Build status](https://ci.appveyor.com/api/projects/status/github/fnc12/sqlite_orm?branch=master&svg=true)](https://ci.appveyor.com/project/fnc12/sqlite-orm/history) | | | [![Website](https://img.shields.io/badge/official-website-brightgreen.svg)](https://github.com/fcn12/sqlite_orm/) |
| [`dev`](https://github.com/fcn12/sqlite_orm/tree/dev) | [![Build Status](https://travis-ci.org/fnc12/sqlite_orm.svg?branch=dev)](https://travis-ci.org/fcn12/sqlite_orm) | [![Build status](https://ci.appveyor.com/api/projects/status/github/fnc12/sqlite_orm?branch=dev&svg=true)](https://ci.appveyor.com/project/fnc12/sqlite-orm/history) | | | [![Website](https://img.shields.io/badge/official-website-brightgreen.svg)](https://github.com/fcn12/sqlite_orm/tree/dev) |

# Advantages

* **No raw string queries**
Expand All @@ -17,6 +24,7 @@ SQLite ORM light header only library for modern C++
* **Built with modern C++14 features (no macros and external scripts)**
* **CRUD support**
* **Pure select query support**
* **UNION, EXCEPT and INTERSECT support**
* **STL compatible**
* **Custom types binding support**
* **BLOB support** - maps to `std::vector<char>` or one can bind your custom type
Expand Down Expand Up @@ -47,7 +55,7 @@ struct User{
std::string firstName;
std::string lastName;
int birthDate;
std::shared_ptr<std::string> imageUrl;
std::unique_ptr<std::string> imageUrl;
int typeId;
};

Expand Down Expand Up @@ -93,7 +101,7 @@ More details about making storage can be found in [tutorial](https://github.com/
Let's create and insert new `User` into database. First we need to create a `User` object with any id and call `insert` function. It will return id of just created user or throw exception if something goes wrong.

```c++
User user{-1, "Jonh", "Doe", 664416000, std::make_shared<std::string>("url_to_heaven"), 3 };
User user{-1, "Jonh", "Doe", 664416000, std::make_unique<std::string>("url_to_heaven"), 3 };

auto insertedId = storage.insert(user);
cout << "insertedId = " << insertedId << endl; // insertedId = 8
Expand All @@ -118,17 +126,17 @@ try{
}
```

Probably you may not like throwing exceptions. Me too. Exception `std::system_error` is thrown because return type in `get` function is not nullable. You can use alternative version `get_no_throw` which returns `std::shared_ptr` and doesn't throw `not_found_exception` if nothing found - just returns `nullptr`.
Probably you may not like throwing exceptions. Me too. Exception `std::system_error` is thrown because return type in `get` function is not nullable. You can use alternative version `get_pointer` which returns `std::unique_ptr` and doesn't throw `not_found_exception` if nothing found - just returns `nullptr`.

```c++
if(auto user = storage.get_no_throw<User>(insertedId)){
if(auto user = storage.get_pointer<User>(insertedId)){
cout << "user = " << user->firstName << " " << user->lastName << endl;
}else{
cout << "no user with id " << insertedId << endl;
}
```

`std::shared_ptr` is used as optional in `sqlite_orm`. Of course there is class optional in C++14 located at `std::experimental::optional`. But we don't want to use it until it is `experimental`.
`std::unique_ptr` is used as optional in `sqlite_orm`. Of course there is class optional in C++14 located at `std::experimental::optional`. But we don't want to use it until it is `experimental`.

We can also update our user. It updates row by id provided in `user` object and sets all other non `primary_key` fields to values stored in the passed `user` object. So you can just assign members to `user` object you want and call `update`

Expand Down Expand Up @@ -180,7 +188,7 @@ for(auto &user : storage.iterate<User>()) {

`iterate` member function returns adapter object that has `begin` and `end` member functions returning iterators that fetch object on dereference operator call.

CRUD functions `get`, `get_no_throw`, `remove`, `update` (not `insert`) work only if your type has a primary key column. If you try to `get` an object that is mapped to your storage but has no primary key column a `std::system_error` will be thrown cause `sqlite_orm` cannot detect an id. If you want to know how to perform a storage without primary key take a look at `date_time.cpp` example in `examples` folder.
CRUD functions `get`, `get_pointer`, `remove`, `update` (not `insert`) work only if your type has a primary key column. If you try to `get` an object that is mapped to your storage but has no primary key column a `std::system_error` will be thrown cause `sqlite_orm` cannot detect an id. If you want to know how to perform a storage without primary key take a look at `date_time.cpp` example in `examples` folder.

# Aggregate Functions

Expand Down Expand Up @@ -215,21 +223,21 @@ cout << "concatedUserIdWithDashes = " << concatedUserIdWithDashes << endl;

// SELECT MAX(id) FROM users
if(auto maxId = storage.max(&User::id)){
cout << "maxId = " << *maxId <<endl; // maxId = 12 (maxId is std::shared_ptr<int>)
cout << "maxId = " << *maxId <<endl; // maxId = 12 (maxId is std::unique_ptr<int>)
}else{
cout << "maxId is null" << endl;
}

// SELECT MAX(first_name) FROM users
if(auto maxFirstName = storage.max(&User::firstName)){
cout << "maxFirstName = " << *maxFirstName << endl; // maxFirstName = Jonh (maxFirstName is std::shared_ptr<std::string>)
cout << "maxFirstName = " << *maxFirstName << endl; // maxFirstName = Jonh (maxFirstName is std::unique_ptr<std::string>)
}else{
cout << "maxFirstName is null" << endl;
}

// SELECT MIN(id) FROM users
if(auto minId = storage.min(&User::id)){
cout << "minId = " << *minId << endl; // minId = 1 (minId is std::shared_ptr<int>)
cout << "minId = " << *minId << endl; // minId = 1 (minId is std::unique_ptr<int>)
}else{
cout << "minId is null" << endl;
}
Expand All @@ -242,7 +250,7 @@ if(auto minLastName = storage.min(&User::lastName)){
}

// SELECT SUM(id) FROM users
if(auto sumId = storage.sum(&User::id)){ // sumId is std::shared_ptr<int>
if(auto sumId = storage.sum(&User::id)){ // sumId is std::unique_ptr<int>
cout << "sumId = " << *sumId << endl;
}else{
cout << "sumId is null" << endl;
Expand Down
9 changes: 6 additions & 3 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@
* `FOREIGN KEY` - sync_schema fk comparison and ability of two tables to have fk to each other
* rest of core functions(https://sqlite.org/lang_corefunc.html)
* `CASE`
* `HAVING`
* `EXISTS`
* asterisk in raw select: `SELECT rowid, * FROM table`
* `ATTACH`
* blob incremental I/O https://sqlite.org/c3ref/blob_open.html
* reusing of prepared statements - useful for query optimisation
* subselect
* explicit FROM for subqueries in FROM argument
* backup API https://www.sqlite.org/backup.html
* busy handler https://sqlite.org/c3ref/busy_handler.html
* CAST https://sqlite.org/lang_expr.html#castexpr
* CREATE VIEW and other view operations https://sqlite.org/lang_createview.html
* triggers
* query static check for correct order (e.g. `GROUP BY` after `WHERE`)
* column alias
* `FULL OUTER JOIN`
* `WINDOW`
* `UPSERT` https://www.sqlite.org/lang_UPSERT.html

Please feel free to add any feature that isn't listed here and not implemented yet.
42 changes: 42 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright (c) 2012-2019 Sebastien Rombauts ([email protected])

# build format
version: "{build}"

# scripts that run after cloning repository
install:
- git submodule update --init --recursive

image:
- Visual Studio 2017

# configurations to add to build matrix
# TODO: MinGW Makefiles and MSYS Makefiles
configuration:
- Debug
- Release

environment:
matrix:
- arch: Win32
- arch: Win64

init:
- echo %APPVEYOR_BUILD_WORKER_IMAGE% - %configuration% - %arch%
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" (set vs=Visual Studio 15 2017)
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" (set vs=Visual Studio 14 2015)
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2013" (set vs=Visual Studio 12 2013)
- if "%arch%"=="Win64" (set generator="%vs% Win64")
- if "%arch%"=="Win32" (set generator="%vs%")
- echo %generator%

# scripts to run before build
before_build:
- mkdir compile
- cd compile
- cmake -DSqliteOrm_BuildTests=ON .. -G %generator%

# build examples, and run tests (ie make & make test)
build_script:
- cmake --build . --config %configuration%
- ctest --output-on-failure --build-config %configuration%
12 changes: 12 additions & 0 deletions build/cmake/DefineInstallationPaths.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Define the default install paths
set(BIN_INSTALL_DIR "bin" CACHE PATH "The binary install dir (default: bin)")
set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}" CACHE PATH "The library install dir (default: lib${LIB_SUFFIX})")
set(INCLUDE_INSTALL_DIR "include" CACHE PATH "The library install dir (default: include)")
set(CMAKE_INSTALL_DIR "lib/cmake" CACHE PATH "The subdirectory to install cmake config files (default: cmake)")
set(PKGCONFIG_INSTALL_DIR "lib/pkgconfig" CACHE PATH "The subdirectory to install pkgconfig config files (default: lib/pkgconfig)")
set(DOC_INSTALL_DIR "share/doc" CACHE PATH "The subdirectory to install documentation files (default: share/doc)")
set(prefix "${CMAKE_INSTALL_PREFIX}")
set(exec_prefix "${CMAKE_INSTALL_PREFIX}/bin")
set(libdir "${CMAKE_INSTALL_PREFIX}/lib")
set(includedir "${CMAKE_INSTALL_PREFIX}/include")
set(cmakedir "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DIR}")
24 changes: 24 additions & 0 deletions build/cmake/GenerateConfigModule.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
include(CMakePackageConfigHelpers)

set(PACKAGE_INCLUDE_INSTALL_DIR "${includedir}/sqlite_orm")
set(PACKAGE_CMAKE_INSTALL_DIR "${cmakedir}/sqlite_orm")

# In CYGWIN enviroment below commands does not work properly
if (NOT CYGWIN)
configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/build/cmake/SqliteOrmConfig.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/SqliteOrmConfig.cmake"
INSTALL_DESTINATION "${CMAKE_INSTALL_DIR}/sqlite_orm"
PATH_VARS
PACKAGE_INCLUDE_INSTALL_DIR
PACKAGE_CMAKE_INSTALL_DIR
)

write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/SqliteOrmConfigVersion.cmake"
VERSION ${sqlite_orm_VERSION}
COMPATIBILITY SameMajorVersion
)

install(FILES "${CMAKE_CURRENT_BINARY_DIR}/SqliteOrmConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/SqliteOrmConfigVersion.cmake"
DESTINATION "${CMAKE_INSTALL_DIR}/sqlite_orm")
endif()
22 changes: 22 additions & 0 deletions build/cmake/SqliteOrmConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
set(SQLITE_ORM_VERSION ${sqlite_orm_VERSION})

@PACKAGE_INIT@

set_and_check(SQLITE_ORM_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
set_and_check(SQLITE_ORM_CMAKE_DIR "@PACKAGE_CMAKE_INSTALL_DIR@")

if (NOT TARGET sqlite_orm::sqlite_orm)
include("${SQLITE_ORM_CMAKE_DIR}/SqliteOrmTargets.cmake")
endif()

set(SQLITE_ORM_LIBRARIES sqlite_orm::sqlite_orm)

if ("${SQLITE_ORM_LIBRARIES}" STREQUAL "")
message(FATAL_ERROR "sqlite_orm libraries were not found")
endif()

if (NOT SqliteOrm_FIND_QUIETLY)
message(STATUS "Found sqlite_orm: ${PACKAGE_PREFIX_DIR}")
endif()

check_required_components(SqliteOrm)
Loading

0 comments on commit 24283f6

Please sign in to comment.