mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-27 00:50:45 +00:00
79e222e3c [Travis] Switch to latest Oracle downloader v2.0.3 3992cd8f6 [Travis] Try travis-oracle downloader hotfix 958f1b010 [Travis] Use only ORACLE_LOGIN_userid and ORACLE_LOGIN_pass f03569ffe [Travis] Oracle has changed login form 682486db9 Merge pull request #607 from rocksolidwebdesign/master e8ed51c37 use fully qualified soci::session to fix build on macosx sierra c98c877bc [doc] Add note on factory objects not exported from DLLs d0552e64a Catch unhandled exception in PostgreSQL ODBC unit test 643853322 Add missing -DWITH_POSTGRESQL=ON to scripts\build.bat 82867ced7 [docs] Clarify name of MySQL package with client library a35851478 Complete scripts\built.bat with basic CMake options. 225d5a3a4 [CMake] Simplify warning messages d90a7acfc [docs] Fix CMake options for SQLite 3 3d32f5253 Merge pull request #596 from mloskot/ml/macro-soci-override 5d980ee98 Merge pull request #600 from mloskot/ml/cmake-update-FindDB2 05ab0bcf6 Add SOCI_OVERRIDE macro as conditional C++11 override specifier aa9744e0a [DB2] Add additional install paths to search for DB2 client 3069f242b Merge pull request #594 from mloskot/ml/cmake-postgresql-nosinglerow a5bb763ab Merge pull request #599 from mloskot/ml/cmake-drop-cdash 466fdf32c [docs] Update name DB2 driver/client library name a7f5240a1 [CMake] Add SOCI_POSTGRESQL_NOSINLGEROWMODE option (default OFF) 601a89227 [CMake] Remove CDash remains fffe6d9c8 [CMake] Tidy up FindOracle.cmake formatting 6157f8d97 [CMake] Add /usr/lib/oracle/*/client${LIB_SUFFIX} to searched paths bbc18d73d [firebird] Add Ubuntu firebird-dev package as dependency example fd18f5c6c [CMake] Determine LIB_SUFFIX from SOCI_TARGET_ARCH_X64 c5f59c9d3 [Travis] Revert remove of any notifications to soci-devel mailing list f7f2a6123 [Travis] Remove any notifications to soci-devel mailing list 6df733826 [docs] Add pages for Ada language bindings 41f288bf3 Merge pull request #595 from mloskot/ml/db2-null-dereference 62f4bf5c4 [db2] Fix null pointer dereference 340a72eda [CMake] FindPostgreSQL.cmake update lost POSTGRESQL_VERSION return 5da552537 [docs] Remove Ada pages from TOC due to building failure 5e0e70c95 [docs] Add copyright footer ea0f6c11e [docs] Add languages/ada pages to TOC 2ab0fb901 Add CHANGELOG.md generated from GitHub 961368043 Add changelog.sh utility to generate CHANGELOG.md from GitHub 0621bd610 [Circle] Fix missing checkout in workflow 2c45f2bc5 [docs] Fix issues reported by markdownlint 46071f5f6 [docs] Replace HTML tables with Markdown tables 80a86c0eb Format compact table in README 14b693e64 [docs] Avoid markdownlint warnings about line length 13031a831 [docs] Fix README.md linting issues 2d575b8d7 [docs] Add link to master branch docs on docs.html 8427054b7 [Circle] Fix markdownlint invocation cc75d6e09 [Circle] Fix global installation of markdownlint-cli 522c7bbb6 [docs] Add .markdownlint.json configuration file 498381595 [AppVeyor] Add build job with Visual Studio 2017 (#588) fd37e3b80 [AppVeyor] Update badge after switch to organizational account 51d058f04 Repair VC8 compile of test applications (#593) c2310cf54 [Circle] Add markdownlint and define lint-build-deploy workflow for docs b9f4007e4 Fix __GNUC__ condition ignoring -Wmaybe-uninitialized 08fe54076 Ignored -Wmaybe-uninitialized in GCC all versions following 4.7 29be6f860 Merge pull request #592 from mloskot/ml/replace-alternative-tokens a161e24c1 Replace C alternative boolean operator representations with primary tokens 07a23d8a2 [CircleCI] Disable gem. Requires separate docker w/ Ruby df87eb1eb [CircleCI] Install markdownlint gem 92de7a387 [Vagrant] Fix bach if. Silence wget. Add logging. 6b9531179 [Vagrant] Update setup with primary VM and optionals. 4cb3b636f [Travis] Disable clang jobs to save on built times 4e98cd2cf [docs] Add MySQL 8.0.1 on Windows to tested versions 275965736 Add CMake options to disable/enable individual backends. cba05c702 Add build.bat for convenience of Visual Studio users 67c479ed9 Merge pull request #590 from mloskot/ml/cmake-update-FindPostgreSQL 35d2df6f4 [cmake] Update FindPostgreSQL.cmake from CMake 3.9 4fdfbf817 [cmake] Improve testing of Abc_FOUND and ABC_FOUND variables 3f006d3ae Fix copy-paste typo error in README bd3ee7a48 [CI] Fix webhook specs and events d31d17be3 [CI] Fix webhook URLs and use default events 34ced08e3 Fix URLs for badges in README 1653bd0b7 Update badges in README 7a4704be3 [Travis] Update webhook for notifications on gitter.im/SOCI/soci 17167fd97 [AppVeyor] Update webhook for notifications on gitter.im/SOCI/soci 95e55689e [Circle] Update webhook for notifications on gitter.im/SOCI/soci 68b914b19 Add footer: BSL © Maciej Sobczak and contributors. 8bf913e9c [Circle] Add webhook to receive notification on Gitter chat 25b2ab9af Actually link the generated docs 4aa8d5ab9 Link docs generated for master as (development) a40420e4c [Circle] Use API token for the badge fc59a621c [Circle] Fix status badge 15eba50e8 Add CircleCI setup to build docs and deploy to SF.net 3fa0a58cb [EditorConfig] Add settings for YAML and CMake scripts b36f437bc Merge branch 'more-xml' b85ec90c6 Check that inserting malformed XML values fails 2b89a134a Enable XML/CLOB tests for PostgreSQL via ODBC 6e4732102 Add very simple XML and CLOB support to ODBC backend fabb8f0f0 Make XML comparison in the test work for SQL Server too 11a8982d5 Add a helper function for copying strings in ODBC backend too 556f5d336 Add exchange_type_traits<> specializations for XML and CLOB f1243acdf Add helper function for copying string to PostgreSQL backend 5e6f37e35 Document types used for XML and CLOB support in Firebird backend bd236c8c8 Merge branch 'xml-firebird' e6e1ad305 Merge pull request #585 from mloskot/ml/enable-oracle-for-pulls 0cadedaf5 Enable Oracle builds for pull requests 93e844d02 [Travis] Update Oracle installation setup 3a82540aa Also throw if unsupported type is used for vector "into" in DB2 0f1756c55 Throw if unsupported type is used for vector "into" parameter 3a7677425 Merge branch 'odbc-vec-into-null' ff2464925 Merge branch 'oracle-fix-null-str' 023f4df03 Skip running Oracle tests for PR builds on Travis CI df4039923 Fix bug with null strings in bull selections in ODBC and DB2 6ca9cd64a Add REQUIRE_NOTHROW() around SQL statements in the string test 63bcc8944 Add workaround for empty strings being null in Oracle 2d74f9aaa Merge pull request #579 from mloskot/ml/travis-oracle-restore c3b943c87 Restore Oracle build job on Travis CI 9943459f4 Add support for XML type to Firebird backend too 059faf5d9 Add CLOB support to Firebird backend 85159db6f Refactor: move XML and CLOB tests to common code 4744c1705 Fix the build after the previous commit 201c89f0e Fixed wrong handling of errors in single-row mode for PostgreSQL. e26d134b4 Merge pull request #577 from mloskot/ml/bin-to-scripts 6363537e6 Add Windows shell scripts with CRLF to .editorconfig d38b21ca6 Move directory /bin to /scripts 316885a37 Merge pull request #576 from alexott/editorconfig 461a44585 Update .editorconfig with comments from review 2c7c312d7 Add support for EditorConfig 09c26314d Allow defining SOCI_POSTGRESQL_NOSINLGEROWMODE for PostgreSQL < 9 4b451971a Avoid using overloaded virtual methods in vector type backends f6980d2ce Merge pull request #572 from alexott/coverity-fixes 23d2f2593 fix some of warnings from fresh Coverity report 25eb5bdb3 Initialize indISCHolder_ member in firebird_into/use_type_backend classes 042dc0fd9 Merge pull request #570 from mcencora/master 9d82ee8e7 Remove unnecessary namespace qualification 3db8f4371 cmake: export SOCI public include directories e4ab099df Fix undefined sanitizer warnings 8fdb2e7ea Merge pull request #566 from mloskot/ml/mkdocs 80941a9d9 Update structure of SOCI 4.0.0 documentation 9c8191903 Fixed Makefile build for PostgreSQL (broken by other modifications). e7db59c74 Merge pull request #557 from msobczak/master f6d08a75f Merge pull request #564 from Arenoros/master 43229ecfe Fix types for SQLite3 backend ed25eea2c Fix session::get_table_names() for sqlite backend 7a6559c18 Merge branch 'odbc-string-len' c6aef12b1 Add test checking string length when using bulk insert 51c4c1e1a Fix the length of strings in DB2 vector operations be4f26fea Fix the length of strings in ODBC vector operations 521a84085 Improve get_affected_rows() documentation e7e7fb78a Return -1 from get_affected_rows() in ODBC backend if unknown 97a4728cb Remove loop that could be never executed from ODBC code 1a0eeb186 Fix harmless variable shadowing warnings e7cdd4754 Fix loss of error message in ODBC backend when using vectors 06915e483 Add check for absence of unneeded truncation too 82038018c Merge branch 'refactor-parse-std-tm' 56bc9f9c5 Return int, not long, from parse10() helper 281f54f51 Check for negative date components in parse10() f2e84c4bf Don't pass exception message to parse10() helper a1e07e389 Avoid duplicate code for parsing dates in different backends e2f1ca530 Fix libraries link order when linking tests statically a3685fd09 Fix unused parameter warnings in Oracle backend code 488825079 Explicitly use Ubuntu Precise for Travis builds 638b89d1f Merge remote-tracking branch 'upstream/master' 138b29e43 Lazy initialization of the temporary LOB objects for Oracle. a9ab0db16 Merge pull request #541 from ckaminski/master f938c0133 Get rid of allowed failures in Travis CI configuration 52539f8ab Merge branch 'odbc-mysql-bug' 2aeb32872 Fix reading from unallocated memory in ODBC with MySQL dc05c8e82 Use switch over exchange type in ODBC vector backend code 7bd491cf2 Fix check for clang in CMake configuration 702c214a9 Remove dummy stream insertion overload for boost::optional 1b416275d Remove Travis CI builds using Postgression d7c986c6b Disable MySQL unit test currently always resulting in a crash 2f65f02e8 Define SOCI_SQLITE3_SOURCE in all SQLite3 backend sources 4f1fbfcd4 Suppress memory leak report in glibc NSS under Ubuntu d91c2228c Add get_dummy_from_{table,clause}() methods 78bedc931 Consistently check for connection in the session object methods cf9cfa90c Fix DB2 backend build after x_xmltype and x_longstring additions 4b642ac5c Fixed handling of BINARY_DOUBLE in dynamic row. 2d621e8f3 Fixed memleak when reusing into and use elements. 9bb0f70b6 Revert "Fix inserting strings longer than 8000 bytes with ODBC/MS SQL" 7c28bd6c3 Fix inserting strings longer than 8000 bytes with ODBC/MS SQL b510e1a63 moved to latest Catch UT Framework (#544) 33ae81a71 Merge pull request #545 from snikulov/odbc_handle_defaults 92afc1f91 Use defaults for unsupported types in ODBC 7fba06984 disable autosetting of SOCI_CXX_C11 to OFF fa0e5b5a2 Merge pull request #536 from ddowling/master 723230fcc Support the OCI_SUCCESS_WITH_INFO return code in get_error_details f21578e2a Fix an uninitialised variable access when using the Oracle backend with a database type not in the standard accepted set. a912148f9 Fix uninitialized procedure::gotData_ 646efa070 Merge pull request #534 from mutcher/master 87509d52d Corrections in README.md 34c534722 Export struct sqlite3_soci_error from DLL on Windows. 840100102 Update .gitignore patterns for Visual Studio (Code) dc87a2c58 Docs markdown cleanup. e719c44bb Merge pull request #524 from ravselj/firebird_blob_bug 2edb58395 Firebird backend blob write bug fix. 0a88814c2 Added Firebird specific test indicating BLOB write bug. 6eb1a3e97 Fixed handling of empty long strings. e7194837e Added empty_blob() and nvl() to portable utilities. adae5ade8 Merge pull request #509 from msobczak/xml_clob 45eaff9e9 Added handling of big string in DDL. 9b2d48f3b Merge pull request #510 from mloskot/ml/add-missing-decl 8ae0f3962 Add missing declspec to properly export exception classes. f7b11ca71 Fixed handling of dt_xml in sqlite3. 1655a195e Added bigstring (XML and CLOB) support. 81a48efaf Fixed missing space in DDL. d68170494 Fixed handling of DDL alter column syntax. 1eb4c2935 Merge pull request #508 from msobczak/blob_offset 4b0dbab3e Added uniform offset for BLOB read/write operations. c5e37d273 Merge pull request #503 from wisk/cmake-package-export e082831ce export cmake package ba9963779 travis-ci: Allows to fail for odbc and mysql 92c430669 Merge pull request #454 from snikulov/enable_asan ec746bd1d Merge pull request #375 from ravselj/sqlite_load_one 88b331507 Merge pull request #487 from msobczak/bulkiterators 780a5c5d2 Corrected handling of vectors with user-defined types. 9e83a50c3 Merge pull request #494 from snikulov/fix_travis da09c7c6b Fix travis-ci build 307d94caf Merge pull request #492 from snikulov/av_odbc_driver_name 12708b190 Merge pull request #491 from snikulov/av_mingw_fix 4a0ac2ba3 Fixed driver name and passwd for PostgreSQL ODBC driver on AppVeyor 783e8b089 Fixed MinGW build with proper URL 0142d057f Merge pull request #489 from snikulov/fix_383 0723512f3 fixed #383 8d2901675 Added unit tests and docs for bulk iterators. 2f8a7a05e Added bulk iterators for Oracle and PostgreSQL. 2fcad8b24 Merge pull request #486 from msobczak/failover 002f6a9a7 Added docs for failover. 3daef94c7 Added failover callback for Oracle and PostgreSQL. a0b29bc94 Merge pull request #484 from msobczak/portable-DDL c959c3812 Added Oracle unit tests for DDL and metadata. 2a8e8965e Added PostgreSQL unit tests for DDL and metadata. cbee6429a Typo fixes and improved docs. 4244fae07 Merge pull request #482 from msobczak/PostgreSQL-singlerows 8d2a75baa Added support for portable DDL statements. a0917b7c8 Fixed multiple definitions bug with column_info. 596c6762b Merge pull request #480 from msobczak/metadata b70a4e8b2 Added singlerows mode for PostgreSQL. 816839514 Merge remote-tracking branch 'upstream/master' into metadata 30aca6230 Added docs for error categories. f2b2f4bc0 Added more error codes for error categories in Oracle. a05b61f1f Added docs and removed impractical function for metadata queries. 3c3fec623 Portable metadata queries. cd26169ef Added (partial) handling of OCI_SUCCESS_WITH_INFO in Oracle. 21a062023 Merge pull request #479 from snikulov/fix_478 bb8aaca05 fixed #478 376362493 Merge pull request #474 from wdavilaneto/master 23967e281 Merge pull request #475 from snikulov/cov_fixes ec65da5a5 Fixed uninited local std::tm structs 8cb99538c adding oracle remote connection exemple without tnsnames.ora 56379eb81 Merge pull request #471 from snikulov/fix_travis 25ac65fc5 Travis-CI: allowed failure for DB2 backend 8d8002b7b Merge pull request #470 from snikulov/fix_appvr 2895c7d06 Appveyour now using MySQL 5.7 d419e945a Update AppVeyor badge URL 5c14d49cc Remove info on binding char[] support. 57db62210 Added basic support for error categories. a1d45503b Documented Oracle wallet authentication option. cae51eec9 Added Oracle wallet authentication. 8c6b47977 Added NLS support for connection parameters in Oracle. 912649c2c Merge pull request #459 from shelomentsevd/master 8b70e0983 Documentation. exchange.md cleaned from typos c80646c0d Merge pull request #455 from snikulov/msvc2012_fix 3470079d1 compilation fix for msvc2012 d27fba19a Merge pull request #453 from snikulov/catch_updates 36e8fc91b updated catch.hpp version to 1.3.3 56b0b02b8 added Address Sanitizer to expose memory errors f26138913 Merge pull request #452 from vadz/cxx11 c07a42da0 Merge pull request #451 from vadz/config-vs-platform ec7d2dfc3 Define cxx_details::auto_ptr<> to get rid of preprocessor checks e06bfe96e Include soci/soci-platform.h instead of soci-config.h 6fbd8481e Avoid recursive inclusion between soci-{config,platform}.h 6caeb0b50 Merge pull request #449 from snikulov/appvr_up 78ea85ca1 fixed #447 ffc564b70 Use noexcept(false) for once_temp_type dtor with MSVS 2015 too 5e3813f50 Use C++11 deleted members for SOCI_NOT_{ASSIGNABLE,COPYABLE} 449e743b9 Merge pull request #446 from ArnaudD-FR/version 46513d877 CMake read version from version.h a8ab4c88b Revert "CMake generates soci/version.h" 6f68a7f00 Clean up already implemented features from TODO. 38d405935 Vagrant: update usage and development workflow. c2a387b2f Vagrant: correct DB2 database lookup for existing soci test db. f856f7730 Vagrant: fix accidental syntax error fb545a9b8 Vagrant: update usage documentation bd4d11d34 Add #define SOCI_HAVE_CXX_C11 mapped from with CMake SOCI_CXX_C11 option. e476b9d93 Vagrant: build with SOCI_CXX_C11=ON c6deb5d7e Vagrant: script formatting [ci skip] f4a47bfcb Vagrant: correct connection strings for tests 9b10e0ba2 Vagrant: set DB2 connection string for the backend tests. a84dade10 CMake: add boost_message_value as counterpart of boost_report_value. 540d33272 Vagrant: add SOCI_HOST variables for VMs networking d9e6d687a Merge pull request #438 from mloskot/db2-sqldriverconnect da61b6379 DB2: document option db2_option_driver_complete 838b99b62 DB2: Add sample SQLDriverConnect connection string 5d1ab2c77 DB2: Switch session from SQLConnect ot SQLDriverConnect ba8b1aa24 DB2: SQLExecute return code was not tested for SQL_NO_DATA. 837e88dec Vagrant: reorder booting to load DBs before dev env 8afea2f90 Vagrant: add SOCI_DB2_USER and SOCI_DB2_PASS variables 4a576a0c2 Vagrant: switch back to building from /vagrant share cd167df2e Vagrant: enable host to db2 networking on port 50000 7903d8e1a Vagrant: document networking support 04a59095d Vagrant: increase vm memory to 1024M 98ae7b206 Vagrant: try to avoid re-creation of soci DB if it exists 48a9c9797 Vagrant: do not run tests during provision 29c429ce9 Merge branch 'master' of https://github.com/SOCI/soci d6182bd9b Vagrant: add Avahi/MDNS to support resolving .local hostnames c22bfbcc1 Merge pull request #436 from ArnaudD-FR/test_version 094e19c68 CMake generates soci/version.h 2104cc9a6 Merge pull request #435 from ArnaudD-FR/test_definition 6908e473f Specify definitions in soci-config.h 634b2bf84 Vagrant: update DB2 CLI download steps 137efc496 Vagrant: add DB2 CLI client to soci.vm 435547064 Vagrant: define SOCI_* env variables via /etc/profile.d 569e8ecea CMake: add DB2 CLI driver locations 521f83cc0 Vagrant: correct comment [ci skip] e50025ea9 Vagrant: install zip [ci skip] a3e3f9671 Merge branch 'master' of https://github.com/SOCI/soci 6043cdf54 Vagrant: Add VM provisioned with DB2 instance and sample database 3a5066d9b Travis: remove sourcing of common.sh as unnecessary baad25922 Spell-check and formatting 111f5644d Preserve LF or CRLF for certain file types. 016687f03 Vagrant: explain debconf issue while installing Firebird 8a04c61c4 Merge pull request #434 from mloskot/master 01b9b48a3 Add Vagrant configuration 0ba242f51 Merge pull request #430 from ArnaudD-FR/sqlite3_reset d219a5790 [SQLITE3] Add reset API to reset sqlite3 statement fa708ad9f Merge pull request #428 from MonsieurNicolas/affectedRowFixSqlite 8cd3cf584 added test that reuses prepared statement 6af865fce reset count of affected rows (sqlite3) 149c53a43 Merge pull request #427 from snikulov/pr_coverity_init 0cc5c50ab - Fixed Coverity issues for SQLite3: 12644, 12645, 12646 - Fixed gcc/clang warns produced with -Wextra switch for SQLite3 9476a7a53 Merge pull request #426 from snikulov/pr_odbc_enable 86890bd2b Enabled mysql/postgresql - fixed #407 0232debc8 Merge pull request #425 from snikulov/cmake_win_cxx11 c2b37f0d2 moved SOCI_CXX_C11 define to common section 91fb559f0 Merge pull request #422 from snikulov/pr_374_fix 2af6c5efc Initialize rowid_backend-derived classes members in ctor 10e3c768a Avoid harmless Coverity dead code warning in MySQL code 4fd5c965a If prepare, execute, fetch... scenario is used and fetch() is called after gotData=false was already returned it begins another loop instead of returning false again indicating that all the data was already read. The following backend fix resolves this issue. e07f634a7 Added additional basic functionality test from prepare, execute, fetch scenario. 5b96f8c69 Clang: fixed #374 4576731e6 Disable email notifications to soci-devel 35bde9728 Merge pull request #420 from jeking3/feature/postgresql-uuid-unit-test ddde1f4c8 Merge pull request #421 from jeking3/bugfix/test-access-dsn-file-ignore 315b2cb5b add ignore of cmake generated dsn file for access 60abeb88c add a unit test for the postgresql uuid data type b1f730cd8 Merge pull request #419 from snikulov/pr_valgrind 8f51034cf Travis-CI: added valgrind check 185593f91 Merge pull request #418 from hw-dwalter/master b63e850cc fixed get_affected_rows() to pass test and fixed formatting 1ebc2661c Update .travis.yml to change coverity invokation branch ae3c4d2d8 Merge pull request #414 from hw-dwalter/master 90097ec73 added test to demonstrate bug #221 and make it valid with all backends b86a7b8ca Update README.md 6fe0a64bd Merge pull request #417 from snikulov/coverity_part_2 dff81b73e coverity: updated .travis.yml 8c0f35e21 Merge pull request #415 from snikulov/pr_413_rework 59d2cf016 Merge pull request #416 from snikulov/pr_travis_upd 1fa1a9413 Travis-CI: try add Coverity tool 63ef39126 AppVeyor: enable MSSQL ODBC connection 7aab87e8d Merge pull request #410 from snikulov/pr_appvr_mysql d36b06e26 Appveyor: added build for MySQL backend 8a67dbc63 Merge pull request #409 from snikulov/pr_appvr_postgres c0de792ae Appveyor: added PosgreSQL 9.4 backend 58975c6aa Merge pull request #408 from snikulov/pr_appvr_sqlite d0f6dec5f Appveyor: Added SQLite to build 4d2e19533 Merge pull request #406 from snikulov/appvr_db_services f7278ce54 Merge pull request #405 from snikulov/pr_odbc_test_reorg 629e64231 appvr: added db services to build workers 9d06e47a7 ODBC: test updates 14dfe5195 Appveyor: run ctest in test_script step 0530f6fec Avoid use of POSIX strptime function 68a335707 Add some variations for tests for use with indicators. 0d84fef30 Add std::tm checks to the use with indicators tests 985571234 Add tests for some variants with char* query 0b2837def Add test for query string as char* 3a49359bd Request CATCH to disable all the C++11 features. 24cbf26cd Merge pull request #403 from DraconPern/minorcmakefix 4fab0bb33 fixed typo 0e8223f89 Notify Gitter on every build 474c44443 Fix Gitter invalid token error 1eac4da5d Merge pull request #401 from snikulov/pr_appvr_boost da59e623d Merge pull request #400 from snikulov/pr_boost_opt c02d65340 Merge pull request #402 from ArnaudD-FR/master 09d6f9c81 Name struct to avoid clang error/warning (issue #374) 87e1c8384 Appveyor: added Boost libraries to build 063e75374 fix for #370 1fd43ebf6 Fix accidentally broken YAML syntax 87492930c Add Gitter integration webhooks for Travis CI and Appveyor 21ba1ddc8 Merge pull request #398 from snikulov/mingw_final 2060fa062 Merge pull request #399 from SOCI/snikulov-patch-1 c683042f6 Update README.md 59c49ed50 mingw: not use ms extension for MinGW G++ compilation 492d04249 Merge pull request #397 from snikulov/make_verbose e3e093b2e cmake: generate verbose build 903590290 Merge pull request #395 from snikulov/av_warn_fix d1fd85b45 connection-pool: moved common part out of #ifdef 6c8b6cd42 Switch Appveyor URL from snikulov/soci to mloskot/soci. b6443a4a2 Restore using -pedantic but use -Wno-pedantic-ms-format too 8fe5d2a1d Initialise in/out pos variable 96783407e Update connection-pool.cpp 21357eda7 Merge pull request #391 from snikulov/pr_appveyor_init 443beaa0b Don't add "-fPIC" explicitly, CMake does it automatically e607b1c73 Don't use "-pedantic" option when building with g++ 56207063b initial integration with AppVeyor-CI 8fda2bb37 boost: disable autolink, because soci controls required libs itself 7747cab51 updated to latest Catch UT framework to work with MinGW with PR #496 bb79b6074 cmake: updated FindODBC.cmake to search right sqlext.h on Windows 64dfb79f7 Merge pull request #381 from ravselj/sqlite_bug 23d398994 sqlite3_close moved after sqlite3_errmsg is called. d0f718350 Merge pull request #380 from dgrafe/subproject_integration_fixed f2261c40a Build system: Replacing CMAKE_SOURCE_DIR with CMAKE_CURRENT_SOURCE_DIR git-subtree-dir: src/soci git-subtree-split: 79e222e3c2278e6108137a2d26d3689418b37544
1201 lines
31 KiB
C++
1201 lines
31 KiB
C++
//
|
|
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
|
// Distributed under the Boost Software License, Version 1.0.
|
|
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
// http://www.boost.org/LICENSE_1_0.txt)
|
|
//
|
|
|
|
#include "soci/soci.h"
|
|
#include "soci/postgresql/soci-postgresql.h"
|
|
#include "common-tests.h"
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <cmath>
|
|
#include <cstring>
|
|
#include <ctime>
|
|
#include <cstdlib>
|
|
|
|
using namespace soci;
|
|
using namespace soci::tests;
|
|
|
|
std::string connectString;
|
|
backend_factory const &backEnd = *soci::factory_postgresql();
|
|
|
|
// Postgres-specific tests
|
|
|
|
struct oid_table_creator : public table_creator_base
|
|
{
|
|
oid_table_creator(soci::session& sql)
|
|
: table_creator_base(sql)
|
|
{
|
|
sql << "create table soci_test ("
|
|
" id integer,"
|
|
" name varchar(100)"
|
|
") with oids";
|
|
}
|
|
};
|
|
|
|
// ROWID test
|
|
// Note: in PostgreSQL, there is no ROWID, there is OID.
|
|
// It is still provided as a separate type for "portability",
|
|
// whatever that means.
|
|
TEST_CASE("PostgreSQL ROWID", "[postgresql][rowid][oid]")
|
|
{
|
|
soci::session sql(backEnd, connectString);
|
|
|
|
oid_table_creator tableCreator(sql);
|
|
|
|
sql << "insert into soci_test(id, name) values(7, \'John\')";
|
|
|
|
rowid rid(sql);
|
|
sql << "select oid from soci_test where id = 7", into(rid);
|
|
|
|
int id;
|
|
std::string name;
|
|
|
|
#ifndef SOCI_POSTGRESQL_NOPARAMS
|
|
|
|
sql << "select id, name from soci_test where oid = :rid",
|
|
into(id), into(name), use(rid);
|
|
|
|
#else
|
|
// Older PostgreSQL does not support use elements.
|
|
|
|
postgresql_rowid_backend *rbe
|
|
= static_cast<postgresql_rowid_backend *>(rid.get_backend());
|
|
|
|
unsigned long oid = rbe->value_;
|
|
|
|
sql << "select id, name from soci_test where oid = " << oid,
|
|
into(id), into(name);
|
|
|
|
#endif // SOCI_POSTGRESQL_NOPARAMS
|
|
|
|
CHECK(id == 7);
|
|
CHECK(name == "John");
|
|
}
|
|
|
|
TEST_CASE("PostgreSQL prepare error", "[postgresql][exception]")
|
|
{
|
|
soci::session sql(backEnd, connectString);
|
|
|
|
// Must not cause the application to crash.
|
|
statement st(sql);
|
|
st.prepare(""); // Throws an exception in some versions.
|
|
}
|
|
|
|
// function call test
|
|
class function_creator : function_creator_base
|
|
{
|
|
public:
|
|
|
|
function_creator(soci::session & sql)
|
|
: function_creator_base(sql)
|
|
{
|
|
// before a language can be used it must be defined
|
|
// if it has already been defined then an error will occur
|
|
try { sql << "create language plpgsql"; }
|
|
catch (soci_error const &) {} // ignore if error
|
|
|
|
#ifndef SOCI_POSTGRESQL_NOPARAMS
|
|
|
|
sql <<
|
|
"create or replace function soci_test(msg varchar) "
|
|
"returns varchar as $$ "
|
|
"declare x int := 1;"
|
|
"begin "
|
|
" return msg; "
|
|
"end $$ language plpgsql";
|
|
#else
|
|
|
|
sql <<
|
|
"create or replace function soci_test(varchar) "
|
|
"returns varchar as \' "
|
|
"declare x int := 1;"
|
|
"begin "
|
|
" return $1; "
|
|
"end \' language plpgsql";
|
|
#endif
|
|
}
|
|
|
|
protected:
|
|
|
|
std::string drop_statement()
|
|
{
|
|
return "drop function soci_test(varchar)";
|
|
}
|
|
};
|
|
|
|
TEST_CASE("PostgreSQL function call", "[postgresql][function]")
|
|
{
|
|
soci::session sql(backEnd, connectString);
|
|
|
|
function_creator functionCreator(sql);
|
|
|
|
std::string in("my message");
|
|
std::string out;
|
|
|
|
#ifndef SOCI_POSTGRESQL_NOPARAMS
|
|
|
|
statement st = (sql.prepare <<
|
|
"select soci_test(:input)",
|
|
into(out),
|
|
use(in, "input"));
|
|
|
|
#else
|
|
// Older PostgreSQL does not support use elements.
|
|
|
|
statement st = (sql.prepare <<
|
|
"select soci_test(\'" << in << "\')",
|
|
into(out));
|
|
|
|
#endif // SOCI_POSTGRESQL_NOPARAMS
|
|
|
|
st.execute(true);
|
|
CHECK(out == in);
|
|
|
|
// explicit procedure syntax
|
|
{
|
|
std::string in("my message2");
|
|
std::string out;
|
|
|
|
#ifndef SOCI_POSTGRESQL_NOPARAMS
|
|
|
|
procedure proc = (sql.prepare <<
|
|
"soci_test(:input)",
|
|
into(out), use(in, "input"));
|
|
|
|
#else
|
|
// Older PostgreSQL does not support use elements.
|
|
|
|
procedure proc = (sql.prepare <<
|
|
"soci_test(\'" << in << "\')", into(out));
|
|
|
|
#endif // SOCI_POSTGRESQL_NOPARAMS
|
|
|
|
proc.execute(true);
|
|
CHECK(out == in);
|
|
}
|
|
}
|
|
|
|
// BLOB test
|
|
struct blob_table_creator : public table_creator_base
|
|
{
|
|
blob_table_creator(soci::session & sql)
|
|
: table_creator_base(sql)
|
|
{
|
|
sql <<
|
|
"create table soci_test ("
|
|
" id integer,"
|
|
" img oid"
|
|
")";
|
|
}
|
|
};
|
|
|
|
TEST_CASE("PostgreSQL blob", "[postgresql][blob]")
|
|
{
|
|
{
|
|
soci::session sql(backEnd, connectString);
|
|
|
|
blob_table_creator tableCreator(sql);
|
|
|
|
char buf[] = "abcdefghijklmnopqrstuvwxyz";
|
|
|
|
sql << "insert into soci_test(id, img) values(7, lo_creat(-1))";
|
|
|
|
// in PostgreSQL, BLOB operations must be within transaction block
|
|
transaction tr(sql);
|
|
|
|
{
|
|
blob b(sql);
|
|
|
|
sql << "select img from soci_test where id = 7", into(b);
|
|
CHECK(b.get_len() == 0);
|
|
|
|
b.write(0, buf, sizeof(buf));
|
|
CHECK(b.get_len() == sizeof(buf));
|
|
|
|
b.append(buf, sizeof(buf));
|
|
CHECK(b.get_len() == 2 * sizeof(buf));
|
|
}
|
|
{
|
|
blob b(sql);
|
|
sql << "select img from soci_test where id = 7", into(b);
|
|
CHECK(b.get_len() == 2 * sizeof(buf));
|
|
char buf2[100];
|
|
b.read(0, buf2, 10);
|
|
CHECK(std::strncmp(buf2, "abcdefghij", 10) == 0);
|
|
}
|
|
|
|
unsigned long oid;
|
|
sql << "select img from soci_test where id = 7", into(oid);
|
|
sql << "select lo_unlink(" << oid << ")";
|
|
}
|
|
|
|
// additional sibling test for read_from_start and write_from_start
|
|
{
|
|
soci::session sql(backEnd, connectString);
|
|
|
|
blob_table_creator tableCreator(sql);
|
|
|
|
char buf[] = "abcdefghijklmnopqrstuvwxyz";
|
|
|
|
sql << "insert into soci_test(id, img) values(7, lo_creat(-1))";
|
|
|
|
// in PostgreSQL, BLOB operations must be within transaction block
|
|
transaction tr(sql);
|
|
|
|
{
|
|
blob b(sql);
|
|
|
|
sql << "select img from soci_test where id = 7", into(b);
|
|
CHECK(b.get_len() == 0);
|
|
|
|
b.write_from_start(buf, sizeof(buf));
|
|
CHECK(b.get_len() == sizeof(buf));
|
|
|
|
b.append(buf, sizeof(buf));
|
|
CHECK(b.get_len() == 2 * sizeof(buf));
|
|
}
|
|
{
|
|
blob b(sql);
|
|
sql << "select img from soci_test where id = 7", into(b);
|
|
CHECK(b.get_len() == 2 * sizeof(buf));
|
|
char buf2[100];
|
|
b.read_from_start(buf2, 10);
|
|
CHECK(std::strncmp(buf2, "abcdefghij", 10) == 0);
|
|
}
|
|
|
|
unsigned long oid;
|
|
sql << "select img from soci_test where id = 7", into(oid);
|
|
sql << "select lo_unlink(" << oid << ")";
|
|
}
|
|
}
|
|
|
|
struct longlong_table_creator : table_creator_base
|
|
{
|
|
longlong_table_creator(soci::session & sql)
|
|
: table_creator_base(sql)
|
|
{
|
|
sql << "create table soci_test(val int8)";
|
|
}
|
|
};
|
|
|
|
// long long test
|
|
TEST_CASE("PostgreSQL long long", "[postgresql][longlong]")
|
|
{
|
|
soci::session sql(backEnd, connectString);
|
|
|
|
longlong_table_creator tableCreator(sql);
|
|
|
|
long long v1 = 1000000000000LL;
|
|
sql << "insert into soci_test(val) values(:val)", use(v1);
|
|
|
|
long long v2 = 0LL;
|
|
sql << "select val from soci_test", into(v2);
|
|
|
|
CHECK(v2 == v1);
|
|
}
|
|
|
|
// vector<long long>
|
|
TEST_CASE("PostgreSQL vector long long", "[postgresql][vector][longlong]")
|
|
{
|
|
soci::session sql(backEnd, connectString);
|
|
|
|
longlong_table_creator tableCreator(sql);
|
|
|
|
std::vector<long long> v1;
|
|
v1.push_back(1000000000000LL);
|
|
v1.push_back(1000000000001LL);
|
|
v1.push_back(1000000000002LL);
|
|
v1.push_back(1000000000003LL);
|
|
v1.push_back(1000000000004LL);
|
|
|
|
sql << "insert into soci_test(val) values(:val)", use(v1);
|
|
|
|
std::vector<long long> v2(10);
|
|
sql << "select val from soci_test order by val desc", into(v2);
|
|
|
|
REQUIRE(v2.size() == 5);
|
|
CHECK(v2[0] == 1000000000004LL);
|
|
CHECK(v2[1] == 1000000000003LL);
|
|
CHECK(v2[2] == 1000000000002LL);
|
|
CHECK(v2[3] == 1000000000001LL);
|
|
CHECK(v2[4] == 1000000000000LL);
|
|
}
|
|
|
|
// unsigned long long test
|
|
TEST_CASE("PostgreSQL unsigned long long", "[postgresql][unsigned][longlong]")
|
|
{
|
|
soci::session sql(backEnd, connectString);
|
|
|
|
longlong_table_creator tableCreator(sql);
|
|
|
|
unsigned long long v1 = 1000000000000ULL;
|
|
sql << "insert into soci_test(val) values(:val)", use(v1);
|
|
|
|
unsigned long long v2 = 0ULL;
|
|
sql << "select val from soci_test", into(v2);
|
|
|
|
CHECK(v2 == v1);
|
|
}
|
|
|
|
struct boolean_table_creator : table_creator_base
|
|
{
|
|
boolean_table_creator(soci::session & sql)
|
|
: table_creator_base(sql)
|
|
{
|
|
sql << "create table soci_test(val boolean)";
|
|
}
|
|
};
|
|
|
|
TEST_CASE("PostgreSQL boolean", "[postgresql][boolean]")
|
|
{
|
|
soci::session sql(backEnd, connectString);
|
|
|
|
boolean_table_creator tableCreator(sql);
|
|
|
|
int i1 = 0;
|
|
|
|
sql << "insert into soci_test(val) values(:val)", use(i1);
|
|
|
|
int i2 = 7;
|
|
sql << "select val from soci_test", into(i2);
|
|
|
|
CHECK(i2 == i1);
|
|
|
|
sql << "update soci_test set val = true";
|
|
sql << "select val from soci_test", into(i2);
|
|
CHECK(i2 == 1);
|
|
}
|
|
|
|
struct uuid_table_creator : table_creator_base
|
|
{
|
|
uuid_table_creator(soci::session & sql)
|
|
: table_creator_base(sql)
|
|
{
|
|
sql << "create table soci_test(val uuid)";
|
|
}
|
|
};
|
|
|
|
// uuid test
|
|
TEST_CASE("PostgreSQL uuid", "[postgresql][uuid]")
|
|
{
|
|
soci::session sql(backEnd, connectString);
|
|
|
|
uuid_table_creator tableCreator(sql);
|
|
|
|
std::string v1("cd2dcb78-3817-442e-b12a-17c7e42669a0");
|
|
sql << "insert into soci_test(val) values(:val)", use(v1);
|
|
|
|
std::string v2;
|
|
sql << "select val from soci_test", into(v2);
|
|
|
|
CHECK(v2 == v1);
|
|
}
|
|
|
|
// dynamic backend test -- currently skipped by default
|
|
TEST_CASE("PostgreSQL dynamic backend", "[postgresql][backend][.]")
|
|
{
|
|
try
|
|
{
|
|
soci::session sql("nosuchbackend://" + connectString);
|
|
FAIL("expected exception not thrown");
|
|
}
|
|
catch (soci_error const & e)
|
|
{
|
|
CHECK(e.get_error_message() ==
|
|
"Failed to open: libsoci_nosuchbackend.so");
|
|
}
|
|
|
|
{
|
|
dynamic_backends::register_backend("pgsql", backEnd);
|
|
|
|
std::vector<std::string> backends = dynamic_backends::list_all();
|
|
REQUIRE(backends.size() == 1);
|
|
CHECK(backends[0] == "pgsql");
|
|
|
|
{
|
|
soci::session sql("pgsql://" + connectString);
|
|
}
|
|
|
|
dynamic_backends::unload("pgsql");
|
|
|
|
backends = dynamic_backends::list_all();
|
|
CHECK(backends.empty());
|
|
}
|
|
|
|
{
|
|
soci::session sql("postgresql://" + connectString);
|
|
}
|
|
}
|
|
|
|
TEST_CASE("PostgreSQL literals", "[postgresql][into]")
|
|
{
|
|
soci::session sql(backEnd, connectString);
|
|
|
|
int i;
|
|
sql << "select 123", into(i);
|
|
CHECK(i == 123);
|
|
|
|
try
|
|
{
|
|
sql << "select 'ABC'", into (i);
|
|
FAIL("expected exception not thrown");
|
|
}
|
|
catch (soci_error const & e)
|
|
{
|
|
char const * expectedPrefix = "Cannot convert data";
|
|
CAPTURE(e.what());
|
|
CHECK(strncmp(e.what(), expectedPrefix, strlen(expectedPrefix)) == 0);
|
|
}
|
|
}
|
|
|
|
TEST_CASE("PostgreSQL backend name", "[postgresql][backend]")
|
|
{
|
|
soci::session sql(backEnd, connectString);
|
|
|
|
CHECK(sql.get_backend_name() == "postgresql");
|
|
}
|
|
|
|
// test for double-colon cast in SQL expressions
|
|
TEST_CASE("PostgreSQL double colon cast", "[postgresql][cast]")
|
|
{
|
|
soci::session sql(backEnd, connectString);
|
|
|
|
int a = 123;
|
|
int b = 0;
|
|
sql << "select :a::integer", use(a), into(b);
|
|
CHECK(b == a);
|
|
}
|
|
|
|
// test for date, time and timestamp parsing
|
|
TEST_CASE("PostgreSQL datetime", "[postgresql][datetime]")
|
|
{
|
|
soci::session sql(backEnd, connectString);
|
|
|
|
std::string someDate = "2009-06-17 22:51:03.123";
|
|
std::tm t1 = std::tm(), t2 = std::tm(), t3 = std::tm();
|
|
|
|
sql << "select :sd::date, :sd::time, :sd::timestamp",
|
|
use(someDate, "sd"), into(t1), into(t2), into(t3);
|
|
|
|
// t1 should contain only the date part
|
|
CHECK(t1.tm_year == 2009 - 1900);
|
|
CHECK(t1.tm_mon == 6 - 1);
|
|
CHECK(t1.tm_mday == 17);
|
|
CHECK(t1.tm_hour == 0);
|
|
CHECK(t1.tm_min == 0);
|
|
CHECK(t1.tm_sec == 0);
|
|
|
|
// t2 should contain only the time of day part
|
|
CHECK(t2.tm_year == 0);
|
|
CHECK(t2.tm_mon == 0);
|
|
CHECK(t2.tm_mday == 1);
|
|
CHECK(t2.tm_hour == 22);
|
|
CHECK(t2.tm_min == 51);
|
|
CHECK(t2.tm_sec == 3);
|
|
|
|
// t3 should contain all information
|
|
CHECK(t3.tm_year == 2009 - 1900);
|
|
CHECK(t3.tm_mon == 6 - 1);
|
|
CHECK(t3.tm_mday == 17);
|
|
CHECK(t3.tm_hour == 22);
|
|
CHECK(t3.tm_min == 51);
|
|
CHECK(t3.tm_sec == 3);
|
|
}
|
|
|
|
// test for number of affected rows
|
|
|
|
struct table_creator_for_test11 : table_creator_base
|
|
{
|
|
table_creator_for_test11(soci::session & sql)
|
|
: table_creator_base(sql)
|
|
{
|
|
sql << "create table soci_test(val integer)";
|
|
}
|
|
};
|
|
|
|
TEST_CASE("PostgreSQL get affected rows", "[postgresql][affected-rows]")
|
|
{
|
|
soci::session sql(backEnd, connectString);
|
|
|
|
table_creator_for_test11 tableCreator(sql);
|
|
|
|
for (int i = 0; i != 10; i++)
|
|
{
|
|
sql << "insert into soci_test(val) values(:val)", use(i);
|
|
}
|
|
|
|
statement st1 = (sql.prepare <<
|
|
"update soci_test set val = val + 1");
|
|
st1.execute(false);
|
|
|
|
CHECK(st1.get_affected_rows() == 10);
|
|
|
|
statement st2 = (sql.prepare <<
|
|
"delete from soci_test where val <= 5");
|
|
st2.execute(false);
|
|
|
|
CHECK(st2.get_affected_rows() == 5);
|
|
}
|
|
|
|
// test INSERT INTO ... RETURNING syntax
|
|
|
|
struct table_creator_for_test12 : table_creator_base
|
|
{
|
|
table_creator_for_test12(soci::session & sql)
|
|
: table_creator_base(sql)
|
|
{
|
|
sql << "create table soci_test(sid serial, txt text)";
|
|
}
|
|
};
|
|
|
|
TEST_CASE("PostgreSQL insert into ... returning", "[postgresql]")
|
|
{
|
|
soci::session sql(backEnd, connectString);
|
|
|
|
table_creator_for_test12 tableCreator(sql);
|
|
|
|
std::vector<long> ids(10);
|
|
for (std::size_t i = 0; i != ids.size(); i++)
|
|
{
|
|
long sid(0);
|
|
std::string txt("abc");
|
|
sql << "insert into soci_test(txt) values(:txt) returning sid", use(txt, "txt"), into(sid);
|
|
ids[i] = sid;
|
|
}
|
|
|
|
std::vector<long> ids2(ids.size());
|
|
sql << "select sid from soci_test order by sid", into(ids2);
|
|
CHECK(std::equal(ids.begin(), ids.end(), ids2.begin()));
|
|
}
|
|
|
|
struct bytea_table_creator : public table_creator_base
|
|
{
|
|
bytea_table_creator(soci::session& sql)
|
|
: table_creator_base(sql)
|
|
{
|
|
sql << "drop table if exists soci_test;";
|
|
sql << "create table soci_test ( val bytea null )";
|
|
}
|
|
};
|
|
|
|
TEST_CASE("PostgreSQL bytea", "[postgresql][bytea]")
|
|
{
|
|
soci::session sql(backEnd, connectString);
|
|
|
|
// PostgreSQL supports two different output formats for bytea values:
|
|
// historical "escape" format, which is the only one supported until
|
|
// PostgreSQL 9.0, and "hex" format used by default since 9.0, we need
|
|
// to determine which one is actually in use.
|
|
std::string bytea_output_format;
|
|
sql << "select setting from pg_settings where name='bytea_output'",
|
|
into(bytea_output_format);
|
|
char const* expectedBytea;
|
|
if (bytea_output_format.empty() || bytea_output_format == "escape")
|
|
expectedBytea = "\\015\\014\\013\\012";
|
|
else if (bytea_output_format == "hex")
|
|
expectedBytea = "\\x0d0c0b0a";
|
|
else
|
|
throw std::runtime_error("Unknown PostgreSQL bytea_output \"" +
|
|
bytea_output_format + "\"");
|
|
|
|
bytea_table_creator tableCreator(sql);
|
|
|
|
int v = 0x0A0B0C0D;
|
|
unsigned char* b = reinterpret_cast<unsigned char*>(&v);
|
|
std::string data;
|
|
std::copy(b, b + sizeof(v), std::back_inserter(data));
|
|
{
|
|
|
|
sql << "insert into soci_test(val) values(:val)", use(data);
|
|
|
|
// 1) into string, no Oid mapping
|
|
std::string bin1;
|
|
sql << "select val from soci_test", into(bin1);
|
|
CHECK(bin1 == expectedBytea);
|
|
|
|
// 2) Oid-to-dt_string mapped
|
|
row r;
|
|
sql << "select * from soci_test", into(r);
|
|
|
|
REQUIRE(r.size() == 1);
|
|
column_properties const& props = r.get_properties(0);
|
|
CHECK(props.get_data_type() == soci::dt_string);
|
|
std::string bin2 = r.get<std::string>(0);
|
|
CHECK(bin2 == expectedBytea);
|
|
}
|
|
}
|
|
|
|
// json
|
|
struct table_creator_json : public table_creator_base
|
|
{
|
|
table_creator_json(soci::session& sql)
|
|
: table_creator_base(sql)
|
|
{
|
|
sql << "drop table if exists soci_json_test;";
|
|
sql << "create table soci_json_test(data json)";
|
|
}
|
|
};
|
|
|
|
// Return 9,2 for 9.2.3
|
|
typedef std::pair<int,int> server_version;
|
|
|
|
server_version get_postgresql_version(soci::session& sql)
|
|
{
|
|
std::string version;
|
|
std::pair<int,int> result;
|
|
sql << "select version()",into(version);
|
|
if (sscanf(version.c_str(),"PostgreSQL %i.%i", &result.first, &result.second) < 2)
|
|
{
|
|
throw std::runtime_error("Failed to retrieve PostgreSQL version number");
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// Test JSON. Only valid for PostgreSQL Server 9.2++
|
|
TEST_CASE("PostgreSQL JSON", "[postgresql][json]")
|
|
{
|
|
soci::session sql(backEnd, connectString);
|
|
server_version version = get_postgresql_version(sql);
|
|
if ( version >= server_version(9,2))
|
|
{
|
|
std::string result;
|
|
std::string valid_input = "{\"tool\":\"soci\",\"result\":42}";
|
|
std::string invalid_input = "{\"tool\":\"other\",\"result\":invalid}";
|
|
|
|
table_creator_json tableCreator(sql);
|
|
|
|
sql << "insert into soci_json_test (data) values(:data)",use(valid_input);
|
|
sql << "select data from soci_json_test",into(result);
|
|
CHECK(result == valid_input);
|
|
|
|
CHECK_THROWS_AS((
|
|
sql << "insert into soci_json_test (data) values(:data)",use(invalid_input)),
|
|
soci_error
|
|
);
|
|
}
|
|
else
|
|
{
|
|
WARN("JSON test skipped (PostgreSQL >= 9.2 required, found " << version.first << "." << version.second << ")");
|
|
}
|
|
}
|
|
|
|
struct table_creator_text : public table_creator_base
|
|
{
|
|
table_creator_text(soci::session& sql) : table_creator_base(sql)
|
|
{
|
|
sql << "drop table if exists soci_test;";
|
|
sql << "create table soci_test(name varchar(20))";
|
|
}
|
|
};
|
|
|
|
// Test deallocate_prepared_statement called for non-existing statement
|
|
// which creation failed due to invalid SQL syntax.
|
|
// https://github.com/SOCI/soci/issues/116
|
|
TEST_CASE("PostgreSQL statement prepare failure", "[postgresql][prepare]")
|
|
{
|
|
soci::session sql(backEnd, connectString);
|
|
table_creator_text tableCreator(sql);
|
|
|
|
try
|
|
{
|
|
// types mismatch should lead to PQprepare failure
|
|
statement get_trades =
|
|
(sql.prepare
|
|
<< "select * from soci_test where name=9999");
|
|
FAIL("expected exception not thrown");
|
|
}
|
|
catch(soci_error const& e)
|
|
{
|
|
std::string const msg(e.what());
|
|
CAPTURE(msg);
|
|
|
|
// poor-man heuristics
|
|
CHECK(msg.find("prepared statement") == std::string::npos);
|
|
CHECK(msg.find("operator does not exist") != std::string::npos);
|
|
}
|
|
}
|
|
|
|
// Test the support of PostgreSQL-style casts with ORM
|
|
TEST_CASE("PostgreSQL ORM cast", "[postgresql][orm]")
|
|
{
|
|
soci::session sql(backEnd, connectString);
|
|
values v;
|
|
v.set("a", 1);
|
|
sql << "select :a::int", use(v); // Must not throw an exception!
|
|
}
|
|
|
|
// Test the DDL and metadata functionality
|
|
TEST_CASE("PostgreSQL DDL with metadata", "[postgresql][ddl]")
|
|
{
|
|
soci::session sql(backEnd, connectString);
|
|
|
|
// note: prepare_column_descriptions expects l-value
|
|
std::string ddl_t1 = "ddl_t1";
|
|
std::string ddl_t2 = "ddl_t2";
|
|
std::string ddl_t3 = "ddl_t3";
|
|
|
|
// single-expression variant:
|
|
sql.create_table(ddl_t1).column("i", soci::dt_integer).column("j", soci::dt_integer);
|
|
|
|
// check whether this table was created:
|
|
|
|
bool ddl_t1_found = false;
|
|
bool ddl_t2_found = false;
|
|
bool ddl_t3_found = false;
|
|
std::string table_name;
|
|
soci::statement st = (sql.prepare_table_names(), into(table_name));
|
|
st.execute();
|
|
while (st.fetch())
|
|
{
|
|
if (table_name == ddl_t1) { ddl_t1_found = true; }
|
|
if (table_name == ddl_t2) { ddl_t2_found = true; }
|
|
if (table_name == ddl_t3) { ddl_t3_found = true; }
|
|
}
|
|
|
|
CHECK(ddl_t1_found);
|
|
CHECK(ddl_t2_found == false);
|
|
CHECK(ddl_t3_found == false);
|
|
|
|
// check whether ddl_t1 has the right structure:
|
|
|
|
bool i_found = false;
|
|
bool j_found = false;
|
|
bool other_found = false;
|
|
soci::column_info ci;
|
|
soci::statement st1 = (sql.prepare_column_descriptions(ddl_t1), into(ci));
|
|
st1.execute();
|
|
while (st1.fetch())
|
|
{
|
|
if (ci.name == "i")
|
|
{
|
|
CHECK(ci.type == soci::dt_integer);
|
|
CHECK(ci.nullable);
|
|
i_found = true;
|
|
}
|
|
else if (ci.name == "j")
|
|
{
|
|
CHECK(ci.type == soci::dt_integer);
|
|
CHECK(ci.nullable);
|
|
j_found = true;
|
|
}
|
|
else
|
|
{
|
|
other_found = true;
|
|
}
|
|
}
|
|
|
|
CHECK(i_found);
|
|
CHECK(j_found);
|
|
CHECK(other_found == false);
|
|
|
|
// two more tables:
|
|
|
|
// separately defined columns:
|
|
// (note: statement is executed when ddl object goes out of scope)
|
|
{
|
|
soci::ddl_type ddl = sql.create_table(ddl_t2);
|
|
ddl.column("i", soci::dt_integer);
|
|
ddl.column("j", soci::dt_integer);
|
|
ddl.column("k", soci::dt_integer)("not null");
|
|
ddl.primary_key("t2_pk", "j");
|
|
}
|
|
|
|
sql.add_column(ddl_t1, "k", soci::dt_integer);
|
|
sql.add_column(ddl_t1, "big", soci::dt_string, 0); // "unlimited" length -> text
|
|
sql.drop_column(ddl_t1, "i");
|
|
|
|
// or with constraint as in t2:
|
|
sql.add_column(ddl_t2, "m", soci::dt_integer)("not null");
|
|
|
|
// third table with a foreign key to the second one
|
|
{
|
|
soci::ddl_type ddl = sql.create_table(ddl_t3);
|
|
ddl.column("x", soci::dt_integer);
|
|
ddl.column("y", soci::dt_integer);
|
|
ddl.foreign_key("t3_fk", "x", ddl_t2, "j");
|
|
}
|
|
|
|
// check if all tables were created:
|
|
|
|
ddl_t1_found = false;
|
|
ddl_t2_found = false;
|
|
ddl_t3_found = false;
|
|
soci::statement st2 = (sql.prepare_table_names(), into(table_name));
|
|
st2.execute();
|
|
while (st2.fetch())
|
|
{
|
|
if (table_name == ddl_t1) { ddl_t1_found = true; }
|
|
if (table_name == ddl_t2) { ddl_t2_found = true; }
|
|
if (table_name == ddl_t3) { ddl_t3_found = true; }
|
|
}
|
|
|
|
CHECK(ddl_t1_found);
|
|
CHECK(ddl_t2_found);
|
|
CHECK(ddl_t3_found);
|
|
|
|
// check if ddl_t1 has the right structure (it was altered):
|
|
|
|
i_found = false;
|
|
j_found = false;
|
|
bool k_found = false;
|
|
bool big_found = false;
|
|
other_found = false;
|
|
soci::statement st3 = (sql.prepare_column_descriptions(ddl_t1), into(ci));
|
|
st3.execute();
|
|
while (st3.fetch())
|
|
{
|
|
if (ci.name == "j")
|
|
{
|
|
CHECK(ci.type == soci::dt_integer);
|
|
CHECK(ci.nullable);
|
|
j_found = true;
|
|
}
|
|
else if (ci.name == "k")
|
|
{
|
|
CHECK(ci.type == soci::dt_integer);
|
|
CHECK(ci.nullable);
|
|
k_found = true;
|
|
}
|
|
else if (ci.name == "big")
|
|
{
|
|
CHECK(ci.type == soci::dt_string);
|
|
CHECK(ci.precision == 0); // "unlimited" for strings
|
|
big_found = true;
|
|
}
|
|
else
|
|
{
|
|
other_found = true;
|
|
}
|
|
}
|
|
|
|
CHECK(i_found == false);
|
|
CHECK(j_found);
|
|
CHECK(k_found);
|
|
CHECK(big_found);
|
|
CHECK(other_found == false);
|
|
|
|
// check if ddl_t2 has the right structure:
|
|
|
|
i_found = false;
|
|
j_found = false;
|
|
k_found = false;
|
|
bool m_found = false;
|
|
other_found = false;
|
|
soci::statement st4 = (sql.prepare_column_descriptions(ddl_t2), into(ci));
|
|
st4.execute();
|
|
while (st4.fetch())
|
|
{
|
|
if (ci.name == "i")
|
|
{
|
|
CHECK(ci.type == soci::dt_integer);
|
|
CHECK(ci.nullable);
|
|
i_found = true;
|
|
}
|
|
else if (ci.name == "j")
|
|
{
|
|
CHECK(ci.type == soci::dt_integer);
|
|
CHECK(ci.nullable == false); // primary key
|
|
j_found = true;
|
|
}
|
|
else if (ci.name == "k")
|
|
{
|
|
CHECK(ci.type == soci::dt_integer);
|
|
CHECK(ci.nullable == false);
|
|
k_found = true;
|
|
}
|
|
else if (ci.name == "m")
|
|
{
|
|
CHECK(ci.type == soci::dt_integer);
|
|
CHECK(ci.nullable == false);
|
|
m_found = true;
|
|
}
|
|
else
|
|
{
|
|
other_found = true;
|
|
}
|
|
}
|
|
|
|
CHECK(i_found);
|
|
CHECK(j_found);
|
|
CHECK(k_found);
|
|
CHECK(m_found);
|
|
CHECK(other_found == false);
|
|
|
|
sql.drop_table(ddl_t1);
|
|
sql.drop_table(ddl_t3); // note: this must be dropped before ddl_t2
|
|
sql.drop_table(ddl_t2);
|
|
|
|
// check if all tables were dropped:
|
|
|
|
ddl_t1_found = false;
|
|
ddl_t2_found = false;
|
|
ddl_t3_found = false;
|
|
st2 = (sql.prepare_table_names(), into(table_name));
|
|
st2.execute();
|
|
while (st2.fetch())
|
|
{
|
|
if (table_name == ddl_t1) { ddl_t1_found = true; }
|
|
if (table_name == ddl_t2) { ddl_t2_found = true; }
|
|
if (table_name == ddl_t3) { ddl_t3_found = true; }
|
|
}
|
|
|
|
CHECK(ddl_t1_found == false);
|
|
CHECK(ddl_t2_found == false);
|
|
CHECK(ddl_t3_found == false);
|
|
|
|
int i = -1;
|
|
sql << "select lo_unlink(" + sql.empty_blob() + ")", into(i);
|
|
CHECK(i == 1);
|
|
sql << "select " + sql.nvl() + "(1, 2)", into(i);
|
|
CHECK(i == 1);
|
|
sql << "select " + sql.nvl() + "(NULL, 2)", into(i);
|
|
CHECK(i == 2);
|
|
}
|
|
|
|
// Test the bulk iterators functionality
|
|
TEST_CASE("Bulk iterators", "[postgresql][bulkiters]")
|
|
{
|
|
soci::session sql(backEnd, connectString);
|
|
|
|
sql << "create table t (i integer)";
|
|
|
|
// test bulk iterators with basic types
|
|
{
|
|
std::vector<int> v;
|
|
v.push_back(10);
|
|
v.push_back(20);
|
|
v.push_back(30);
|
|
v.push_back(40);
|
|
v.push_back(50);
|
|
|
|
std::size_t begin = 2;
|
|
std::size_t end = 5;
|
|
sql << "insert into t (i) values (:v)", soci::use(v, begin, end);
|
|
|
|
v.clear();
|
|
v.resize(20);
|
|
begin = 5;
|
|
end = 20;
|
|
sql << "select i from t", soci::into(v, begin, end);
|
|
|
|
CHECK(end == 8);
|
|
for (std::size_t i = 0; i != 5; ++i)
|
|
{
|
|
CHECK(v[i] == 0);
|
|
}
|
|
CHECK(v[5] == 30);
|
|
CHECK(v[6] == 40);
|
|
CHECK(v[7] == 50);
|
|
for (std::size_t i = end; i != 20; ++i)
|
|
{
|
|
CHECK(v[i] == 0);
|
|
}
|
|
}
|
|
|
|
sql << "delete from t";
|
|
|
|
// test bulk iterators with user types
|
|
{
|
|
std::vector<MyInt> v;
|
|
v.push_back(MyInt(10));
|
|
v.push_back(MyInt(20));
|
|
v.push_back(MyInt(30));
|
|
v.push_back(MyInt(40));
|
|
v.push_back(MyInt(50));
|
|
|
|
std::size_t begin = 2;
|
|
std::size_t end = 5;
|
|
sql << "insert into t (i) values (:v)", soci::use(v, begin, end);
|
|
|
|
v.clear();
|
|
for (std::size_t i = 0; i != 20; ++i)
|
|
{
|
|
v.push_back(MyInt(-1));
|
|
}
|
|
|
|
begin = 5;
|
|
end = 20;
|
|
sql << "select i from t", soci::into(v, begin, end);
|
|
|
|
CHECK(end == 8);
|
|
for (std::size_t i = 0; i != 5; ++i)
|
|
{
|
|
CHECK(v[i].get() == -1);
|
|
}
|
|
CHECK(v[5].get() == 30);
|
|
CHECK(v[6].get() == 40);
|
|
CHECK(v[7].get() == 50);
|
|
for (std::size_t i = end; i != 20; ++i)
|
|
{
|
|
CHECK(v[i].get() == -1);
|
|
}
|
|
}
|
|
|
|
sql << "drop table t";
|
|
}
|
|
|
|
//
|
|
// Support for soci Common Tests
|
|
//
|
|
|
|
// DDL Creation objects for common tests
|
|
struct table_creator_one : public table_creator_base
|
|
{
|
|
table_creator_one(soci::session & sql)
|
|
: table_creator_base(sql)
|
|
{
|
|
sql << "create table soci_test(id integer, val integer, c char, "
|
|
"str varchar(20), sh int2, ul numeric(20), d float8, "
|
|
"num76 numeric(7,6), "
|
|
"tm timestamp, i1 integer, i2 integer, i3 integer, "
|
|
"name varchar(20))";
|
|
}
|
|
};
|
|
|
|
struct table_creator_two : public table_creator_base
|
|
{
|
|
table_creator_two(soci::session & sql)
|
|
: table_creator_base(sql)
|
|
{
|
|
sql << "create table soci_test(num_float float8, num_int integer,"
|
|
" name varchar(20), sometime timestamp, chr char)";
|
|
}
|
|
};
|
|
|
|
struct table_creator_three : public table_creator_base
|
|
{
|
|
table_creator_three(soci::session & sql)
|
|
: table_creator_base(sql)
|
|
{
|
|
sql << "create table soci_test(name varchar(100) not null, "
|
|
"phone varchar(15))";
|
|
}
|
|
};
|
|
|
|
struct table_creator_for_get_affected_rows : table_creator_base
|
|
{
|
|
table_creator_for_get_affected_rows(soci::session & sql)
|
|
: table_creator_base(sql)
|
|
{
|
|
sql << "create table soci_test(val integer)";
|
|
}
|
|
};
|
|
|
|
struct table_creator_for_xml : table_creator_base
|
|
{
|
|
table_creator_for_xml(soci::session& sql)
|
|
: table_creator_base(sql)
|
|
{
|
|
sql << "create table soci_test(id integer, x xml)";
|
|
}
|
|
};
|
|
|
|
struct table_creator_for_clob : table_creator_base
|
|
{
|
|
table_creator_for_clob(soci::session& sql)
|
|
: table_creator_base(sql)
|
|
{
|
|
sql << "create table soci_test(id integer, s text)";
|
|
}
|
|
};
|
|
|
|
// Common tests context
|
|
class test_context : public test_context_base
|
|
{
|
|
public:
|
|
test_context(backend_factory const &backEnd, std::string const &connectString)
|
|
: test_context_base(backEnd, connectString)
|
|
{}
|
|
|
|
table_creator_base* table_creator_1(soci::session& s) const SOCI_OVERRIDE
|
|
{
|
|
return new table_creator_one(s);
|
|
}
|
|
|
|
table_creator_base* table_creator_2(soci::session& s) const SOCI_OVERRIDE
|
|
{
|
|
return new table_creator_two(s);
|
|
}
|
|
|
|
table_creator_base* table_creator_3(soci::session& s) const SOCI_OVERRIDE
|
|
{
|
|
return new table_creator_three(s);
|
|
}
|
|
|
|
table_creator_base* table_creator_4(soci::session& s) const SOCI_OVERRIDE
|
|
{
|
|
return new table_creator_for_get_affected_rows(s);
|
|
}
|
|
|
|
table_creator_base* table_creator_xml(soci::session& s) const SOCI_OVERRIDE
|
|
{
|
|
return new table_creator_for_xml(s);
|
|
}
|
|
|
|
table_creator_base* table_creator_clob(soci::session& s) const SOCI_OVERRIDE
|
|
{
|
|
return new table_creator_for_clob(s);
|
|
}
|
|
|
|
bool has_real_xml_support() const SOCI_OVERRIDE
|
|
{
|
|
return true;
|
|
}
|
|
|
|
std::string to_date_time(std::string const &datdt_string) const SOCI_OVERRIDE
|
|
{
|
|
return "timestamptz(\'" + datdt_string + "\')";
|
|
}
|
|
|
|
bool has_fp_bug() const SOCI_OVERRIDE
|
|
{
|
|
return false;
|
|
}
|
|
|
|
std::string sql_length(std::string const& s) const SOCI_OVERRIDE
|
|
{
|
|
return "char_length(" + s + ")";
|
|
}
|
|
};
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
|
|
#ifdef _MSC_VER
|
|
// Redirect errors, unrecoverable problems, and assert() failures to STDERR,
|
|
// instead of debug message window.
|
|
// This hack is required to run assert()-driven tests by Buildbot.
|
|
// NOTE: Comment this 2 lines for debugging with Visual C++ debugger to catch assertions inside.
|
|
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
|
|
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
|
|
#endif //_MSC_VER
|
|
|
|
if (argc >= 2)
|
|
{
|
|
connectString = argv[1];
|
|
|
|
// Replace the connect string with the process name to ensure that
|
|
// CATCH uses the correct name in its messages.
|
|
argv[1] = argv[0];
|
|
|
|
argc--;
|
|
argv++;
|
|
}
|
|
else
|
|
{
|
|
std::cout << "usage: " << argv[0]
|
|
<< " connectstring [test-arguments...]\n"
|
|
<< "example: " << argv[0]
|
|
<< " \'connect_string_for_PostgreSQL\'\n";
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
test_context tc(backEnd, connectString);
|
|
|
|
return Catch::Session().run(argc, argv);
|
|
}
|