diff options
139 files changed, 2757 insertions, 732 deletions
@@ -1,3 +1,5 @@ +Copyright (c) 2009-2024 Code Synthesis Tools CC. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. diff --git a/Makefile.am b/Makefile.am index 5ae3d5a..963f3c8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,4 @@ # file : Makefile.am -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file SUBDIRS = __path__(dirs) @@ -1,7 +1,6 @@ #! /bin/sh # file : bootstrap -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file # diff --git a/build/bootstrap.build b/build/bootstrap.build index a5a24ab..bb9c901 100644 --- a/build/bootstrap.build +++ b/build/bootstrap.build @@ -1,5 +1,4 @@ # file : build/bootstrap.build -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file project = libodb-sqlite diff --git a/build/bootstrap.make b/build/bootstrap.make index 82d2e63..c859827 100644 --- a/build/bootstrap.make +++ b/build/bootstrap.make @@ -1,5 +1,4 @@ # file : build/bootstrap.make -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file project_name := libodb-sqlite diff --git a/build/export.build b/build/export.build index 7d740c5..8ce77d8 100644 --- a/build/export.build +++ b/build/export.build @@ -1,5 +1,4 @@ # file : build/export.build -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file $out_root/ diff --git a/build/export/libodb-sqlite/stub.make b/build/export/libodb-sqlite/stub.make index ed533c8..af9cfd4 100644 --- a/build/export/libodb-sqlite/stub.make +++ b/build/export/libodb-sqlite/stub.make @@ -1,5 +1,4 @@ # file : build/export/libodb-sqlite/stub.make -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file $(call include-once,$(src_root)/odb/sqlite/makefile,$(out_root)) diff --git a/build/import/cli/LICENSE b/build/import/cli/LICENSE deleted file mode 100644 index f6b2d2b..0000000 --- a/build/import/cli/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -Copyright (c) 2009-2019 Code Synthesis Tools CC. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/build/import/cli/cli-cxx.make b/build/import/cli/cli-cxx.make index 3d01453..9bdf238 100644 --- a/build/import/cli/cli-cxx.make +++ b/build/import/cli/cli-cxx.make @@ -1,5 +1,4 @@ # file : build/import/cli/cli-cxx.make -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : MIT; see accompanying LICENSE file # Here we are operating in the importing project's space, not in diff --git a/build/import/cli/configuration-rules.make b/build/import/cli/configuration-rules.make index f13d01b..6355000 100644 --- a/build/import/cli/configuration-rules.make +++ b/build/import/cli/configuration-rules.make @@ -1,5 +1,4 @@ # file : build/import/cli/configuration-rules.make -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : MIT; see accompanying LICENSE file $(dcf_root)/import/cli/configuration-dynamic.make: | $(dcf_root)/import/cli/. diff --git a/build/import/cli/configure b/build/import/cli/configure index 944f48c..2a1fde4 100755 --- a/build/import/cli/configure +++ b/build/import/cli/configure @@ -1,7 +1,6 @@ #! /usr/bin/env bash # file : build/import/cli/configure -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : MIT; see accompanying LICENSE file diff --git a/build/import/cli/stub.make b/build/import/cli/stub.make index 047ba40..741b371 100644 --- a/build/import/cli/stub.make +++ b/build/import/cli/stub.make @@ -1,5 +1,4 @@ # file : build/import/cli/stub.make -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : MIT; see accompanying LICENSE file $(call include-once,$(scf_root)/import/cli/configuration-rules.make,$(dcf_root)) diff --git a/build/import/libodb-sqlite/LICENSE b/build/import/libodb-sqlite/LICENSE deleted file mode 120000 index 5853aae..0000000 --- a/build/import/libodb-sqlite/LICENSE +++ /dev/null @@ -1 +0,0 @@ -../../../LICENSE
\ No newline at end of file diff --git a/build/import/libodb-sqlite/configuration-rules.make b/build/import/libodb-sqlite/configuration-rules.make index 260dcb6..bf8dee4 100644 --- a/build/import/libodb-sqlite/configuration-rules.make +++ b/build/import/libodb-sqlite/configuration-rules.make @@ -1,5 +1,4 @@ # file : build/import/libodb-sqlite/configuration-rules.make -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file $(dcf_root)/import/libodb-sqlite/configuration-dynamic.make: | $(dcf_root)/import/libodb-sqlite/. diff --git a/build/import/libodb-sqlite/configure b/build/import/libodb-sqlite/configure index 2d61e29..9f245f5 100755 --- a/build/import/libodb-sqlite/configure +++ b/build/import/libodb-sqlite/configure @@ -1,7 +1,6 @@ #! /usr/bin/env bash # file : build/import/libodb-sqlite/configure -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file diff --git a/build/import/libodb-sqlite/stub.make b/build/import/libodb-sqlite/stub.make index add7c39..417e65a 100644 --- a/build/import/libodb-sqlite/stub.make +++ b/build/import/libodb-sqlite/stub.make @@ -1,5 +1,4 @@ # file : build/import/libodb-sqlite/stub.make -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file $(call include-once,$(scf_root)/import/libodb-sqlite/configuration-rules.make,$(dcf_root)) diff --git a/build/import/libodb/LICENSE b/build/import/libodb/LICENSE deleted file mode 100644 index ed9c55c..0000000 --- a/build/import/libodb/LICENSE +++ /dev/null @@ -1,12 +0,0 @@ -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License version 2 as -published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA diff --git a/build/import/libodb/configuration-rules.make b/build/import/libodb/configuration-rules.make index 872cbb3..340c418 100644 --- a/build/import/libodb/configuration-rules.make +++ b/build/import/libodb/configuration-rules.make @@ -1,5 +1,4 @@ # file : build/import/libodb/configuration-rules.make -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file $(dcf_root)/import/libodb/configuration-dynamic.make: | $(dcf_root)/import/libodb/. diff --git a/build/import/libodb/configure b/build/import/libodb/configure index 0d57a5f..261a202 100755 --- a/build/import/libodb/configure +++ b/build/import/libodb/configure @@ -1,7 +1,6 @@ #! /usr/bin/env bash # file : build/import/libodb/configure -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file diff --git a/build/import/libodb/stub.make b/build/import/libodb/stub.make index 6b7088d..04dc786 100644 --- a/build/import/libodb/stub.make +++ b/build/import/libodb/stub.make @@ -1,5 +1,4 @@ # file : build/import/libodb/stub.make -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file $(call include-once,$(scf_root)/import/libodb/configuration-rules.make,$(dcf_root)) diff --git a/build/import/libsqlite/LICENSE b/build/import/libsqlite/LICENSE deleted file mode 100644 index 3912109..0000000 --- a/build/import/libsqlite/LICENSE +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/build/import/libsqlite/configuration-rules.make b/build/import/libsqlite/configuration-rules.make index 52db522..c7fcbed 100644 --- a/build/import/libsqlite/configuration-rules.make +++ b/build/import/libsqlite/configuration-rules.make @@ -1,5 +1,4 @@ # file : build/import/libsqlite/configuration-rules.make -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file $(dcf_root)/import/libsqlite/configuration-dynamic.make: | $(dcf_root)/import/libsqlite/. diff --git a/build/import/libsqlite/configure b/build/import/libsqlite/configure index 81cf42b..0ae364f 100755 --- a/build/import/libsqlite/configure +++ b/build/import/libsqlite/configure @@ -1,7 +1,6 @@ #! /usr/bin/env bash # file : build/import/libsqlite/configure -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file diff --git a/build/import/libsqlite/rules.make b/build/import/libsqlite/rules.make index 8cc81e3..7e346bd 100644 --- a/build/import/libsqlite/rules.make +++ b/build/import/libsqlite/rules.make @@ -1,5 +1,4 @@ # file : build/import/libsqlite/rules.make -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file $(dcf_root)/import/libsqlite/%: root := $(libsqlite_root) diff --git a/build/import/libsqlite/stub.make b/build/import/libsqlite/stub.make index 2038625..2d9e519 100644 --- a/build/import/libsqlite/stub.make +++ b/build/import/libsqlite/stub.make @@ -1,5 +1,4 @@ # file : build/import/libsqlite/stub.make -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file $(call include-once,$(scf_root)/import/libsqlite/configuration-rules.make,$(dcf_root)) diff --git a/build/root.build b/build/root.build index ece30fb..a1975db 100644 --- a/build/root.build +++ b/build/root.build @@ -1,7 +1,8 @@ # file : build/root.build -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file +config [bool] config.libodb_sqlite.develop ?= false + cxx.std = latest using cxx @@ -16,11 +17,3 @@ if ($cxx.target.system == 'win32-msvc') if ($cxx.class == 'msvc') cxx.coptions += /wd4251 /wd4275 /wd4800 - -# Load the cli module but only if it's available. This way a distribution -# that includes pre-generated files can be built without installing cli. -# This is also the reason why we need to explicitly spell out individual -# source file prerequisites instead of using the cli.cxx{} group (it won't -# be there unless the module is configured). -# -using? cli @@ -1,8 +1,9 @@ # file : buildfile -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file -./: {*/ -build/ -m4/ -etc/} doc{GPLv2 INSTALL LICENSE NEWS README} manifest +./: {*/ -build/ -m4/ -etc/} \ + doc{INSTALL NEWS README} legal{GPLv2 LICENSE} \ + manifest # Don't install tests or the INSTALL file. # diff --git a/configure.ac b/configure.ac index 21b0b51..27a5537 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,4 @@ # file : configure.ac -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file AC_PREREQ(2.60) diff --git a/libodb-sqlite.pc.in b/libodb-sqlite.pc.in index dc682a2..b53bc6f 100644 --- a/libodb-sqlite.pc.in +++ b/libodb-sqlite.pc.in @@ -1,5 +1,4 @@ # file : libodb-sqlite.pc.in -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file prefix=@prefix@ diff --git a/m4/disable-rpath.m4 b/m4/disable-rpath.m4 index 7874d4b..0864209 100644 --- a/m4/disable-rpath.m4 +++ b/m4/disable-rpath.m4 @@ -1,5 +1,4 @@ dnl file : m4/disable-rpath.m4 -dnl copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC dnl license : GNU GPL v2; see accompanying LICENSE file dnl AC_DEFUN([DISABLE_RPATH],[ diff --git a/m4/libodb.m4 b/m4/libodb.m4 index 5f140bd..0dba7c4 100644 --- a/m4/libodb.m4 +++ b/m4/libodb.m4 @@ -1,5 +1,4 @@ dnl file : m4/libodb.m4 -dnl copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC dnl license : GNU GPL v2; see accompanying LICENSE file dnl dnl LIBODB([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) diff --git a/m4/libsqlite.m4 b/m4/libsqlite.m4 index 3985706..421e990 100644 --- a/m4/libsqlite.m4 +++ b/m4/libsqlite.m4 @@ -1,5 +1,4 @@ dnl file : m4/libsqlite.m4 -dnl copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC dnl license : GNU GPL v2; see accompanying LICENSE file dnl dnl LIBSQLITE([ACTION-IF-FOUND[,ACTION-IF-NOT-FOUND]]) diff --git a/m4/libtool-link.m4 b/m4/libtool-link.m4 index 635793f..302639f 100644 --- a/m4/libtool-link.m4 +++ b/m4/libtool-link.m4 @@ -1,5 +1,4 @@ dnl file : m4/libtool-link.m4 -dnl copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC dnl license : GNU GPL v2; see accompanying LICENSE file dnl dnl diff --git a/m4/pkgconfig.m4 b/m4/pkgconfig.m4 index d5aa2d0..c48ea56 100644 --- a/m4/pkgconfig.m4 +++ b/m4/pkgconfig.m4 @@ -1,5 +1,4 @@ dnl file : m4/pkgconfig.m4 -dnl copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC dnl license : GNU GPL v2; see accompanying LICENSE file dnl AC_DEFUN([PKGCONFIG],[ diff --git a/m4/static-lib.m4 b/m4/static-lib.m4 index 79b89cd..5fb1c11 100644 --- a/m4/static-lib.m4 +++ b/m4/static-lib.m4 @@ -1,5 +1,4 @@ dnl file : m4/static-lib.m4 -dnl copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC dnl license : GNU GPL v2; see accompanying LICENSE file dnl dnl STATIC_LIB(MACRO, DESCRIPTION) diff --git a/m4/threads.m4 b/m4/threads.m4 index 10bdfdd..6f2e25f 100644 --- a/m4/threads.m4 +++ b/m4/threads.m4 @@ -1,5 +1,4 @@ dnl file : m4/threads.m4 -dnl copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC dnl license : GNU GPL v2; see accompanying LICENSE file dnl AC_DEFUN([THREADS],[ @@ -1,5 +1,4 @@ # file : makefile -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file include $(dir $(lastword $(MAKEFILE_LIST)))build/bootstrap.make @@ -13,13 +12,13 @@ clean := $(out_base)/.clean $(default): $(addprefix $(out_base)/,$(addsuffix /,$(dirs))) $(dist): export dirs := $(dirs) -$(dist): export docs := GPLv2 LICENSE README NEWS version +$(dist): export docs := GPLv2 LICENSE README NEWS version.txt $(dist): data_dist := INSTALL libodb-sqlite-vc8.sln libodb-sqlite-vc9.sln \ libodb-sqlite-vc10.sln libodb-sqlite-vc11.sln libodb-sqlite-vc12.sln \ $(subst $(src_base)/,,$(shell find $(src_base)/etc -type f)) $(dist): exec_dist := bootstrap $(dist): export extra_dist := $(data_dist) $(exec_dist) -$(dist): export version = $(shell cat $(src_root)/version) +$(dist): export version = $(shell cat $(src_root)/version.txt) $(dist): $(addprefix $(out_base)/,$(addsuffix /.dist,$(dirs))) $(call dist-data,$(docs) $(data_dist) libodb-sqlite.pc.in) @@ -1,10 +1,10 @@ : 1 name: libodb-sqlite -version: 2.5.0-b.16.z +version: 2.5.0-b.26.z project: odb summary: SQLite ODB runtime library -license: GPLv2 -license: proprietary +license: GPL-2.0-only +license: other: proprietary ; Not free/open source. topics: C++, ORM, SQLite, SQL description-file: README changes-file: NEWS @@ -12,10 +12,11 @@ url: https://www.codesynthesis.com/products/odb/ doc-url: https://www.codesynthesis.com/products/odb/doc/manual.xhtml src-url: https://git.codesynthesis.com/cgit/odb/libodb-sqlite/ email: odb-users@codesynthesis.com -build-email: odb-builds@codesynthesis.com +build-warning-email: odb-builds@codesynthesis.com builds: all requires: c++11 -depends: * build2 >= 0.11.0 -depends: * bpkg >= 0.11.0 +depends: * build2 >= 0.16.0- +depends: * bpkg >= 0.16.0- depends: libsqlite3 ^3.6.18 -depends: libodb [2.5.0-b.16.1 2.5.0-b.17) +depends: libodb [2.5.0-b.26.1 2.5.0-b.27) +depends: * cli ^1.2.0- ? ($config.libodb_sqlite.develop) diff --git a/odb/sqlite/Makefile.am b/odb/sqlite/Makefile.am index f6be926..0f66fc3 100644 --- a/odb/sqlite/Makefile.am +++ b/odb/sqlite/Makefile.am @@ -1,5 +1,4 @@ # file : odb/sqlite/Makefile.am -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file lib_LTLIBRARIES = libodb-sqlite.la diff --git a/odb/sqlite/auto-handle.hxx b/odb/sqlite/auto-handle.hxx index 22f0cf9..d25e919 100644 --- a/odb/sqlite/auto-handle.hxx +++ b/odb/sqlite/auto-handle.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/auto-handle.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_AUTO_HANDLE_HXX diff --git a/odb/sqlite/binding.hxx b/odb/sqlite/binding.hxx index 09d4927..3807130 100644 --- a/odb/sqlite/binding.hxx +++ b/odb/sqlite/binding.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/binding.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_BINDING_HXX diff --git a/odb/sqlite/blob-stream.hxx b/odb/sqlite/blob-stream.hxx index 1531fd1..caa7c24 100644 --- a/odb/sqlite/blob-stream.hxx +++ b/odb/sqlite/blob-stream.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/blob-stream.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_BLOB_STREAM_HXX diff --git a/odb/sqlite/blob.hxx b/odb/sqlite/blob.hxx index 0c559df..a4892a2 100644 --- a/odb/sqlite/blob.hxx +++ b/odb/sqlite/blob.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/blob.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_BLOB_HXX diff --git a/odb/sqlite/buildfile b/odb/sqlite/buildfile index 26ea2b8..d2a6656 100644 --- a/odb/sqlite/buildfile +++ b/odb/sqlite/buildfile @@ -1,13 +1,15 @@ # file : odb/sqlite/buildfile -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file +define cli: file +cli{*}: extension = cli + import int_libs = libodb%lib{odb} import int_libs += libsqlite3%lib{sqlite3} -lib{odb-sqlite}: {hxx ixx txx cxx}{* -version-build2} {hxx}{version-build2} \ - details/{hxx ixx txx cxx}{* -options} details/{hxx ixx cxx}{options} \ - details/build2/{h}{*} \ +lib{odb-sqlite}: {hxx ixx txx cxx}{* -version-build2} {hxx}{version-build2} \ + details/{hxx ixx txx cxx}{* -options} \ + details/build2/{h}{*} \ $int_libs # Include the generated version header into the distribution (so that we don't @@ -48,35 +50,76 @@ if $version.pre_release else lib{odb-sqlite}: bin.lib.version = @"-$version.major.$version.minor" -# Generated options parser. +develop = $config.libodb_sqlite.develop + +## Consumption build ($develop == false). +# + +# Use pregenerated versions in the consumption build. +# +lib{odb-sqlite}: details/pregenerated/{hxx ixx cxx}{**}: include = (!$develop) + +if! $develop + cxx.poptions =+ "-I($src_base/details/pregenerated)" # Note: must come first. + +# Don't install pregenerated headers since they are only used internally in +# the database implementation (also below). +# +details/pregenerated/{hxx ixx}{*}: install = false + +# Distribute pregenerated versions only in the consumption build. +# +details/pregenerated/{hxx ixx cxx}{*}: dist = (!$develop) + # -details/ +## + +## Development build ($develop == true). +# + +lib{odb-sqlite}: details/{hxx ixx cxx}{options}: include = $develop + +if $develop + import! [metadata] cli = cli%exe{cli} + +# In the development build distribute regenerated {hxx ixx cxx}{options}, +# remapping their locations to the paths of the pregenerated versions (which +# are only distributed in the consumption build; see above). This way we make +# sure that the distributed files are always up-to-date. +# +<details/{hxx ixx cxx}{options}>: details/cli{options} $cli { - if $cli.configured - { - cli.cxx{options}: cli{options} - - cli.options += --include-with-brackets --include-prefix odb/sqlite/details \ ---guard-prefix LIBODB_SQLITE_DETAILS --generate-file-scanner \ ---cli-namespace odb::sqlite::details::cli --long-usage --no-combined-flags - - # Include generated cli files into the distribution and don't remove them - # when cleaning in src (so that clean results in a state identical to - # distributed). But don't install their headers since they are only used - # internally in the database implementation. - # - cli.cxx{*}: - { - dist = true - clean = ($src_root != $out_root) - install = false - } - } - else - # No install for the pre-generated case. - # - hxx{options}@./ ixx{options}@./: install = false + install = false + dist = ($develop ? pregenerated/odb/sqlite/details/ : false) + + # Symlink the generated code in src for convenience of development. + # + backlink = true } +% +if $develop +{{ + options = --include-with-brackets --include-prefix odb/sqlite/details \ + --guard-prefix LIBODB_SQLITE_DETAILS --generate-file-scanner \ + --cli-namespace odb::sqlite::details::cli --long-usage \ + --no-combined-flags + + $cli $options -o $out_base/details/ $path($<[0]) + + # If the result differs from the pregenerated version, copy it over. + # + d = [dir_path] $src_base/details/pregenerated/odb/sqlite/details/ + + if diff $d/options.hxx $path($>[0]) >- && \ + diff $d/options.ixx $path($>[1]) >- && \ + diff $d/options.cxx $path($>[2]) >- + exit + end + + cp $path($>[0]) $d/options.hxx + cp $path($>[1]) $d/options.ixx + cp $path($>[2]) $d/options.cxx +}} # Install into the odb/sqlite/ subdirectory of, say, /usr/include/ # recreating subdirectories. @@ -99,7 +142,7 @@ details/build2/ { h{*}: install = false - if ($cxx.class == 'msvc') + if ($cxx.target.system == 'win32-msvc') { h{config-vc}@./: install = $install_include/details/ h{config-vc-stub}@./: install = $install_include/details/build2/config-vc.h diff --git a/odb/sqlite/connection-factory.cxx b/odb/sqlite/connection-factory.cxx index 579cb61..794c6dd 100644 --- a/odb/sqlite/connection-factory.cxx +++ b/odb/sqlite/connection-factory.cxx @@ -1,7 +1,8 @@ // file : odb/sqlite/connection-factory.cxx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file +#include <cassert> + #include <odb/details/lock.hxx> #include <odb/sqlite/database.hxx> @@ -18,6 +19,40 @@ namespace odb namespace sqlite { // + // serial_connection_factory + // + + serial_connection_factory:: + ~serial_connection_factory () + { + // We should hold the last reference to the connection. + // + if (connection_ != 0) + assert (connection_.count () == 1); + } + + connection_ptr serial_connection_factory:: + create () + { + return connection_ptr (new (shared) connection (*this)); + } + + connection_ptr serial_connection_factory:: + connect () + { + return connection_; + } + + void serial_connection_factory:: + database (database_type& db) + { + connection_factory::database (db); + + if (!connection_) + connection_ = create (); + } + + // // single_connection_factory // @@ -262,5 +297,121 @@ namespace odb pooled_connection* c (static_cast<pooled_connection*> (arg)); return static_cast<connection_pool_factory&> (c->factory_).release (c); } + + // + // default_attached_connection_factory + // + + void default_attached_connection_factory:: + detach () + { + // Note that this function may be called several times, for example, in + // case of detach_database() failure. + // + if (attached_connection_ != 0) + { + // We should hold the last reference to the attached connection. + // + assert (attached_connection_.count () == 1); + + // While it may seem like a good idea to also invalidate query results + // and reset active statements, if any such result/statement is still + // alive, then there would be bigger problems since it would have a + // dangling reference to the connection. In a way, that's the same + // reason we don't do it in the connection destructor. + + // Remove ourselves from the active object list of the main + // connection. + // + if (next_ != this) // Might have already been done. + list_remove (); + + const string& s (database ().schema ()); + + if (s != "main" && s != "temp") + main_factory ().detach_database (main_connection_, s); + + // Explicitly free the attached connection so that we don't try to + // redo this. + // + attached_connection_.reset (); + } + } + + default_attached_connection_factory:: + ~default_attached_connection_factory () + { + if (attached_connection_ != 0) + { + // This can throw. Ignoring the failure to detach seems like the most + // sensible thing to do here. + // + try{ detach (); } catch (...) {} + } + } + + connection_ptr default_attached_connection_factory:: + connect () + { + return attached_connection_; + } + + void default_attached_connection_factory:: + database (database_type& db) + { + attached_connection_factory::database (db); + + if (!attached_connection_) + { + const string& s (db.schema ()); + + if (s != "main" && s != "temp") + main_factory ().attach_database (main_connection_, db.name (), s); + + attached_connection_.reset ( + new (shared) connection (*this, + s != "main" ? &translate_statement : 0)); + + // Add ourselves to the active object list of the main connection. + // + list_add (); + } + } + + void default_attached_connection_factory:: + clear () + { + attached_connection_->clear (); + } + + void default_attached_connection_factory:: + translate_statement (string& r, + const char* text, + size_t text_size, + connection& conn) + { + r.assign (text, text_size); + + // Things will fall apart if any of the statements we translate use + // "main" as a table alias. So we have this crude check even though it + // means we cannot use "main" for other aliases (e.g., column). + // + assert (r.find ("AS \"main\"") == string::npos); + + const string& s (conn.database ().schema ()); + for (size_t p (0); (p = r.find ("\"main\".", p, 7)) != string::npos; ) + { + // Verify the preceding character. + // + if (p != 0 && r[p - 1] == '.') + { + p += 7; + continue; + } + + r.replace (p + 1, 4, s); + p += s.size () + 3; + } + } } } diff --git a/odb/sqlite/connection-factory.hxx b/odb/sqlite/connection-factory.hxx index 616a940..b410997 100644 --- a/odb/sqlite/connection-factory.hxx +++ b/odb/sqlite/connection-factory.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/connection-factory.hxx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_CONNECTION_FACTORY_HXX @@ -24,7 +23,42 @@ namespace odb { namespace sqlite { - // Share a single connection. + // Share a single connection in a guaranteed serial database access. + // + // For example, a single-threaded application that executes all the + // operations via the database instance without messing with multiple + // connections/transactions would qualify. + // + class LIBODB_SQLITE_EXPORT serial_connection_factory: + public connection_factory + { + public: + serial_connection_factory () {} + + virtual connection_ptr + connect (); + + virtual void + database (database_type&); + + virtual + ~serial_connection_factory (); + + private: + serial_connection_factory (const serial_connection_factory&); + serial_connection_factory& operator= (const serial_connection_factory&); + + protected: + // This function is called when the factory needs to create the + // connection. + // + virtual connection_ptr + create (); + + connection_ptr connection_; + }; + + // Share a single connection potentially between multiple threads. // class LIBODB_SQLITE_EXPORT single_connection_factory: public connection_factory @@ -199,6 +233,38 @@ namespace odb details::mutex mutex_; details::condition cond_; }; + + class LIBODB_SQLITE_EXPORT default_attached_connection_factory: + public attached_connection_factory + { + public: + explicit + default_attached_connection_factory (const connection_ptr& main) + : attached_connection_factory (main) {} + + using attached_connection_factory::database; // Accessor. + + virtual void + database (database_type&); + + virtual connection_ptr + connect (); + + virtual void + detach (); + + // Active object interface. + // + virtual void + clear (); + + virtual + ~default_attached_connection_factory (); + + protected: + static void + translate_statement (std::string&, const char*, std::size_t, connection&); + }; } } diff --git a/odb/sqlite/connection.cxx b/odb/sqlite/connection.cxx index ab17c7c..0445163 100644 --- a/odb/sqlite/connection.cxx +++ b/odb/sqlite/connection.cxx @@ -1,5 +1,4 @@ // file : odb/sqlite/connection.cxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <new> // std::bad_alloc @@ -26,11 +25,16 @@ odb_sqlite_connection_unlock_callback (void**, int); namespace odb { + using namespace details; + namespace sqlite { connection:: - connection (connection_factory& cf, int extra_flags) + connection (connection_factory& cf, + int extra_flags, + statement_translator* st) : odb::connection (cf), + statement_translator_ (st), unlock_cond_ (unlock_mutex_), active_objects_ (0) { @@ -82,9 +86,12 @@ namespace odb } connection:: - connection (connection_factory& cf, sqlite3* handle) + connection (connection_factory& cf, + sqlite3* handle, + statement_translator* st) : odb::connection (cf), handle_ (handle), + statement_translator_ (st), unlock_cond_ (unlock_mutex_), active_objects_ (0) { @@ -106,6 +113,31 @@ namespace odb db.foreign_keys () ? 22 : 23); st.execute (); + // String lengths include '\0', as per the SQLite manual suggestion. + // + begin_.reset (new (shared) generic_statement (*this, "BEGIN", 6)); + commit_.reset (new (shared) generic_statement (*this, "COMMIT", 7)); + rollback_.reset (new (shared) generic_statement (*this, "ROLLBACK", 9)); + + // Create statement cache. + // + statement_cache_.reset (new statement_cache_type (*this)); + } + + connection:: + connection (attached_connection_factory& cf, statement_translator* st) + : odb::connection (cf), + handle_ (0), + statement_translator_ (st), + unlock_cond_ (unlock_mutex_), + active_objects_ (0) + { + // Copy some things over from the main connection. + // + connection& main (*cf.main_connection_); + + tracer_ = main.tracer_; + // Create statement cache. // statement_cache_.reset (new statement_cache_type (*this)); @@ -120,6 +152,44 @@ namespace odb clear_prepared_map (); } + generic_statement& connection:: + begin_statement () + { + return static_cast<generic_statement&> (*begin_); + } + + generic_statement& connection:: + begin_immediate_statement () + { + if (!begin_immediate_) + begin_immediate_.reset ( + new (shared) generic_statement (*this, "BEGIN IMMEDIATE", 16)); + + return static_cast<generic_statement&> (*begin_immediate_); + } + + generic_statement& connection:: + begin_exclusive_statement () + { + if (!begin_exclusive_) + begin_exclusive_.reset ( + new (shared) generic_statement (*this, "BEGIN EXCLUSIVE", 16)); + + return static_cast<generic_statement&> (*begin_exclusive_); + } + + generic_statement& connection:: + commit_statement () + { + return static_cast<generic_statement&> (*commit_); + } + + generic_statement& connection:: + rollback_statement () + { + return static_cast<generic_statement&> (*rollback_); + } + transaction_impl* connection:: begin () { @@ -168,7 +238,7 @@ namespace odb // unlock_notify() returns SQLITE_OK or SQLITE_LOCKED (deadlock). // - int e (sqlite3_unlock_notify (handle_, + int e (sqlite3_unlock_notify (handle (), &odb_sqlite_connection_unlock_callback, this)); if (e == SQLITE_LOCKED) @@ -186,11 +256,21 @@ namespace odb void connection:: clear () { - // The current first active_object will remove itself from the list - // and make the second object (if any) the new first. + invalidate_results (); + + // The current first active_object may remove itself from the list and + // make the second object (if any) the new first. // - while (active_objects_ != 0) - active_objects_->clear (); + for (active_object** pp (&active_objects_); *pp != 0; ) + { + active_object* p (*pp); + p->clear (); + + // Move to the next object if this one decided to stay on the list. + // + if (*pp == p) + pp = &p->next_; + } } // connection_factory @@ -206,6 +286,20 @@ namespace odb odb::connection_factory::db_ = &db; db_ = &db; } + + void connection_factory:: + attach_database (const connection_ptr& conn, + const std::string& name, + const std::string& schema) + { + conn->execute ("ATTACH DATABASE '" + name + "' AS \"" + schema + '"'); + } + + void connection_factory:: + detach_database (const connection_ptr& conn, const std::string& schema) + { + conn->execute ("DETACH DATABASE \"" + schema + '"'); + } } } diff --git a/odb/sqlite/connection.hxx b/odb/sqlite/connection.hxx index a71f07e..dbe4494 100644 --- a/odb/sqlite/connection.hxx +++ b/odb/sqlite/connection.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/connection.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_CONNECTION_HXX @@ -9,6 +8,7 @@ #include <sqlite3.h> +#include <odb/statement.hxx> #include <odb/connection.hxx> #include <odb/details/mutex.hxx> @@ -30,20 +30,22 @@ namespace odb namespace sqlite { class statement_cache; + class generic_statement; class connection_factory; + class attached_connection_factory; class connection; typedef details::shared_ptr<connection> connection_ptr; // SQLite "active object", i.e., an object that needs to be // "cleared" before the transaction can be committed and the - // connection release. These form a doubly-linked list. + // connection released. These form a doubly-linked list. // class LIBODB_SQLITE_EXPORT active_object { public: - // This function should remove the object from the list, since - // it shall no longer be "active". + // This function may remove the object from the list since it may no + // longer be "active". // virtual void clear () = 0; @@ -58,6 +60,8 @@ namespace odb list_remove (); protected: + friend class connection; + // prev_ == 0 means we are the first element. // next_ == 0 means we are the last element. // next_ == this means we are not on the list (prev_ should be 0). @@ -74,15 +78,42 @@ namespace odb typedef sqlite::statement_cache statement_cache_type; typedef sqlite::database database_type; + // Translate the database schema in the statement text (used to + // implement attached databases). If the result is empty, then no + // translation is required and the original text should be used as is. + // + typedef void (statement_translator) (std::string& result, + const char* text, + std::size_t text_size, + connection&); virtual ~connection (); - connection (connection_factory&, int extra_flags = 0); - connection (connection_factory&, sqlite3* handle); + connection (connection_factory&, + int extra_flags = 0, + statement_translator* = 0); + + connection (connection_factory&, + sqlite3* handle, + statement_translator* = 0); + + // Create an attached connection (see the attached database constructor + // for details). + // + connection (attached_connection_factory&, statement_translator*); database_type& database (); + // Return the main connection of an attached connection. If this + // connection is main, return itself. + // + connection& + main_connection (); + + static connection_ptr + main_connection (const connection_ptr&); + public: virtual transaction_impl* begin (); @@ -139,10 +170,7 @@ namespace odb public: sqlite3* - handle () - { - return handle_; - } + handle (); statement_cache_type& statement_cache () @@ -157,11 +185,36 @@ namespace odb wait (); public: - // Reset active statements. + // Reset active statements. Also invalidates query results by first + // calling invalidate_results(). // void clear (); + public: + // Note: only available on main connection. + // + generic_statement& + begin_statement (); + + generic_statement& + begin_immediate_statement (); + + generic_statement& + begin_exclusive_statement (); + + generic_statement& + commit_statement (); + + generic_statement& + rollback_statement (); + + protected: + friend class attached_connection_factory; + + connection_factory& + factory (); + private: connection (const connection&); connection& operator= (const connection&); @@ -171,13 +224,27 @@ namespace odb init (); private: + // Note that we use NULL handle as an indication of an attached + // connection. + // auto_handle<sqlite3> handle_; + statement_translator* statement_translator_; + // Keep statement_cache_ after handle_ so that it is destroyed before // the connection is closed. // details::unique_ptr<statement_cache_type> statement_cache_; + // Note: using odb::statement in order to break the connection-statement + // dependency cycle. + // + details::shared_ptr<odb::statement> begin_; + details::shared_ptr<odb::statement> begin_immediate_; + details::shared_ptr<odb::statement> begin_exclusive_; + details::shared_ptr<odb::statement> commit_; + details::shared_ptr<odb::statement> rollback_; + // Unlock notification machinery. // private: @@ -189,6 +256,7 @@ namespace odb connection_unlock_callback (void**, int); private: + friend class statement; // statement_translator_ friend class transaction_impl; // invalidate_results() // Linked list of active objects currently associated @@ -219,12 +287,65 @@ namespace odb connection_factory (): db_ (0) {} + // Attach/detach additional databases. Connection is one of the main + // connections created by this factory. Note: not called for "main" and + // "temp" schemas. + // + // The default implementations simply execute the ATTACH DATABASE and + // DETACH DATABASE SQLite statements. + // + virtual void + attach_database (const connection_ptr&, + const std::string& name, + const std::string& schema); + + virtual void + detach_database (const connection_ptr&, const std::string& schema); + // Needed to break the circular connection_factory-database dependency // (odb::connection_factory has the odb::database member). // protected: database_type* db_; }; + + // The call to database() should cause ATTACH DATABASE (or otherwise make + // sure the database is attached). Destruction of the factory should cause + // DETACH DATABASE (or otherwise notice that this factory no longer needs + // the database attached). + // + // Note that attached_connection_factory is an active object that + // registers itself with the main connection in order to get notified on + // transaction finalization. + // + class LIBODB_SQLITE_EXPORT attached_connection_factory: + public connection_factory, + public active_object + { + public: + explicit + attached_connection_factory (const connection_ptr& main) + : active_object (*main), main_connection_ (main) {} + + virtual void + detach () = 0; + + protected: + friend class database; + friend class connection; + friend class transaction_impl; + + connection_factory& + main_factory (); + + // Note that this essentially establishes a "framework" for all the + // attached connection factory implementations: they hold a counted + // reference to the main connection and they maintain a single shared + // attached connection. + // + connection_ptr main_connection_; + connection_ptr attached_connection_; + }; } } diff --git a/odb/sqlite/connection.ixx b/odb/sqlite/connection.ixx index 87b599f..094fd52 100644 --- a/odb/sqlite/connection.ixx +++ b/odb/sqlite/connection.ixx @@ -1,12 +1,11 @@ // file : odb/sqlite/connection.ixx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file namespace odb { namespace sqlite { - // active_objects + // active_object // inline void active_object:: list_add () @@ -38,6 +37,36 @@ namespace odb return static_cast<connection_factory&> (factory_).database (); } + inline connection& connection:: + main_connection () + { + return handle_ != 0 + ? *this + : *static_cast<attached_connection_factory&> (factory_).main_connection_; + } + + inline connection_ptr connection:: + main_connection (const connection_ptr& c) + { + return c->handle_ != 0 + ? c + : static_cast<attached_connection_factory&> (c->factory_).main_connection_; + } + + inline sqlite3* connection:: + handle () + { + return handle_ != 0 + ? handle_ + : static_cast<attached_connection_factory&> (factory_).main_connection_->handle_; + } + + inline connection_factory& connection:: + factory () + { + return static_cast<connection_factory&> (factory_); + } + template <typename T> inline prepared_query<T> connection:: prepare_query (const char* n, const char* q) @@ -67,5 +96,13 @@ namespace odb // return prepare_query<T> (n, sqlite::query_base (q)); } + + // attached_connection_factory + // + inline connection_factory& attached_connection_factory:: + main_factory () + { + return main_connection_->factory (); + } } } diff --git a/odb/sqlite/container-statements.hxx b/odb/sqlite/container-statements.hxx index 7edc2dc..b9cccf0 100644 --- a/odb/sqlite/container-statements.hxx +++ b/odb/sqlite/container-statements.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/container-statements.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_CONTAINER_STATEMENTS_HXX diff --git a/odb/sqlite/container-statements.txx b/odb/sqlite/container-statements.txx index 8f3844c..6db91f2 100644 --- a/odb/sqlite/container-statements.txx +++ b/odb/sqlite/container-statements.txx @@ -1,5 +1,4 @@ // file : odb/sqlite/container-statements.txx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <cstddef> // std::size_t diff --git a/odb/sqlite/database.cxx b/odb/sqlite/database.cxx index 79c8666..a7cf098 100644 --- a/odb/sqlite/database.cxx +++ b/odb/sqlite/database.cxx @@ -1,5 +1,4 @@ // file : odb/sqlite/database.cxx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifdef _WIN32 @@ -152,8 +151,35 @@ namespace odb factory_->database (*this); } + database:: + database (const connection_ptr& conn, + const string& name, + const string& schema, + transfer_ptr<attached_connection_factory> factory) + : odb::database (id_sqlite), + name_ (name), + schema_ (schema), + flags_ (0), + factory_ (factory.transfer ()) + { + assert (!schema_.empty ()); + + // Copy some things over from the connection's database. + // + database& db (conn->database ()); + + tracer_ = db.tracer_; + foreign_keys_ = db.foreign_keys_; + + if (!factory_) + factory_.reset (new default_attached_connection_factory ( + connection::main_connection (conn))); + + factory_->database (*this); + } + void database:: - print_usage (std::ostream& os) + print_usage (ostream& os) { details::options::print_usage (os); } @@ -197,7 +223,7 @@ namespace odb else if (!schema_version_table_.empty ()) text += schema_version_table_; // Already quoted. else - text += "\"schema_version\""; + text += "\"main\".\"schema_version\""; text += " WHERE \"name\" = ?"; @@ -226,7 +252,9 @@ namespace odb cp = factory_->connect (); sqlite::connection& c ( - cp != 0 ? *cp : transaction::current ().connection ()); + cp != 0 + ? *cp + : transaction::current ().connection (const_cast<database&> (*this))); try { diff --git a/odb/sqlite/database.hxx b/odb/sqlite/database.hxx index 024372c..e1e62cc 100644 --- a/odb/sqlite/database.hxx +++ b/odb/sqlite/database.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/database.hxx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_DATABASE_HXX @@ -84,8 +83,78 @@ namespace odb details::transfer_ptr<connection_factory> = details::transfer_ptr<connection_factory> ()); + // Attach to the specified connection a database with the specified name + // as the specified schema. Good understanding of SQLite ATTACH/DETACH + // DATABASE statements semantics and ODB connection management is + // strongly recommended when using this mechanism. + // + // The resulting database instance is referred to as an "attached + // database" and the connection it returns as an "attached connection" + // (which is just a proxy for the main connection). Database operations + // executed on the attached database or attached connection are + // automatically translated to refer to the specified schema rather than + // "main". For uniformity attached databases can also be created for the + // pre-attached "main" and "temp" schemas (in this case name can be + // anything). + // + // The automatic translation of the statements relies on their text + // having references to top-level database entities (tables, indexes, + // etc) qualified with the "main" schema. To achieve this, compile your + // headers with `--schema main` and, if using schema migration, with + // `--schema-version-table main.schema_version`. You must also not use + // "main" as an object/table alias in views of native statements. For + // optimal translation performance use 4-character schema names. + // + // The main connection and attached to it databases and connections are + // all meant to be used within the same thread. In particular, the + // attached database holds a counted reference to the main connection + // which means the connection will not be released until all the + // attached to this connection databases are destroyed. + // + // Note that in this model the attached databases are attached to the + // main connection, not to the (main) database, which mimics the + // underlying semantics of SQLite. An alternative model would have been + // to notionally attach the databases to the main database and under the + // hood automatically attach them to each returned connection. While + // this may seem like a more convenient model in some cases, it is also + // less flexible: the current model allows attaching a different set of + // databases to different connections, attaching them on demand as the + // transaction progresses, etc. Also, the more convenient model can be + // implemented on top of this model by deriving an application-specific + // database class and/or providing custom connection factories. + // + // Note that unless the name is a URI with appropriate mode, it is + // opened with the SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE flags. So if + // you want just SQLITE_OPEN_READWRITE, then you will need to verify its + // existence manually prior to calling this constructor. + // + // Note that attaching/detaching databases withing a transaction is only + // supported since SQLite 3.21.0. + // + database (const connection_ptr&, + const std::string& name, + const std::string& schema, + details::transfer_ptr<attached_connection_factory> = + details::transfer_ptr<attached_connection_factory> ()); + + // The database is automatically detached on destruction but a failure + // to detach is ignored. To detect such a failure perform explicit + // detach. For uniformity detaching a main database is a no-op. + // + void + detach (); + + // Return the main database of an attached database. If this database + // is main, return itself. + // + database& + main_database (); + // Move-constructible but not move-assignable. // + // Note: noexcept is not specified since odb::database(odb::database&&) + // can throw. + // #ifdef ODB_CXX11 database (database&&); #endif @@ -100,6 +169,15 @@ namespace odb return name_; } + // Schema name under which this database was attached or empty for the + // main database. + // + const std::string& + schema () const + { + return schema_; + } + int flags () const { @@ -464,12 +542,19 @@ namespace odb connection_ (); private: + friend class transaction_impl; // factory_ + // Note: remember to update move ctor if adding any new members. // std::string name_; + std::string schema_; int flags_; bool foreign_keys_; std::string vfs_; + + // Note: keep last so that all other database members are still valid + // during factory's destruction. + // details::unique_ptr<connection_factory> factory_; }; } diff --git a/odb/sqlite/database.ixx b/odb/sqlite/database.ixx index a62dad1..e906a39 100644 --- a/odb/sqlite/database.ixx +++ b/odb/sqlite/database.ixx @@ -1,5 +1,4 @@ // file : odb/sqlite/database.ixx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <utility> // move() @@ -15,6 +14,7 @@ namespace odb database (database&& db) // Has to be inline. : odb::database (std::move (db)), name_ (std::move (db.name_)), + schema_ (std::move (db.schema_)), flags_ (db.flags_), foreign_keys_ (db.foreign_keys_), vfs_ (std::move (db.vfs_)), @@ -24,6 +24,21 @@ namespace odb } #endif + inline void database:: + detach () + { + if (!schema_.empty ()) + static_cast<attached_connection_factory&> (*factory_).detach (); + } + + inline database& database:: + main_database () + { + return schema_.empty () + ? *this + : static_cast<attached_connection_factory&> (*factory_).main_connection_->database (); + } + inline connection_ptr database:: connection () { @@ -591,7 +606,7 @@ namespace odb { // Throws if not in transaction. // - sqlite::connection& c (transaction::current ().connection ()); + sqlite::connection& c (transaction::current ().connection (*this)); return c.prepare_query<T> (n, q); } diff --git a/odb/sqlite/details/.gitignore b/odb/sqlite/details/.gitignore index c6e608b..b298f89 100644 --- a/odb/sqlite/details/.gitignore +++ b/odb/sqlite/details/.gitignore @@ -1 +1 @@ -options.?xx +/options.?xx diff --git a/odb/sqlite/details/build2/config-stub.h b/odb/sqlite/details/build2/config-stub.h index c5f34dd..34ba8ff 100644 --- a/odb/sqlite/details/build2/config-stub.h +++ b/odb/sqlite/details/build2/config-stub.h @@ -1,5 +1,4 @@ /* file : odb/sqlite/details/build2/config-stub.h - * copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC * license : GNU GPL v2; see accompanying LICENSE file */ diff --git a/odb/sqlite/details/build2/config-vc-stub.h b/odb/sqlite/details/build2/config-vc-stub.h index f24b0c0..70e3e93 100644 --- a/odb/sqlite/details/build2/config-vc-stub.h +++ b/odb/sqlite/details/build2/config-vc-stub.h @@ -1,5 +1,4 @@ /* file : odb/sqlite/details/build2/config-vc-stub.h - * copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC * license : GNU GPL v2; see accompanying LICENSE file */ diff --git a/odb/sqlite/details/build2/config-vc.h b/odb/sqlite/details/build2/config-vc.h index a3b0299..75ce442 100644 --- a/odb/sqlite/details/build2/config-vc.h +++ b/odb/sqlite/details/build2/config-vc.h @@ -1,5 +1,4 @@ /* file : odb/sqlite/details/build2/config-vc.h - * copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC * license : GNU GPL v2; see accompanying LICENSE file */ diff --git a/odb/sqlite/details/build2/config.h b/odb/sqlite/details/build2/config.h index f304825..b4a1a1f 100644 --- a/odb/sqlite/details/build2/config.h +++ b/odb/sqlite/details/build2/config.h @@ -1,5 +1,4 @@ /* file : odb/sqlite/details/build2/config.h - * copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC * license : GNU GPL v2; see accompanying LICENSE file */ diff --git a/odb/sqlite/details/config-vc.h b/odb/sqlite/details/config-vc.h index 1f1fc61..f42c2a0 100644 --- a/odb/sqlite/details/config-vc.h +++ b/odb/sqlite/details/config-vc.h @@ -1,5 +1,4 @@ /* file : odb/sqlite/details/config-vc.h - * copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC * license : GNU GPL v2; see accompanying LICENSE file */ diff --git a/odb/sqlite/details/config.h.in b/odb/sqlite/details/config.h.in index e819fda..a223ecb 100644 --- a/odb/sqlite/details/config.h.in +++ b/odb/sqlite/details/config.h.in @@ -1,5 +1,4 @@ /* file : odb/sqlite/details/config.h.in - * copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC * license : GNU GPL v2; see accompanying LICENSE file */ diff --git a/odb/sqlite/details/config.hxx b/odb/sqlite/details/config.hxx index 25c976d..4f1c5ce 100644 --- a/odb/sqlite/details/config.hxx +++ b/odb/sqlite/details/config.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/details/config.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_DETAILS_CONFIG_HXX @@ -17,6 +16,18 @@ # endif #endif +// LIBODB_SQLITE_BUILD2 macro can be defined either by the buildfile or by the +// included odb/sqlite/details/config*.h (see above). +// +#ifdef LIBODB_SQLITE_BUILD2 +# include <sqlite3.h> + +# if SQLITE_VERSION_NUMBER >= 3006012 +# define LIBODB_SQLITE_HAVE_UNLOCK_NOTIFY 1 +# endif +# define LIBODB_SQLITE_HAVE_COLUMN_METADATA 1 +#endif + // no post #endif // ODB_SQLITE_DETAILS_CONFIG_HXX diff --git a/odb/sqlite/details/conversion.hxx b/odb/sqlite/details/conversion.hxx index 687c9d0..04843b2 100644 --- a/odb/sqlite/details/conversion.hxx +++ b/odb/sqlite/details/conversion.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/details/conversion.hxx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_DETAILS_CONVERSION_HXX diff --git a/odb/sqlite/details/export.hxx b/odb/sqlite/details/export.hxx index 3d838e7..c0903ae 100644 --- a/odb/sqlite/details/export.hxx +++ b/odb/sqlite/details/export.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/details/export.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_DETAILS_EXPORT_HXX @@ -7,7 +6,15 @@ #include <odb/pre.hxx> -#include <odb/sqlite/details/config.hxx> +#ifdef ODB_COMPILER +# error libodb-sqlite header included in odb-compiled header +#elif !defined(LIBODB_SQLITE_BUILD2) +# ifdef _MSC_VER +# include <odb/sqlite/details/config-vc.h> +# else +# include <odb/sqlite/details/config.h> +# endif +#endif // Normally we don't export class templates (but do complete specializations), // inline functions, and classes with only inline member functions. Exporting diff --git a/odb/sqlite/details/options.cli b/odb/sqlite/details/options.cli index 901457f..d1955c3 100644 --- a/odb/sqlite/details/options.cli +++ b/odb/sqlite/details/options.cli @@ -1,5 +1,4 @@ // file : odb/sqlite/details/options.cli -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file include <string>; diff --git a/odb/sqlite/details/pregenerated/odb/sqlite/details/options.cxx b/odb/sqlite/details/pregenerated/odb/sqlite/details/options.cxx new file mode 100644 index 0000000..12f4193 --- /dev/null +++ b/odb/sqlite/details/pregenerated/odb/sqlite/details/options.cxx @@ -0,0 +1,1027 @@ +// -*- C++ -*- +// +// This file was generated by CLI, a command line interface +// compiler for C++. +// + +// Begin prologue. +// +// +// End prologue. + +#include <odb/sqlite/details/options.hxx> + +#include <map> +#include <set> +#include <string> +#include <vector> +#include <utility> +#include <ostream> +#include <sstream> +#include <cstring> +#include <fstream> + +namespace odb +{ + namespace sqlite + { + namespace details + { + namespace cli + { + // unknown_option + // + unknown_option:: + ~unknown_option () throw () + { + } + + void unknown_option:: + print (::std::ostream& os) const + { + os << "unknown option '" << option ().c_str () << "'"; + } + + const char* unknown_option:: + what () const throw () + { + return "unknown option"; + } + + // unknown_argument + // + unknown_argument:: + ~unknown_argument () throw () + { + } + + void unknown_argument:: + print (::std::ostream& os) const + { + os << "unknown argument '" << argument ().c_str () << "'"; + } + + const char* unknown_argument:: + what () const throw () + { + return "unknown argument"; + } + + // missing_value + // + missing_value:: + ~missing_value () throw () + { + } + + void missing_value:: + print (::std::ostream& os) const + { + os << "missing value for option '" << option ().c_str () << "'"; + } + + const char* missing_value:: + what () const throw () + { + return "missing option value"; + } + + // invalid_value + // + invalid_value:: + ~invalid_value () throw () + { + } + + void invalid_value:: + print (::std::ostream& os) const + { + os << "invalid value '" << value ().c_str () << "' for option '" + << option ().c_str () << "'"; + + if (!message ().empty ()) + os << ": " << message ().c_str (); + } + + const char* invalid_value:: + what () const throw () + { + return "invalid option value"; + } + + // eos_reached + // + void eos_reached:: + print (::std::ostream& os) const + { + os << what (); + } + + const char* eos_reached:: + what () const throw () + { + return "end of argument stream reached"; + } + + // file_io_failure + // + file_io_failure:: + ~file_io_failure () throw () + { + } + + void file_io_failure:: + print (::std::ostream& os) const + { + os << "unable to open file '" << file ().c_str () << "' or read failure"; + } + + const char* file_io_failure:: + what () const throw () + { + return "unable to open file or read failure"; + } + + // unmatched_quote + // + unmatched_quote:: + ~unmatched_quote () throw () + { + } + + void unmatched_quote:: + print (::std::ostream& os) const + { + os << "unmatched quote in argument '" << argument ().c_str () << "'"; + } + + const char* unmatched_quote:: + what () const throw () + { + return "unmatched quote"; + } + + // scanner + // + scanner:: + ~scanner () + { + } + + // argv_scanner + // + bool argv_scanner:: + more () + { + return i_ < argc_; + } + + const char* argv_scanner:: + peek () + { + if (i_ < argc_) + return argv_[i_]; + else + throw eos_reached (); + } + + const char* argv_scanner:: + next () + { + if (i_ < argc_) + { + const char* r (argv_[i_]); + + if (erase_) + { + for (int i (i_ + 1); i < argc_; ++i) + argv_[i - 1] = argv_[i]; + + --argc_; + argv_[argc_] = 0; + } + else + ++i_; + + ++start_position_; + return r; + } + else + throw eos_reached (); + } + + void argv_scanner:: + skip () + { + if (i_ < argc_) + { + ++i_; + ++start_position_; + } + else + throw eos_reached (); + } + + std::size_t argv_scanner:: + position () + { + return start_position_; + } + + // argv_file_scanner + // + int argv_file_scanner::zero_argc_ = 0; + std::string argv_file_scanner::empty_string_; + + bool argv_file_scanner:: + more () + { + if (!args_.empty ()) + return true; + + while (base::more ()) + { + // See if the next argument is the file option. + // + const char* a (base::peek ()); + const option_info* oi = 0; + const char* ov = 0; + + if (!skip_) + { + if ((oi = find (a)) != 0) + { + base::next (); + + if (!base::more ()) + throw missing_value (a); + + ov = base::next (); + } + else if (std::strncmp (a, "-", 1) == 0) + { + if ((ov = std::strchr (a, '=')) != 0) + { + std::string o (a, 0, ov - a); + if ((oi = find (o.c_str ())) != 0) + { + base::next (); + ++ov; + } + } + } + } + + if (oi != 0) + { + if (oi->search_func != 0) + { + std::string f (oi->search_func (ov, oi->arg)); + + if (!f.empty ()) + load (f); + } + else + load (ov); + + if (!args_.empty ()) + return true; + } + else + { + if (!skip_) + skip_ = (std::strcmp (a, "--") == 0); + + return true; + } + } + + return false; + } + + const char* argv_file_scanner:: + peek () + { + if (!more ()) + throw eos_reached (); + + return args_.empty () ? base::peek () : args_.front ().value.c_str (); + } + + const std::string& argv_file_scanner:: + peek_file () + { + if (!more ()) + throw eos_reached (); + + return args_.empty () ? empty_string_ : *args_.front ().file; + } + + std::size_t argv_file_scanner:: + peek_line () + { + if (!more ()) + throw eos_reached (); + + return args_.empty () ? 0 : args_.front ().line; + } + + const char* argv_file_scanner:: + next () + { + if (!more ()) + throw eos_reached (); + + if (args_.empty ()) + return base::next (); + else + { + hold_[i_ == 0 ? ++i_ : --i_].swap (args_.front ().value); + args_.pop_front (); + ++start_position_; + return hold_[i_].c_str (); + } + } + + void argv_file_scanner:: + skip () + { + if (!more ()) + throw eos_reached (); + + if (args_.empty ()) + return base::skip (); + else + { + args_.pop_front (); + ++start_position_; + } + } + + const argv_file_scanner::option_info* argv_file_scanner:: + find (const char* a) const + { + for (std::size_t i (0); i < options_count_; ++i) + if (std::strcmp (a, options_[i].option) == 0) + return &options_[i]; + + return 0; + } + + std::size_t argv_file_scanner:: + position () + { + return start_position_; + } + + void argv_file_scanner:: + load (const std::string& file) + { + using namespace std; + + ifstream is (file.c_str ()); + + if (!is.is_open ()) + throw file_io_failure (file); + + files_.push_back (file); + + arg a; + a.file = &*files_.rbegin (); + + for (a.line = 1; !is.eof (); ++a.line) + { + string line; + getline (is, line); + + if (is.fail () && !is.eof ()) + throw file_io_failure (file); + + string::size_type n (line.size ()); + + // Trim the line from leading and trailing whitespaces. + // + if (n != 0) + { + const char* f (line.c_str ()); + const char* l (f + n); + + const char* of (f); + while (f < l && (*f == ' ' || *f == '\t' || *f == '\r')) + ++f; + + --l; + + const char* ol (l); + while (l > f && (*l == ' ' || *l == '\t' || *l == '\r')) + --l; + + if (f != of || l != ol) + line = f <= l ? string (f, l - f + 1) : string (); + } + + // Ignore empty lines, those that start with #. + // + if (line.empty () || line[0] == '#') + continue; + + string::size_type p (string::npos); + if (line.compare (0, 1, "-") == 0) + { + p = line.find (' '); + + string::size_type q (line.find ('=')); + if (q != string::npos && q < p) + p = q; + } + + string s1; + if (p != string::npos) + { + s1.assign (line, 0, p); + + // Skip leading whitespaces in the argument. + // + if (line[p] == '=') + ++p; + else + { + n = line.size (); + for (++p; p < n; ++p) + { + char c (line[p]); + if (c != ' ' && c != '\t' && c != '\r') + break; + } + } + } + else if (!skip_) + skip_ = (line == "--"); + + string s2 (line, p != string::npos ? p : 0); + + // If the string (which is an option value or argument) is + // wrapped in quotes, remove them. + // + n = s2.size (); + char cf (s2[0]), cl (s2[n - 1]); + + if (cf == '"' || cf == '\'' || cl == '"' || cl == '\'') + { + if (n == 1 || cf != cl) + throw unmatched_quote (s2); + + s2 = string (s2, 1, n - 2); + } + + if (!s1.empty ()) + { + // See if this is another file option. + // + const option_info* oi; + if (!skip_ && (oi = find (s1.c_str ()))) + { + if (s2.empty ()) + throw missing_value (oi->option); + + if (oi->search_func != 0) + { + string f (oi->search_func (s2.c_str (), oi->arg)); + if (!f.empty ()) + load (f); + } + else + { + // If the path of the file being parsed is not simple and the + // path of the file that needs to be loaded is relative, then + // complete the latter using the former as a base. + // +#ifndef _WIN32 + string::size_type p (file.find_last_of ('/')); + bool c (p != string::npos && s2[0] != '/'); +#else + string::size_type p (file.find_last_of ("/\\")); + bool c (p != string::npos && s2[1] != ':'); +#endif + if (c) + s2.insert (0, file, 0, p + 1); + + load (s2); + } + + continue; + } + + a.value = s1; + args_.push_back (a); + } + + a.value = s2; + args_.push_back (a); + } + } + + template <typename X> + struct parser + { + static void + parse (X& x, scanner& s) + { + using namespace std; + + const char* o (s.next ()); + if (s.more ()) + { + string v (s.next ()); + istringstream is (v); + if (!(is >> x && is.peek () == istringstream::traits_type::eof ())) + throw invalid_value (o, v); + } + else + throw missing_value (o); + } + }; + + template <> + struct parser<bool> + { + static void + parse (bool& x, scanner& s) + { + const char* o (s.next ()); + + if (s.more ()) + { + const char* v (s.next ()); + + if (std::strcmp (v, "1") == 0 || + std::strcmp (v, "true") == 0 || + std::strcmp (v, "TRUE") == 0 || + std::strcmp (v, "True") == 0) + x = true; + else if (std::strcmp (v, "0") == 0 || + std::strcmp (v, "false") == 0 || + std::strcmp (v, "FALSE") == 0 || + std::strcmp (v, "False") == 0) + x = false; + else + throw invalid_value (o, v); + } + else + throw missing_value (o); + } + }; + + template <> + struct parser<std::string> + { + static void + parse (std::string& x, scanner& s) + { + const char* o (s.next ()); + + if (s.more ()) + x = s.next (); + else + throw missing_value (o); + } + }; + + template <typename X> + struct parser<std::pair<X, std::size_t> > + { + static void + parse (std::pair<X, std::size_t>& x, scanner& s) + { + x.second = s.position (); + parser<X>::parse (x.first, s); + } + }; + + template <typename X> + struct parser<std::vector<X> > + { + static void + parse (std::vector<X>& c, scanner& s) + { + X x; + parser<X>::parse (x, s); + c.push_back (x); + } + }; + + template <typename X, typename C> + struct parser<std::set<X, C> > + { + static void + parse (std::set<X, C>& c, scanner& s) + { + X x; + parser<X>::parse (x, s); + c.insert (x); + } + }; + + template <typename K, typename V, typename C> + struct parser<std::map<K, V, C> > + { + static void + parse (std::map<K, V, C>& m, scanner& s) + { + const char* o (s.next ()); + + if (s.more ()) + { + std::size_t pos (s.position ()); + std::string ov (s.next ()); + std::string::size_type p = ov.find ('='); + + K k = K (); + V v = V (); + std::string kstr (ov, 0, p); + std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ())); + + int ac (2); + char* av[] = + { + const_cast<char*> (o), + 0 + }; + + if (!kstr.empty ()) + { + av[1] = const_cast<char*> (kstr.c_str ()); + argv_scanner s (0, ac, av, false, pos); + parser<K>::parse (k, s); + } + + if (!vstr.empty ()) + { + av[1] = const_cast<char*> (vstr.c_str ()); + argv_scanner s (0, ac, av, false, pos); + parser<V>::parse (v, s); + } + + m[k] = v; + } + else + throw missing_value (o); + } + }; + + template <typename K, typename V, typename C> + struct parser<std::multimap<K, V, C> > + { + static void + parse (std::multimap<K, V, C>& m, scanner& s) + { + const char* o (s.next ()); + + if (s.more ()) + { + std::size_t pos (s.position ()); + std::string ov (s.next ()); + std::string::size_type p = ov.find ('='); + + K k = K (); + V v = V (); + std::string kstr (ov, 0, p); + std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ())); + + int ac (2); + char* av[] = + { + const_cast<char*> (o), + 0 + }; + + if (!kstr.empty ()) + { + av[1] = const_cast<char*> (kstr.c_str ()); + argv_scanner s (0, ac, av, false, pos); + parser<K>::parse (k, s); + } + + if (!vstr.empty ()) + { + av[1] = const_cast<char*> (vstr.c_str ()); + argv_scanner s (0, ac, av, false, pos); + parser<V>::parse (v, s); + } + + m.insert (typename std::multimap<K, V, C>::value_type (k, v)); + } + else + throw missing_value (o); + } + }; + + template <typename X, typename T, T X::*M> + void + thunk (X& x, scanner& s) + { + parser<T>::parse (x.*M, s); + } + + template <typename X, bool X::*M> + void + thunk (X& x, scanner& s) + { + s.next (); + x.*M = true; + } + } + } + } +} + +#include <map> + +namespace odb +{ + namespace sqlite + { + namespace details + { + // options + // + + options:: + options () + : database_ (), + create_ (), + read_only_ (), + options_file_ () + { + } + + options:: + options (int& argc, + char** argv, + bool erase, + ::odb::sqlite::details::cli::unknown_mode opt, + ::odb::sqlite::details::cli::unknown_mode arg) + : database_ (), + create_ (), + read_only_ (), + options_file_ () + { + ::odb::sqlite::details::cli::argv_scanner s (argc, argv, erase); + _parse (s, opt, arg); + } + + options:: + options (int start, + int& argc, + char** argv, + bool erase, + ::odb::sqlite::details::cli::unknown_mode opt, + ::odb::sqlite::details::cli::unknown_mode arg) + : database_ (), + create_ (), + read_only_ (), + options_file_ () + { + ::odb::sqlite::details::cli::argv_scanner s (start, argc, argv, erase); + _parse (s, opt, arg); + } + + options:: + options (int& argc, + char** argv, + int& end, + bool erase, + ::odb::sqlite::details::cli::unknown_mode opt, + ::odb::sqlite::details::cli::unknown_mode arg) + : database_ (), + create_ (), + read_only_ (), + options_file_ () + { + ::odb::sqlite::details::cli::argv_scanner s (argc, argv, erase); + _parse (s, opt, arg); + end = s.end (); + } + + options:: + options (int start, + int& argc, + char** argv, + int& end, + bool erase, + ::odb::sqlite::details::cli::unknown_mode opt, + ::odb::sqlite::details::cli::unknown_mode arg) + : database_ (), + create_ (), + read_only_ (), + options_file_ () + { + ::odb::sqlite::details::cli::argv_scanner s (start, argc, argv, erase); + _parse (s, opt, arg); + end = s.end (); + } + + options:: + options (::odb::sqlite::details::cli::scanner& s, + ::odb::sqlite::details::cli::unknown_mode opt, + ::odb::sqlite::details::cli::unknown_mode arg) + : database_ (), + create_ (), + read_only_ (), + options_file_ () + { + _parse (s, opt, arg); + } + + ::odb::sqlite::details::cli::usage_para options:: + print_usage (::std::ostream& os, ::odb::sqlite::details::cli::usage_para p) + { + CLI_POTENTIALLY_UNUSED (os); + + if (p != ::odb::sqlite::details::cli::usage_para::none) + os << ::std::endl; + + os << "--database <filename> SQLite database file name. If the database file is not" << ::std::endl + << " specified then a private, temporary on-disk database will" << ::std::endl + << " be created. Use the :memory: special name to create a" << ::std::endl + << " private, temporary in-memory database." << ::std::endl; + + os << std::endl + << "--create Create the SQLite database if it does not already exist." << ::std::endl + << " By default opening the database fails if it does not" << ::std::endl + << " already exist." << ::std::endl; + + os << std::endl + << "--read-only Open the SQLite database in read-only mode. By default" << ::std::endl + << " the database is opened for reading and writing if" << ::std::endl + << " possible, or reading only if the file is write-protected" << ::std::endl + << " by the operating system." << ::std::endl; + + os << std::endl + << "--options-file <file> Read additional options from <file>. Each option should" << ::std::endl + << " appear on a separate line optionally followed by space or" << ::std::endl + << " equal sign (=) and an option value. Empty lines and lines" << ::std::endl + << " starting with # are ignored." << ::std::endl; + + p = ::odb::sqlite::details::cli::usage_para::option; + + return p; + } + + typedef + std::map<std::string, void (*) (options&, ::odb::sqlite::details::cli::scanner&)> + _cli_options_map; + + static _cli_options_map _cli_options_map_; + + struct _cli_options_map_init + { + _cli_options_map_init () + { + _cli_options_map_["--database"] = + &::odb::sqlite::details::cli::thunk< options, std::string, &options::database_ >; + _cli_options_map_["--create"] = + &::odb::sqlite::details::cli::thunk< options, &options::create_ >; + _cli_options_map_["--read-only"] = + &::odb::sqlite::details::cli::thunk< options, &options::read_only_ >; + _cli_options_map_["--options-file"] = + &::odb::sqlite::details::cli::thunk< options, std::string, &options::options_file_ >; + } + }; + + static _cli_options_map_init _cli_options_map_init_; + + bool options:: + _parse (const char* o, ::odb::sqlite::details::cli::scanner& s) + { + _cli_options_map::const_iterator i (_cli_options_map_.find (o)); + + if (i != _cli_options_map_.end ()) + { + (*(i->second)) (*this, s); + return true; + } + + return false; + } + + bool options:: + _parse (::odb::sqlite::details::cli::scanner& s, + ::odb::sqlite::details::cli::unknown_mode opt_mode, + ::odb::sqlite::details::cli::unknown_mode arg_mode) + { + bool r = false; + bool opt = true; + + while (s.more ()) + { + const char* o = s.peek (); + + if (std::strcmp (o, "--") == 0) + { + opt = false; + s.skip (); + r = true; + continue; + } + + if (opt) + { + if (_parse (o, s)) + { + r = true; + continue; + } + + if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0') + { + // Handle combined option values. + // + std::string co; + if (const char* v = std::strchr (o, '=')) + { + co.assign (o, 0, v - o); + ++v; + + int ac (2); + char* av[] = + { + const_cast<char*> (co.c_str ()), + const_cast<char*> (v) + }; + + ::odb::sqlite::details::cli::argv_scanner ns (0, ac, av); + + if (_parse (co.c_str (), ns)) + { + // Parsed the option but not its value? + // + if (ns.end () != 2) + throw ::odb::sqlite::details::cli::invalid_value (co, v); + + s.next (); + r = true; + continue; + } + else + { + // Set the unknown option and fall through. + // + o = co.c_str (); + } + } + + switch (opt_mode) + { + case ::odb::sqlite::details::cli::unknown_mode::skip: + { + s.skip (); + r = true; + continue; + } + case ::odb::sqlite::details::cli::unknown_mode::stop: + { + break; + } + case ::odb::sqlite::details::cli::unknown_mode::fail: + { + throw ::odb::sqlite::details::cli::unknown_option (o); + } + } + + break; + } + } + + switch (arg_mode) + { + case ::odb::sqlite::details::cli::unknown_mode::skip: + { + s.skip (); + r = true; + continue; + } + case ::odb::sqlite::details::cli::unknown_mode::stop: + { + break; + } + case ::odb::sqlite::details::cli::unknown_mode::fail: + { + throw ::odb::sqlite::details::cli::unknown_argument (o); + } + } + + break; + } + + return r; + } + } + } +} + +// Begin epilogue. +// +// +// End epilogue. + diff --git a/odb/sqlite/details/pregenerated/odb/sqlite/details/options.hxx b/odb/sqlite/details/pregenerated/odb/sqlite/details/options.hxx new file mode 100644 index 0000000..abc4b3f --- /dev/null +++ b/odb/sqlite/details/pregenerated/odb/sqlite/details/options.hxx @@ -0,0 +1,530 @@ +// -*- C++ -*- +// +// This file was generated by CLI, a command line interface +// compiler for C++. +// + +#ifndef LIBODB_SQLITE_DETAILS_OPTIONS_HXX +#define LIBODB_SQLITE_DETAILS_OPTIONS_HXX + +// Begin prologue. +// +// +// End prologue. + +#include <list> +#include <deque> +#include <iosfwd> +#include <string> +#include <cstddef> +#include <exception> + +#ifndef CLI_POTENTIALLY_UNUSED +# if defined(_MSC_VER) || defined(__xlC__) +# define CLI_POTENTIALLY_UNUSED(x) (void*)&x +# else +# define CLI_POTENTIALLY_UNUSED(x) (void)x +# endif +#endif + +namespace odb +{ + namespace sqlite + { + namespace details + { + namespace cli + { + class usage_para + { + public: + enum value + { + none, + text, + option + }; + + usage_para (value); + + operator value () const + { + return v_; + } + + private: + value v_; + }; + + class unknown_mode + { + public: + enum value + { + skip, + stop, + fail + }; + + unknown_mode (value); + + operator value () const + { + return v_; + } + + private: + value v_; + }; + + // Exceptions. + // + + class exception: public std::exception + { + public: + virtual void + print (::std::ostream&) const = 0; + }; + + ::std::ostream& + operator<< (::std::ostream&, const exception&); + + class unknown_option: public exception + { + public: + virtual + ~unknown_option () throw (); + + unknown_option (const std::string& option); + + const std::string& + option () const; + + virtual void + print (::std::ostream&) const; + + virtual const char* + what () const throw (); + + private: + std::string option_; + }; + + class unknown_argument: public exception + { + public: + virtual + ~unknown_argument () throw (); + + unknown_argument (const std::string& argument); + + const std::string& + argument () const; + + virtual void + print (::std::ostream&) const; + + virtual const char* + what () const throw (); + + private: + std::string argument_; + }; + + class missing_value: public exception + { + public: + virtual + ~missing_value () throw (); + + missing_value (const std::string& option); + + const std::string& + option () const; + + virtual void + print (::std::ostream&) const; + + virtual const char* + what () const throw (); + + private: + std::string option_; + }; + + class invalid_value: public exception + { + public: + virtual + ~invalid_value () throw (); + + invalid_value (const std::string& option, + const std::string& value, + const std::string& message = std::string ()); + + const std::string& + option () const; + + const std::string& + value () const; + + const std::string& + message () const; + + virtual void + print (::std::ostream&) const; + + virtual const char* + what () const throw (); + + private: + std::string option_; + std::string value_; + std::string message_; + }; + + class eos_reached: public exception + { + public: + virtual void + print (::std::ostream&) const; + + virtual const char* + what () const throw (); + }; + + class file_io_failure: public exception + { + public: + virtual + ~file_io_failure () throw (); + + file_io_failure (const std::string& file); + + const std::string& + file () const; + + virtual void + print (::std::ostream&) const; + + virtual const char* + what () const throw (); + + private: + std::string file_; + }; + + class unmatched_quote: public exception + { + public: + virtual + ~unmatched_quote () throw (); + + unmatched_quote (const std::string& argument); + + const std::string& + argument () const; + + virtual void + print (::std::ostream&) const; + + virtual const char* + what () const throw (); + + private: + std::string argument_; + }; + + // Command line argument scanner interface. + // + // The values returned by next() are guaranteed to be valid + // for the two previous arguments up until a call to a third + // peek() or next(). + // + // The position() function returns a monotonically-increasing + // number which, if stored, can later be used to determine the + // relative position of the argument returned by the following + // call to next(). Note that if multiple scanners are used to + // extract arguments from multiple sources, then the end + // position of the previous scanner should be used as the + // start position of the next. + // + class scanner + { + public: + virtual + ~scanner (); + + virtual bool + more () = 0; + + virtual const char* + peek () = 0; + + virtual const char* + next () = 0; + + virtual void + skip () = 0; + + virtual std::size_t + position () = 0; + }; + + class argv_scanner: public scanner + { + public: + argv_scanner (int& argc, + char** argv, + bool erase = false, + std::size_t start_position = 0); + + argv_scanner (int start, + int& argc, + char** argv, + bool erase = false, + std::size_t start_position = 0); + + int + end () const; + + virtual bool + more (); + + virtual const char* + peek (); + + virtual const char* + next (); + + virtual void + skip (); + + virtual std::size_t + position (); + + protected: + std::size_t start_position_; + int i_; + int& argc_; + char** argv_; + bool erase_; + }; + + class argv_file_scanner: public argv_scanner + { + public: + argv_file_scanner (int& argc, + char** argv, + const std::string& option, + bool erase = false, + std::size_t start_position = 0); + + argv_file_scanner (int start, + int& argc, + char** argv, + const std::string& option, + bool erase = false, + std::size_t start_position = 0); + + argv_file_scanner (const std::string& file, + const std::string& option, + std::size_t start_position = 0); + + struct option_info + { + // If search_func is not NULL, it is called, with the arg + // value as the second argument, to locate the options file. + // If it returns an empty string, then the file is ignored. + // + const char* option; + std::string (*search_func) (const char*, void* arg); + void* arg; + }; + + argv_file_scanner (int& argc, + char** argv, + const option_info* options, + std::size_t options_count, + bool erase = false, + std::size_t start_position = 0); + + argv_file_scanner (int start, + int& argc, + char** argv, + const option_info* options, + std::size_t options_count, + bool erase = false, + std::size_t start_position = 0); + + argv_file_scanner (const std::string& file, + const option_info* options = 0, + std::size_t options_count = 0, + std::size_t start_position = 0); + + virtual bool + more (); + + virtual const char* + peek (); + + virtual const char* + next (); + + virtual void + skip (); + + virtual std::size_t + position (); + + // Return the file path if the peeked at argument came from a file and + // the empty string otherwise. The reference is guaranteed to be valid + // till the end of the scanner lifetime. + // + const std::string& + peek_file (); + + // Return the 1-based line number if the peeked at argument came from + // a file and zero otherwise. + // + std::size_t + peek_line (); + + private: + const option_info* + find (const char*) const; + + void + load (const std::string& file); + + typedef argv_scanner base; + + const std::string option_; + option_info option_info_; + const option_info* options_; + std::size_t options_count_; + + struct arg + { + std::string value; + const std::string* file; + std::size_t line; + }; + + std::deque<arg> args_; + std::list<std::string> files_; + + // Circular buffer of two arguments. + // + std::string hold_[2]; + std::size_t i_; + + bool skip_; + + static int zero_argc_; + static std::string empty_string_; + }; + + template <typename X> + struct parser; + } + } + } +} + +#include <string> + +namespace odb +{ + namespace sqlite + { + namespace details + { + class options + { + public: + options (); + + options (int& argc, + char** argv, + bool erase = false, + ::odb::sqlite::details::cli::unknown_mode option = ::odb::sqlite::details::cli::unknown_mode::fail, + ::odb::sqlite::details::cli::unknown_mode argument = ::odb::sqlite::details::cli::unknown_mode::stop); + + options (int start, + int& argc, + char** argv, + bool erase = false, + ::odb::sqlite::details::cli::unknown_mode option = ::odb::sqlite::details::cli::unknown_mode::fail, + ::odb::sqlite::details::cli::unknown_mode argument = ::odb::sqlite::details::cli::unknown_mode::stop); + + options (int& argc, + char** argv, + int& end, + bool erase = false, + ::odb::sqlite::details::cli::unknown_mode option = ::odb::sqlite::details::cli::unknown_mode::fail, + ::odb::sqlite::details::cli::unknown_mode argument = ::odb::sqlite::details::cli::unknown_mode::stop); + + options (int start, + int& argc, + char** argv, + int& end, + bool erase = false, + ::odb::sqlite::details::cli::unknown_mode option = ::odb::sqlite::details::cli::unknown_mode::fail, + ::odb::sqlite::details::cli::unknown_mode argument = ::odb::sqlite::details::cli::unknown_mode::stop); + + options (::odb::sqlite::details::cli::scanner&, + ::odb::sqlite::details::cli::unknown_mode option = ::odb::sqlite::details::cli::unknown_mode::fail, + ::odb::sqlite::details::cli::unknown_mode argument = ::odb::sqlite::details::cli::unknown_mode::stop); + + // Option accessors. + // + const std::string& + database () const; + + const bool& + create () const; + + const bool& + read_only () const; + + const std::string& + options_file () const; + + // Print usage information. + // + static ::odb::sqlite::details::cli::usage_para + print_usage (::std::ostream&, + ::odb::sqlite::details::cli::usage_para = ::odb::sqlite::details::cli::usage_para::none); + + // Implementation details. + // + protected: + bool + _parse (const char*, ::odb::sqlite::details::cli::scanner&); + + private: + bool + _parse (::odb::sqlite::details::cli::scanner&, + ::odb::sqlite::details::cli::unknown_mode option, + ::odb::sqlite::details::cli::unknown_mode argument); + + public: + std::string database_; + bool create_; + bool read_only_; + std::string options_file_; + }; + } + } +} + +#include <odb/sqlite/details/options.ixx> + +// Begin epilogue. +// +// +// End epilogue. + +#endif // LIBODB_SQLITE_DETAILS_OPTIONS_HXX diff --git a/odb/sqlite/details/pregenerated/odb/sqlite/details/options.ixx b/odb/sqlite/details/pregenerated/odb/sqlite/details/options.ixx new file mode 100644 index 0000000..54092aa --- /dev/null +++ b/odb/sqlite/details/pregenerated/odb/sqlite/details/options.ixx @@ -0,0 +1,324 @@ +// -*- C++ -*- +// +// This file was generated by CLI, a command line interface +// compiler for C++. +// + +// Begin prologue. +// +// +// End prologue. + +#include <cassert> + +namespace odb +{ + namespace sqlite + { + namespace details + { + namespace cli + { + // usage_para + // + inline usage_para:: + usage_para (value v) + : v_ (v) + { + } + + // unknown_mode + // + inline unknown_mode:: + unknown_mode (value v) + : v_ (v) + { + } + + // exception + // + inline ::std::ostream& + operator<< (::std::ostream& os, const exception& e) + { + e.print (os); + return os; + } + + // unknown_option + // + inline unknown_option:: + unknown_option (const std::string& option) + : option_ (option) + { + } + + inline const std::string& unknown_option:: + option () const + { + return option_; + } + + // unknown_argument + // + inline unknown_argument:: + unknown_argument (const std::string& argument) + : argument_ (argument) + { + } + + inline const std::string& unknown_argument:: + argument () const + { + return argument_; + } + + // missing_value + // + inline missing_value:: + missing_value (const std::string& option) + : option_ (option) + { + } + + inline const std::string& missing_value:: + option () const + { + return option_; + } + + // invalid_value + // + inline invalid_value:: + invalid_value (const std::string& option, + const std::string& value, + const std::string& message) + : option_ (option), + value_ (value), + message_ (message) + { + } + + inline const std::string& invalid_value:: + option () const + { + return option_; + } + + inline const std::string& invalid_value:: + value () const + { + return value_; + } + + inline const std::string& invalid_value:: + message () const + { + return message_; + } + + // file_io_failure + // + inline file_io_failure:: + file_io_failure (const std::string& file) + : file_ (file) + { + } + + inline const std::string& file_io_failure:: + file () const + { + return file_; + } + + // unmatched_quote + // + inline unmatched_quote:: + unmatched_quote (const std::string& argument) + : argument_ (argument) + { + } + + inline const std::string& unmatched_quote:: + argument () const + { + return argument_; + } + + // argv_scanner + // + inline argv_scanner:: + argv_scanner (int& argc, + char** argv, + bool erase, + std::size_t sp) + : start_position_ (sp + 1), + i_ (1), + argc_ (argc), + argv_ (argv), + erase_ (erase) + { + } + + inline argv_scanner:: + argv_scanner (int start, + int& argc, + char** argv, + bool erase, + std::size_t sp) + : start_position_ (sp + static_cast<std::size_t> (start)), + i_ (start), + argc_ (argc), + argv_ (argv), + erase_ (erase) + { + } + + inline int argv_scanner:: + end () const + { + return i_; + } + + // argv_file_scanner + // + inline argv_file_scanner:: + argv_file_scanner (int& argc, + char** argv, + const std::string& option, + bool erase, + std::size_t sp) + : argv_scanner (argc, argv, erase, sp), + option_ (option), + options_ (&option_info_), + options_count_ (1), + i_ (1), + skip_ (false) + { + option_info_.option = option_.c_str (); + option_info_.search_func = 0; + } + + inline argv_file_scanner:: + argv_file_scanner (int start, + int& argc, + char** argv, + const std::string& option, + bool erase, + std::size_t sp) + : argv_scanner (start, argc, argv, erase, sp), + option_ (option), + options_ (&option_info_), + options_count_ (1), + i_ (1), + skip_ (false) + { + option_info_.option = option_.c_str (); + option_info_.search_func = 0; + } + + inline argv_file_scanner:: + argv_file_scanner (const std::string& file, + const std::string& option, + std::size_t sp) + : argv_scanner (0, zero_argc_, 0, sp), + option_ (option), + options_ (&option_info_), + options_count_ (1), + i_ (1), + skip_ (false) + { + option_info_.option = option_.c_str (); + option_info_.search_func = 0; + + load (file); + } + + inline argv_file_scanner:: + argv_file_scanner (int& argc, + char** argv, + const option_info* options, + std::size_t options_count, + bool erase, + std::size_t sp) + : argv_scanner (argc, argv, erase, sp), + options_ (options), + options_count_ (options_count), + i_ (1), + skip_ (false) + { + } + + inline argv_file_scanner:: + argv_file_scanner (int start, + int& argc, + char** argv, + const option_info* options, + std::size_t options_count, + bool erase, + std::size_t sp) + : argv_scanner (start, argc, argv, erase, sp), + options_ (options), + options_count_ (options_count), + i_ (1), + skip_ (false) + { + } + + inline argv_file_scanner:: + argv_file_scanner (const std::string& file, + const option_info* options, + std::size_t options_count, + std::size_t sp) + : argv_scanner (0, zero_argc_, 0, sp), + options_ (options), + options_count_ (options_count), + i_ (1), + skip_ (false) + { + load (file); + } + } + } + } +} + +namespace odb +{ + namespace sqlite + { + namespace details + { + // options + // + + inline const std::string& options:: + database () const + { + return this->database_; + } + + inline const bool& options:: + create () const + { + return this->create_; + } + + inline const bool& options:: + read_only () const + { + return this->read_only_; + } + + inline const std::string& options:: + options_file () const + { + return this->options_file_; + } + } + } +} + +// Begin epilogue. +// +// +// End epilogue. diff --git a/odb/sqlite/error.cxx b/odb/sqlite/error.cxx index 49bdc96..ae6bbe3 100644 --- a/odb/sqlite/error.cxx +++ b/odb/sqlite/error.cxx @@ -1,5 +1,4 @@ // file : odb/sqlite/error.cxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <sqlite3.h> diff --git a/odb/sqlite/error.hxx b/odb/sqlite/error.hxx index 441e8ff..4646f85 100644 --- a/odb/sqlite/error.hxx +++ b/odb/sqlite/error.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/error.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_ERROR_HXX diff --git a/odb/sqlite/exceptions.cxx b/odb/sqlite/exceptions.cxx index be06891..0621189 100644 --- a/odb/sqlite/exceptions.cxx +++ b/odb/sqlite/exceptions.cxx @@ -1,5 +1,4 @@ // file : odb/sqlite/exceptions.cxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <sstream> diff --git a/odb/sqlite/exceptions.hxx b/odb/sqlite/exceptions.hxx index 4312c31..3adb433 100644 --- a/odb/sqlite/exceptions.hxx +++ b/odb/sqlite/exceptions.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/exceptions.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_EXCEPTIONS_HXX diff --git a/odb/sqlite/forward.hxx b/odb/sqlite/forward.hxx index e31b156..1be05b4 100644 --- a/odb/sqlite/forward.hxx +++ b/odb/sqlite/forward.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/forward.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_FORWARD_HXX diff --git a/odb/sqlite/makefile b/odb/sqlite/makefile index b0baab1..485b9ec 100644 --- a/odb/sqlite/makefile +++ b/odb/sqlite/makefile @@ -1,5 +1,4 @@ # file : odb/sqlite/makefile -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file include $(dir $(lastword $(MAKEFILE_LIST)))../../build/bootstrap.make @@ -17,7 +16,6 @@ query-const-expr.cxx \ simple-object-statements.cxx \ statement.cxx \ statements-base.cxx \ -statement-cache.cxx \ stream.cxx \ tracer.cxx \ traits.cxx \ @@ -113,7 +111,7 @@ libodb-sqlite-vc10.vcxproj libodb-sqlite-vc10.vcxproj.filters \ libodb-sqlite-vc11.vcxproj libodb-sqlite-vc11.vcxproj.filters \ libodb-sqlite-vc12.vcxproj libodb-sqlite-vc12.vcxproj.filters $(dist): export interface_version = $(shell sed -e \ -'s/^\([0-9]*\.[0-9]*\).*/\1/' $(src_root)/version) +'s/^\([0-9]*\.[0-9]*\).*/\1/' $(src_root)/version.txt) $(dist): $(gen) $(call dist-data,$(sources_dist) $(headers_dist) $(data_dist)) diff --git a/odb/sqlite/no-id-object-result.hxx b/odb/sqlite/no-id-object-result.hxx index 4b6b3d5..b0edb09 100644 --- a/odb/sqlite/no-id-object-result.hxx +++ b/odb/sqlite/no-id-object-result.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/no-id-object-result.hxx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_NO_ID_OBJECT_RESULT_HXX diff --git a/odb/sqlite/no-id-object-result.txx b/odb/sqlite/no-id-object-result.txx index 0d3cae8..bd26afc 100644 --- a/odb/sqlite/no-id-object-result.txx +++ b/odb/sqlite/no-id-object-result.txx @@ -1,5 +1,4 @@ // file : odb/sqlite/no-id-object-result.txx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <odb/callback.hxx> diff --git a/odb/sqlite/no-id-object-statements.hxx b/odb/sqlite/no-id-object-statements.hxx index fb57967..7a0376a 100644 --- a/odb/sqlite/no-id-object-statements.hxx +++ b/odb/sqlite/no-id-object-statements.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/no-id-object-statements.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_NO_ID_OBJECT_STATEMENTS_HXX diff --git a/odb/sqlite/no-id-object-statements.txx b/odb/sqlite/no-id-object-statements.txx index 1fe1db8..d0a62b2 100644 --- a/odb/sqlite/no-id-object-statements.txx +++ b/odb/sqlite/no-id-object-statements.txx @@ -1,5 +1,4 @@ // file : odb/sqlite/no-id-object-statements.txx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <cstring> // std::memset diff --git a/odb/sqlite/polymorphic-object-result.hxx b/odb/sqlite/polymorphic-object-result.hxx index a9d34da..3239471 100644 --- a/odb/sqlite/polymorphic-object-result.hxx +++ b/odb/sqlite/polymorphic-object-result.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/polymorphic-object-result.hxx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_POLYMORPHIC_OBJECT_RESULT_HXX diff --git a/odb/sqlite/polymorphic-object-result.txx b/odb/sqlite/polymorphic-object-result.txx index 960c477..bd22f01 100644 --- a/odb/sqlite/polymorphic-object-result.txx +++ b/odb/sqlite/polymorphic-object-result.txx @@ -1,5 +1,4 @@ // file : odb/sqlite/polymorphic-object-result.txx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <cassert> diff --git a/odb/sqlite/polymorphic-object-statements.hxx b/odb/sqlite/polymorphic-object-statements.hxx index ddee2f0..736686b 100644 --- a/odb/sqlite/polymorphic-object-statements.hxx +++ b/odb/sqlite/polymorphic-object-statements.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/polymorphic-object-statements.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_POLYMORPHIC_OBJECT_STATEMENTS_HXX diff --git a/odb/sqlite/polymorphic-object-statements.txx b/odb/sqlite/polymorphic-object-statements.txx index 6757e4b..6a376d3 100644 --- a/odb/sqlite/polymorphic-object-statements.txx +++ b/odb/sqlite/polymorphic-object-statements.txx @@ -1,5 +1,4 @@ // file : odb/sqlite/polymorphic-object-statements.txx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <cstring> // std::memset @@ -117,7 +116,7 @@ namespace odb root_type& robj, const schema_version_migration* svm) { - connection_type& conn (transaction::current ().connection ()); + connection_type& conn (transaction::current ().connection (db)); polymorphic_derived_object_statements& sts ( conn.statement_cache ().find_object<object_type> ()); root_statements_type& rsts (sts.root_statements ()); diff --git a/odb/sqlite/prepared-query.cxx b/odb/sqlite/prepared-query.cxx index 6812b39..79df0f2 100644 --- a/odb/sqlite/prepared-query.cxx +++ b/odb/sqlite/prepared-query.cxx @@ -1,9 +1,10 @@ // file : odb/sqlite/prepared-query.cxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <odb/sqlite/prepared-query.hxx> +#include <odb/sqlite/connection.hxx> + namespace odb { namespace sqlite @@ -12,5 +13,15 @@ namespace odb ~prepared_query_impl () { } + + bool prepared_query_impl:: + verify_connection (odb::transaction& t) + { + // The transaction can be started using the main database of any of the + // attached databases. So we verify the main connections match. + // + return &static_cast<connection&> (t.connection ()).main_connection () == + &static_cast<connection&> (stmt->connection ()).main_connection (); + } } } diff --git a/odb/sqlite/prepared-query.hxx b/odb/sqlite/prepared-query.hxx index d688b06..a8873a5 100644 --- a/odb/sqlite/prepared-query.hxx +++ b/odb/sqlite/prepared-query.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/prepared-query.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_PREPARED_QUERY_HXX @@ -25,6 +24,9 @@ namespace odb prepared_query_impl (odb::connection& c): odb::prepared_query_impl (c) {} + virtual bool + verify_connection (odb::transaction&); + sqlite::query_base query; }; } diff --git a/odb/sqlite/query-const-expr.cxx b/odb/sqlite/query-const-expr.cxx index 17ef809..c8eaec7 100644 --- a/odb/sqlite/query-const-expr.cxx +++ b/odb/sqlite/query-const-expr.cxx @@ -1,5 +1,4 @@ // file : odb/sqlite/query-const-expr.cxx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <odb/sqlite/query.hxx> diff --git a/odb/sqlite/query-dynamic.cxx b/odb/sqlite/query-dynamic.cxx index 5a05011..8089aed 100644 --- a/odb/sqlite/query-dynamic.cxx +++ b/odb/sqlite/query-dynamic.cxx @@ -1,5 +1,4 @@ // file : odb/sqlite/query-dynamic.cxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <cstddef> // std::size_t diff --git a/odb/sqlite/query-dynamic.hxx b/odb/sqlite/query-dynamic.hxx index ee14f32..f720a95 100644 --- a/odb/sqlite/query-dynamic.hxx +++ b/odb/sqlite/query-dynamic.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/query-dynamic.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_QUERY_DYNAMIC_HXX diff --git a/odb/sqlite/query-dynamic.ixx b/odb/sqlite/query-dynamic.ixx index 0a51893..7fafe3e 100644 --- a/odb/sqlite/query-dynamic.ixx +++ b/odb/sqlite/query-dynamic.ixx @@ -1,5 +1,4 @@ // file : odb/sqlite/query-dynamic.ixx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file namespace odb diff --git a/odb/sqlite/query-dynamic.txx b/odb/sqlite/query-dynamic.txx index faebf25..48b7ec4 100644 --- a/odb/sqlite/query-dynamic.txx +++ b/odb/sqlite/query-dynamic.txx @@ -1,5 +1,4 @@ // file : odb/sqlite/query-dynamic.txx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file namespace odb diff --git a/odb/sqlite/query.cxx b/odb/sqlite/query.cxx index 5862f83..98eb1cd 100644 --- a/odb/sqlite/query.cxx +++ b/odb/sqlite/query.cxx @@ -1,5 +1,4 @@ // file : odb/sqlite/query.cxx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <cstddef> // std::size_t diff --git a/odb/sqlite/query.hxx b/odb/sqlite/query.hxx index 8e45c32..c9cbfaa 100644 --- a/odb/sqlite/query.hxx +++ b/odb/sqlite/query.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/query.hxx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_QUERY_HXX @@ -179,13 +178,14 @@ namespace odb kind_bool }; - clause_part (kind_type k): kind (k) {} - clause_part (kind_type k, const std::string& p): kind (k), part (p) {} + clause_part (kind_type k): kind (k), bool_part (false) {} + clause_part (kind_type k, const std::string& p) + : kind (k), part (p), bool_part (false) {} clause_part (bool p): kind (kind_bool), bool_part (p) {} kind_type kind; std::string part; // If kind is param, then part is conversion expr. - bool bool_part = false; + bool bool_part; }; query_base () diff --git a/odb/sqlite/query.ixx b/odb/sqlite/query.ixx index 2b4cd3f..00e9b66 100644 --- a/odb/sqlite/query.ixx +++ b/odb/sqlite/query.ixx @@ -1,5 +1,4 @@ // file : odb/sqlite/query.ixx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file namespace odb diff --git a/odb/sqlite/query.txx b/odb/sqlite/query.txx index 3ee8bdf..f381ff0 100644 --- a/odb/sqlite/query.txx +++ b/odb/sqlite/query.txx @@ -1,5 +1,4 @@ // file : odb/sqlite/query.txx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file namespace odb diff --git a/odb/sqlite/section-statements.hxx b/odb/sqlite/section-statements.hxx index 2ac489f..e6a5da6 100644 --- a/odb/sqlite/section-statements.hxx +++ b/odb/sqlite/section-statements.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/section-statements.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_SECTION_STATEMENTS_HXX diff --git a/odb/sqlite/section-statements.txx b/odb/sqlite/section-statements.txx index 1fdc7a2..ff588b3 100644 --- a/odb/sqlite/section-statements.txx +++ b/odb/sqlite/section-statements.txx @@ -1,5 +1,4 @@ // file : odb/sqlite/section-statements.txx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <cstring> // std::memset diff --git a/odb/sqlite/simple-object-result.hxx b/odb/sqlite/simple-object-result.hxx index 223257a..d68af8e 100644 --- a/odb/sqlite/simple-object-result.hxx +++ b/odb/sqlite/simple-object-result.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/simple-object-result.hxx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_SIMPLE_OBJECT_RESULT_HXX diff --git a/odb/sqlite/simple-object-result.txx b/odb/sqlite/simple-object-result.txx index 542a006..f27b226 100644 --- a/odb/sqlite/simple-object-result.txx +++ b/odb/sqlite/simple-object-result.txx @@ -1,5 +1,4 @@ // file : odb/sqlite/simple-object-result.txx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <cassert> diff --git a/odb/sqlite/simple-object-statements.cxx b/odb/sqlite/simple-object-statements.cxx index bb93645..1eb07db 100644 --- a/odb/sqlite/simple-object-statements.cxx +++ b/odb/sqlite/simple-object-statements.cxx @@ -1,5 +1,4 @@ // file : odb/sqlite/simple-object-statements.cxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <odb/sqlite/simple-object-statements.hxx> diff --git a/odb/sqlite/simple-object-statements.hxx b/odb/sqlite/simple-object-statements.hxx index 41bcba9..b60fe6c 100644 --- a/odb/sqlite/simple-object-statements.hxx +++ b/odb/sqlite/simple-object-statements.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/simple-object-statements.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_SIMPLE_OBJECT_STATEMENTS_HXX diff --git a/odb/sqlite/simple-object-statements.ixx b/odb/sqlite/simple-object-statements.ixx index 0cd08e7..6756c06 100644 --- a/odb/sqlite/simple-object-statements.ixx +++ b/odb/sqlite/simple-object-statements.ixx @@ -1,5 +1,4 @@ // file : odb/sqlite/simple-object-statements.ixx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file namespace odb diff --git a/odb/sqlite/simple-object-statements.txx b/odb/sqlite/simple-object-statements.txx index 43efd28..b80944d 100644 --- a/odb/sqlite/simple-object-statements.txx +++ b/odb/sqlite/simple-object-statements.txx @@ -1,5 +1,4 @@ // file : odb/sqlite/simple-object-statements.txx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <cstring> // std::memset diff --git a/odb/sqlite/sqlite-types.hxx b/odb/sqlite/sqlite-types.hxx index fa46b32..b9839bf 100644 --- a/odb/sqlite/sqlite-types.hxx +++ b/odb/sqlite/sqlite-types.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/sqlite-types.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_SQLITE_TYPES_HXX diff --git a/odb/sqlite/statement-cache.cxx b/odb/sqlite/statement-cache.cxx deleted file mode 100644 index 36d71ee..0000000 --- a/odb/sqlite/statement-cache.cxx +++ /dev/null @@ -1,40 +0,0 @@ -// file : odb/sqlite/statement-cache.cxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC -// license : GNU GPL v2; see accompanying LICENSE file - -#include <odb/sqlite/statement-cache.hxx> - -namespace odb -{ - using namespace details; - - namespace sqlite - { - statement_cache:: - statement_cache (connection& conn) - : conn_ (conn), - version_seq_ (conn.database ().schema_version_sequence ()), - // String lengths below include '\0', as per SQLite manual - // suggestions. - // - begin_ (new (shared) generic_statement (conn_, "BEGIN", 6)), - commit_ (new (shared) generic_statement (conn_, "COMMIT", 7)), - rollback_ (new (shared) generic_statement (conn_, "ROLLBACK", 9)) - { - } - - void statement_cache:: - begin_immediate_statement_ () const - { - begin_immediate_.reset ( - new (shared) generic_statement (conn_, "BEGIN IMMEDIATE", 16)); - } - - void statement_cache:: - begin_exclusive_statement_ () const - { - begin_exclusive_.reset ( - new (shared) generic_statement (conn_, "BEGIN EXCLUSIVE", 16)); - } - } -} diff --git a/odb/sqlite/statement-cache.hxx b/odb/sqlite/statement-cache.hxx index ffa7f34..31ca685 100644 --- a/odb/sqlite/statement-cache.hxx +++ b/odb/sqlite/statement-cache.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/statement-cache.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_STATEMENT_CACHE_HXX @@ -30,43 +29,9 @@ namespace odb class LIBODB_SQLITE_EXPORT statement_cache { public: - statement_cache (connection&); - - generic_statement& - begin_statement () const - { - return *begin_; - } - - generic_statement& - begin_immediate_statement () const - { - if (!begin_immediate_) - begin_immediate_statement_ (); - - return *begin_immediate_; - } - - generic_statement& - begin_exclusive_statement () const - { - if (!begin_exclusive_) - begin_exclusive_statement_ (); - - return *begin_exclusive_; - } - - generic_statement& - commit_statement () const - { - return *commit_; - } - - generic_statement& - rollback_statement () const - { - return *rollback_; - } + statement_cache (connection& conn) + : conn_ (conn), + version_seq_ (conn_.database ().schema_version_sequence ()) {} template <typename T> typename object_traits_impl<T, id_sqlite>::statements_type& @@ -77,26 +42,12 @@ namespace odb find_view (); private: - void - begin_immediate_statement_ () const; - - void - begin_exclusive_statement_ () const; - - private: typedef std::map<const std::type_info*, details::shared_ptr<statements_base>, details::type_info_comparator> map; connection& conn_; unsigned int version_seq_; - - details::shared_ptr<generic_statement> begin_; - mutable details::shared_ptr<generic_statement> begin_immediate_; - mutable details::shared_ptr<generic_statement> begin_exclusive_; - details::shared_ptr<generic_statement> commit_; - details::shared_ptr<generic_statement> rollback_; - map map_; }; } diff --git a/odb/sqlite/statement-cache.txx b/odb/sqlite/statement-cache.txx index 1dedb58..c089e32 100644 --- a/odb/sqlite/statement-cache.txx +++ b/odb/sqlite/statement-cache.txx @@ -1,5 +1,4 @@ // file : odb/sqlite/statement-cache.txx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <odb/sqlite/database.hxx> diff --git a/odb/sqlite/statement.cxx b/odb/sqlite/statement.cxx index da72d38..b1b0f58 100644 --- a/odb/sqlite/statement.cxx +++ b/odb/sqlite/statement.cxx @@ -1,5 +1,4 @@ // file : odb/sqlite/statement.cxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <odb/tracer.hxx> @@ -28,7 +27,7 @@ namespace odb { { odb::tracer* t; - if ((t = conn_.transaction_tracer ()) || + if ((t = conn_.main_connection ().transaction_tracer ()) || (t = conn_.tracer ()) || (t = conn_.database ().tracer ())) t->deallocate (conn_, *this); @@ -56,27 +55,27 @@ namespace odb { active_ = false; - string tmp; + string tmp1; if (proc != 0) { switch (sk) { case statement_select: - process_select (tmp, + process_select (tmp1, text, &proc->bind->buffer, proc->count, sizeof (bind), '"', '"', optimize); break; case statement_insert: - process_insert (tmp, + process_insert (tmp1, text, &proc->bind->buffer, proc->count, sizeof (bind), '?', '$'); break; case statement_update: - process_update (tmp, + process_update (tmp1, text, &proc->bind->buffer, proc->count, sizeof (bind), '?', @@ -87,8 +86,20 @@ namespace odb assert (false); } - text = tmp.c_str (); - text_size = tmp.size (); + text = tmp1.c_str (); + text_size = tmp1.size (); + } + + string tmp2; + if (conn_.statement_translator_ != 0) + { + conn_.statement_translator_ (tmp2, text, text_size, conn_); + + if (!tmp2.empty ()) + { + text = tmp2.c_str (); + text_size = tmp2.size (); + } } #if SQLITE_VERSION_NUMBER < 3005003 @@ -102,7 +113,7 @@ namespace odb { odb::tracer* t; - if ((t = conn_.transaction_tracer ()) || + if ((t = conn_.main_connection ().transaction_tracer ()) || (t = conn_.tracer ()) || (t = conn_.database ().tracer ())) { @@ -478,7 +489,7 @@ namespace odb { odb::tracer* t; - if ((t = conn_.transaction_tracer ()) || + if ((t = conn_.main_connection ().transaction_tracer ()) || (t = conn_.tracer ()) || (t = conn_.database ().tracer ())) t->execute (conn_, *this); @@ -619,7 +630,7 @@ namespace odb { odb::tracer* t; - if ((t = conn_.transaction_tracer ()) || + if ((t = conn_.main_connection ().transaction_tracer ()) || (t = conn_.tracer ()) || (t = conn_.database ().tracer ())) t->execute (conn_, *this); @@ -739,7 +750,7 @@ namespace odb { { odb::tracer* t; - if ((t = conn_.transaction_tracer ()) || + if ((t = conn_.main_connection ().transaction_tracer ()) || (t = conn_.tracer ()) || (t = conn_.database ().tracer ())) t->execute (conn_, *this); @@ -846,7 +857,7 @@ namespace odb { { odb::tracer* t; - if ((t = conn_.transaction_tracer ()) || + if ((t = conn_.main_connection ().transaction_tracer ()) || (t = conn_.tracer ()) || (t = conn_.database ().tracer ())) t->execute (conn_, *this); @@ -932,7 +943,7 @@ namespace odb { { odb::tracer* t; - if ((t = conn_.transaction_tracer ()) || + if ((t = conn_.main_connection ().transaction_tracer ()) || (t = conn_.tracer ()) || (t = conn_.database ().tracer ())) t->execute (conn_, *this); diff --git a/odb/sqlite/statement.hxx b/odb/sqlite/statement.hxx index 4be1c5a..9eeea7b 100644 --- a/odb/sqlite/statement.hxx +++ b/odb/sqlite/statement.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/statement.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_STATEMENT_HXX diff --git a/odb/sqlite/statements-base.cxx b/odb/sqlite/statements-base.cxx index d0bd786..bde8c55 100644 --- a/odb/sqlite/statements-base.cxx +++ b/odb/sqlite/statements-base.cxx @@ -1,5 +1,4 @@ // file : odb/sqlite/statements-base.cxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <odb/sqlite/statements-base.hxx> diff --git a/odb/sqlite/statements-base.hxx b/odb/sqlite/statements-base.hxx index 60619df..5851d1b 100644 --- a/odb/sqlite/statements-base.hxx +++ b/odb/sqlite/statements-base.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/statements-base.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_STATEMENTS_BASE_HXX diff --git a/odb/sqlite/stream.cxx b/odb/sqlite/stream.cxx index ff39a88..8420ba2 100644 --- a/odb/sqlite/stream.cxx +++ b/odb/sqlite/stream.cxx @@ -1,5 +1,4 @@ // file : odb/sqlite/stream.cxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <sqlite3.h> diff --git a/odb/sqlite/stream.hxx b/odb/sqlite/stream.hxx index 3569082..6ee76cb 100644 --- a/odb/sqlite/stream.hxx +++ b/odb/sqlite/stream.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/stream.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_STREAM_HXX @@ -24,6 +23,10 @@ namespace odb class LIBODB_SQLITE_EXPORT stream: public active_object { public: + // @@ TODO: db is actually what we now (and SQLite in other places) + // call schema (see database::schema(), ATTACH DATABASE). So we + // should probably rename this at some point for consistency. + // stream (const char* db, const char* table, const char* column, diff --git a/odb/sqlite/text-stream.hxx b/odb/sqlite/text-stream.hxx index 851d82d..7a9b467 100644 --- a/odb/sqlite/text-stream.hxx +++ b/odb/sqlite/text-stream.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/text-stream.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_TEXT_STREAM_HXX diff --git a/odb/sqlite/text.hxx b/odb/sqlite/text.hxx index b95f248..3f681fb 100644 --- a/odb/sqlite/text.hxx +++ b/odb/sqlite/text.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/text.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_TEXT_HXX diff --git a/odb/sqlite/tracer.cxx b/odb/sqlite/tracer.cxx index 4c3def8..49f6b00 100644 --- a/odb/sqlite/tracer.cxx +++ b/odb/sqlite/tracer.cxx @@ -1,5 +1,4 @@ // file : odb/sqlite/tracer.cxx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <odb/sqlite/tracer.hxx> diff --git a/odb/sqlite/tracer.hxx b/odb/sqlite/tracer.hxx index 8f8ac8b..b12573b 100644 --- a/odb/sqlite/tracer.hxx +++ b/odb/sqlite/tracer.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/tracer.hxx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_TRACER_HXX diff --git a/odb/sqlite/traits-calls.hxx b/odb/sqlite/traits-calls.hxx index dbc77a1..9d5b59f 100644 --- a/odb/sqlite/traits-calls.hxx +++ b/odb/sqlite/traits-calls.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/traits-calls.hxx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_TRAITS_CALLS_HXX diff --git a/odb/sqlite/traits.cxx b/odb/sqlite/traits.cxx index 73c5521..a47455d 100644 --- a/odb/sqlite/traits.cxx +++ b/odb/sqlite/traits.cxx @@ -1,5 +1,4 @@ // file : odb/sqlite/traits.cxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <odb/sqlite/traits.hxx> diff --git a/odb/sqlite/traits.hxx b/odb/sqlite/traits.hxx index 0c10e69..a8cf578 100644 --- a/odb/sqlite/traits.hxx +++ b/odb/sqlite/traits.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/traits.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_TRAITS_HXX diff --git a/odb/sqlite/transaction-impl.cxx b/odb/sqlite/transaction-impl.cxx index aabb900..6485f7e 100644 --- a/odb/sqlite/transaction-impl.cxx +++ b/odb/sqlite/transaction-impl.cxx @@ -1,5 +1,4 @@ // file : odb/sqlite/transaction-impl.cxx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <sqlite3.h> @@ -7,7 +6,6 @@ #include <odb/sqlite/database.hxx> #include <odb/sqlite/connection.hxx> #include <odb/sqlite/statement.hxx> -#include <odb/sqlite/statement-cache.hxx> #include <odb/sqlite/transaction-impl.hxx> namespace odb @@ -44,23 +42,23 @@ namespace odb odb::transaction_impl::connection_ = connection_.get (); } - statement_cache& sc (connection_->statement_cache ()); + connection_type& mc (connection_->main_connection ()); switch (lock_) { case deferred: { - sc.begin_statement ().execute (); + mc.begin_statement ().execute (); break; } case immediate: { - sc.begin_immediate_statement ().execute (); + mc.begin_immediate_statement ().execute (); break; } case exclusive: { - sc.begin_exclusive_statement ().execute (); + mc.begin_exclusive_statement ().execute (); break; } } @@ -83,7 +81,7 @@ namespace odb // try { - c_->statement_cache ().rollback_statement ().execute (); + c_->rollback_statement ().execute (); } catch (...) {} } @@ -96,21 +94,22 @@ namespace odb void transaction_impl:: commit () { - // Invalidate query results. - // - connection_->invalidate_results (); + connection_type& mc (connection_->main_connection ()); - // Reset active statements. Active statements will prevent COMMIT - // from completing (write statements) or releasing the locks (read - // statements). Normally, a statement is automatically reset on - // completion, however, if an exception is thrown, that may not - // happen. + // Invalidate query results and reset active statements. + // + // Active statements will prevent COMMIT from completing (write + // statements) or releasing the locks (read statements). Normally, a + // statement is automatically reset on completion, however, if an + // exception is thrown, that may not happen. + // + // Note: must be done via the main connection. // - connection_->clear (); + mc.clear (); { - commit_guard cg (*connection_); - connection_->statement_cache ().commit_statement ().execute (); + commit_guard cg (mc); + mc.commit_statement ().execute (); cg.release (); } @@ -122,23 +121,52 @@ namespace odb void transaction_impl:: rollback () { - // Invalidate query results. - // - connection_->invalidate_results (); + connection_type& mc (connection_->main_connection ()); - // Reset active statements. Active statements will prevent ROLLBACK - // from completing (write statements) or releasing the locks (read - // statements). Normally, a statement is automatically reset on - // completion, however, if an exception is thrown, that may not - // happen. + // Invalidate query results and reset active statements (the same + // reasoning as in commit()). + // + // Note: must be done via the main connection. // - connection_->clear (); + mc.clear (); - connection_->statement_cache ().rollback_statement ().execute (); + mc.rollback_statement ().execute (); // Release the connection. // connection_.reset (); } + + odb::connection& transaction_impl:: + connection (odb::database* pdb) + { + if (pdb == 0) + return *connection_; + + // Pick the corresponding connection for main/attached database. + // + database_type& db (static_cast<database_type&> (*pdb)); + + assert (&db.main_database () == + &static_cast<database_type&> (database_).main_database ()); + + return db.schema ().empty () + ? connection_->main_connection () + : *static_cast<attached_connection_factory&> (*db.factory_).attached_connection_; + } + + // Store transaction tracer in the main connection. + // + void transaction_impl:: + tracer (odb::tracer* t) + { + connection_->main_connection ().transaction_tracer_ = t; + } + + odb::tracer* transaction_impl:: + tracer () const + { + return connection_->main_connection ().transaction_tracer_; + } } } diff --git a/odb/sqlite/transaction-impl.hxx b/odb/sqlite/transaction-impl.hxx index 263fa1a..d1a310b 100644 --- a/odb/sqlite/transaction-impl.hxx +++ b/odb/sqlite/transaction-impl.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/transaction-impl.hxx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_TRANSACTION_IMPL_HXX @@ -46,8 +45,14 @@ namespace odb virtual void rollback (); - connection_type& - connection (); + virtual odb::connection& + connection (odb::database*); + + virtual void + tracer (odb::tracer*); + + virtual odb::tracer* + tracer () const; private: connection_ptr connection_; @@ -56,8 +61,6 @@ namespace odb } } -#include <odb/sqlite/transaction-impl.ixx> - #include <odb/post.hxx> #endif // ODB_SQLITE_TRANSACTION_IMPL_HXX diff --git a/odb/sqlite/transaction-impl.ixx b/odb/sqlite/transaction-impl.ixx deleted file mode 100644 index ae66cfa..0000000 --- a/odb/sqlite/transaction-impl.ixx +++ /dev/null @@ -1,15 +0,0 @@ -// file : odb/sqlite/transaction-impl.ixx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC -// license : GNU GPL v2; see accompanying LICENSE file - -namespace odb -{ - namespace sqlite - { - inline transaction_impl::connection_type& transaction_impl:: - connection () - { - return *connection_; - } - } -} diff --git a/odb/sqlite/transaction.cxx b/odb/sqlite/transaction.cxx index 3e98984..8b4ab23 100644 --- a/odb/sqlite/transaction.cxx +++ b/odb/sqlite/transaction.cxx @@ -1,5 +1,4 @@ // file : odb/sqlite/transaction.cxx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <cassert> diff --git a/odb/sqlite/transaction.hxx b/odb/sqlite/transaction.hxx index b41ed10..5e8c141 100644 --- a/odb/sqlite/transaction.hxx +++ b/odb/sqlite/transaction.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/transaction.hxx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_TRANSACTION_HXX @@ -41,6 +40,9 @@ namespace odb connection_type& connection (); + connection_type& + connection (odb::database&); + // Return current transaction or throw if there is no transaction // in effect. // diff --git a/odb/sqlite/transaction.ixx b/odb/sqlite/transaction.ixx index accf263..de4bd3e 100644 --- a/odb/sqlite/transaction.ixx +++ b/odb/sqlite/transaction.ixx @@ -1,5 +1,4 @@ // file : odb/sqlite/transaction.ixx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <odb/sqlite/database.hxx> @@ -40,7 +39,13 @@ namespace odb inline transaction::connection_type& transaction:: connection () { - return implementation ().connection (); + return static_cast<connection_type&> (odb::transaction::connection ()); + } + + inline transaction::connection_type& transaction:: + connection (odb::database& db) + { + return static_cast<connection_type&> (odb::transaction::connection (db)); } inline void transaction:: diff --git a/odb/sqlite/version-build2-stub.hxx b/odb/sqlite/version-build2-stub.hxx index 697d375..a6bb4d0 100644 --- a/odb/sqlite/version-build2-stub.hxx +++ b/odb/sqlite/version-build2-stub.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/version-build2-stub.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <odb/sqlite/version.hxx> diff --git a/odb/sqlite/version-build2.hxx.in b/odb/sqlite/version-build2.hxx.in index 0e0d238..50fef2d 100644 --- a/odb/sqlite/version-build2.hxx.in +++ b/odb/sqlite/version-build2.hxx.in @@ -1,5 +1,4 @@ // file : odb/sqlite/version-build2.hxx.in -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef LIBODB_SQLITE_VERSION // Note: using the version macro itself. diff --git a/odb/sqlite/version.hxx b/odb/sqlite/version.hxx index 32365f8..ad468de 100644 --- a/odb/sqlite/version.hxx +++ b/odb/sqlite/version.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/version.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifdef LIBODB_SQLITE_BUILD2 @@ -32,15 +31,15 @@ // Check that we have compatible ODB version. // -#if ODB_VERSION != 20466 +#if ODB_VERSION != 20476 # error incompatible odb interface version detected #endif // libodb-sqlite version: odb interface version plus the bugfix // version. // -#define LIBODB_SQLITE_VERSION 2049966 -#define LIBODB_SQLITE_VERSION_STR "2.5.0-b.16" +#define LIBODB_SQLITE_VERSION 2049976 +#define LIBODB_SQLITE_VERSION_STR "2.5.0-b.26" #include <odb/post.hxx> diff --git a/odb/sqlite/view-result.hxx b/odb/sqlite/view-result.hxx index 5b300b8..ce3d747 100644 --- a/odb/sqlite/view-result.hxx +++ b/odb/sqlite/view-result.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/view-result.hxx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_VIEW_RESULT_HXX diff --git a/odb/sqlite/view-result.txx b/odb/sqlite/view-result.txx index 9e5957c..60efb81 100644 --- a/odb/sqlite/view-result.txx +++ b/odb/sqlite/view-result.txx @@ -1,5 +1,4 @@ // file : odb/sqlite/view-result.txx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <odb/callback.hxx> diff --git a/odb/sqlite/view-statements.hxx b/odb/sqlite/view-statements.hxx index 555884a..0bd79ee 100644 --- a/odb/sqlite/view-statements.hxx +++ b/odb/sqlite/view-statements.hxx @@ -1,5 +1,4 @@ // file : odb/sqlite/view-statements.hxx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_SQLITE_VIEW_STATEMENTS_HXX diff --git a/odb/sqlite/view-statements.txx b/odb/sqlite/view-statements.txx index 0f06f1c..0531a92 100644 --- a/odb/sqlite/view-statements.txx +++ b/odb/sqlite/view-statements.txx @@ -1,5 +1,4 @@ // file : odb/sqlite/view-statements.txx -// copyright : Copyright (c) 2005-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #include <cstddef> // std::size_t diff --git a/repositories.manifest b/repositories.manifest index b45f391..fe2f8c0 100644 --- a/repositories.manifest +++ b/repositories.manifest @@ -8,3 +8,7 @@ location: https://git.build2.org/packaging/sqlite/sqlite.git##HEAD : role: prerequisite location: ../libodb.git##HEAD + +: +role: prerequisite +location: https://git.codesynthesis.com/cli/cli.git##HEAD diff --git a/tests/basics/buildfile b/tests/basics/buildfile index 9759243..5d671d3 100644 --- a/tests/basics/buildfile +++ b/tests/basics/buildfile @@ -1,5 +1,4 @@ # file : tests/basics/buildfile -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file import libs = libodb-sqlite%lib{odb-sqlite} diff --git a/tests/basics/driver.cxx b/tests/basics/driver.cxx index 053d76b..b998574 100644 --- a/tests/basics/driver.cxx +++ b/tests/basics/driver.cxx @@ -1,5 +1,4 @@ // file : tests/basics/driver.cxx -// copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file // Basic test to make sure the library is usable. Functionality testing diff --git a/tests/build/bootstrap.build b/tests/build/bootstrap.build index c5c067b..6ee38db 100644 --- a/tests/build/bootstrap.build +++ b/tests/build/bootstrap.build @@ -1,5 +1,4 @@ # file : tests/build/bootstrap.build -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file project = # Unnamed subproject. diff --git a/tests/build/root.build b/tests/build/root.build index da6ff40..6c5a90b 100644 --- a/tests/build/root.build +++ b/tests/build/root.build @@ -1,5 +1,4 @@ # file : tests/build/root.build -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file cxx.std = latest diff --git a/tests/buildfile b/tests/buildfile index 3614001..57588a4 100644 --- a/tests/buildfile +++ b/tests/buildfile @@ -1,5 +1,4 @@ # file : tests/buildfile -# copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file ./: {*/ -build/} diff --git a/version b/version deleted file mode 100644 index dfe1a80..0000000 --- a/version +++ /dev/null @@ -1 +0,0 @@ -2.5.0-b.16 diff --git a/version.txt b/version.txt new file mode 100644 index 0000000..6bc2f39 --- /dev/null +++ b/version.txt @@ -0,0 +1 @@ +2.5.0-b.26 |