├── .gitignore ├── LICENSE.txt ├── README.md ├── ado ├── Makefile.in ├── README.md ├── aclocal.m4 ├── config.gpr ├── config.guess ├── config.sub ├── config │ ├── mysql-create-table.sql │ ├── postgresql-create-table.sql │ └── sqlite-create-table.sql ├── configure ├── configure.ac ├── install-sh ├── sqlbench.gpr.in ├── sqlbench.properties └── src │ ├── sqlbench-main.adb │ ├── sqlbench-simple.adb │ ├── sqlbench-simple.ads │ ├── sqlbench.adb │ └── sqlbench.ads ├── java ├── README.md ├── config ├── pom.xml ├── sql-benchmark.iml ├── sqlbench.properties └── src │ ├── main │ └── java │ │ └── org │ │ └── ciceron │ │ └── sqlbenchmark │ │ ├── Benchmark.java │ │ ├── Main.java │ │ └── Simple.java │ └── test │ └── java │ └── org │ └── ciceron │ └── sqlbenchmark │ └── AppTest.java ├── plot-memory.gpi ├── plot-mysql.gpi ├── plot-postgresql.gpi ├── plot-sqlite.gpi ├── plot-user-time.gpi ├── python ├── README.md ├── config ├── sqlbench.properties └── src │ ├── __init__.py │ ├── __main__.py │ ├── benchmark.py │ ├── mysql_benchmark.py │ ├── mysql_simple.py │ ├── postgresql_benchmark.py │ ├── postgresql_simple.py │ ├── sqlite_benchmark.py │ └── sqlite_simple.py ├── run-all.sh ├── sql-benchmark-results.xls └── tools ├── Makefile.in ├── aclocal.m4 ├── config.gpr ├── config.guess ├── config.sub ├── configure ├── configure.ac ├── install-sh ├── src ├── excel_writer │ ├── excel_out.adb │ ├── excel_out.ads │ ├── ieee_754-generic_double_precision.adb │ ├── ieee_754-generic_double_precision.ads │ └── ieee_754.ads ├── tool-data.adb ├── tool-data.ads ├── tool-main.adb └── tool.ads ├── tool.gpr.in └── tool.properties /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | *.xml 3 | *~ 4 | */sqlbench.db* 5 | java/.idea 6 | java/target 7 | ado/bin 8 | ado/obj 9 | ado/autom4te.cache 10 | ado/config.status 11 | ado/Makefile 12 | ado/sqlbench.gpr 13 | tools/tool.gpr 14 | tools/bin 15 | tools/obj 16 | tools/Makefile 17 | tools/config.status 18 | tools/autom4te.cache 19 | python/src/__pycache__ 20 | 21 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | The *sql-benchmark* provides simple benchmark of several database drivers in several languages. 4 | Benchmarks are intended to be simple so that they can be implemented easily for several 5 | languages and SQL databases. Some of the goals are: 6 | 7 | * Evaluate the performance of a database driver, 8 | * Compare the performance of different languages when connecting to a database, 9 | * Have a rough comparison on simple SQL queries on different databases. 10 | 11 | # Languages 12 | 13 | * [Java Benchmark](https://github.com/stcarrez/sql-benchmark/tree/master/java) 14 | * [Ada Benchmark](https://github.com/stcarrez/sql-benchmark/tree/master/ado) 15 | * [Python Benchmark](https://github.com/stcarrez/sql-benchmark/tree/master/python) 16 | 17 | # Databases 18 | 19 | Three SQL databases are supported: 20 | 21 | * SQLite, 22 | * MySQL/MariaDB, 23 | * PostgreSQL 24 | 25 | Before running the SQL benchmark of MySQL/MariaDB and PostgreSQL, you must create the 26 | `sqlbench` database and give access to the `sqlbench` user. 27 | 28 | The SQLite database is created automatically. 29 | 30 | ## MySQL/MariaDB setup 31 | 32 | 1. Create the 'sqlbench' database in MySQL/MariaDB 33 | 34 | ``` 35 | mysql -u root 36 | mysql> create database sqlbench; 37 | ``` 38 | 39 | 2. Create the 'sqlbench' user: 40 | ``` 41 | mysql> create user 'sqlbench'@'localhost' identified by 'sqlbench'; 42 | ``` 43 | 44 | 3. Give the access rights: 45 | ``` 46 | mysql> grant select, insert, update, delete, 47 | create, drop, create temporary tables, execute, 48 | show view on sqlbench.* to sqlbench@'localhost'; 49 | mysql> flush privileges; 50 | ``` 51 | 52 | ## Postgresql setup 53 | 54 | To create manually the database, you can proceed to the following steps: 55 | 56 | 1. Create the 'sqlbench' user and configure the password 57 | (enter 'sqlbench' for the password or update the configuration sqlbench.properties file): 58 | 59 | ``` 60 | sudo -u postgres createuser sqlbench --pwprompt 61 | ``` 62 | 63 | 2. Create the 'sqlbench' database in Postgresql 64 | 65 | ``` 66 | sudo -u postgres createdb -O sqlbench sqlbench 67 | ``` 68 | 69 | # Running 70 | 71 | The script `run-all.sh` can be used to run all the benchmark and produce the results. 72 | Before running it, make sure you have built the Ada and Java benchmark programs as 73 | well as the Ada aggregator tool. To build, run the following commands. 74 | 75 | ``` 76 | cd ado 77 | ./configure 78 | make 79 | cd ../java 80 | mvn compile assembly:single 81 | cd ../tools 82 | ./configure 83 | make 84 | cd .. 85 | ``` 86 | 87 | Then, simply run the script: 88 | 89 | ``` 90 | ./run-all.sh 91 | ``` 92 | 93 | # Results 94 | 95 | ![Time](https://github.com/stcarrez/sql-benchmark/wiki/images/time.png) 96 | ![Memory](https://github.com/stcarrez/sql-benchmark/wiki/images/memory.png) 97 | ![SQLite](https://github.com/stcarrez/sql-benchmark/wiki/images/sqlite.png) 98 | ![MySQL](https://github.com/stcarrez/sql-benchmark/wiki/images/mysql.png) 99 | ![PostgreSQL](https://github.com/stcarrez/sql-benchmark/wiki/images/postgresql.png) 100 | 101 | 102 | ## CONNECT; SELECT 1; CLOSE 103 | 104 | | | sqlite | mysql | postgresql | 105 | |-----------------------|---------------|---------------|---------------| 106 | | Ada | 23.68 us | 311.0 us | 5.541 ms | 107 | | Java | 187.7 us | 895.8 us | 10.80 ms | 108 | | Python | 42.00 us | 398.5 us | 6.071 ms | 109 | 110 | ## DO 1 111 | 112 | | | sqlite | mysql | postgresql | 113 | |-----------------------|---------------|---------------|---------------| 114 | | Ada | | 19.04 us | | 115 | | Java | | 53.72 us | | 116 | | Python | | 33.03 us | | 117 | 118 | ## DROP table; CREATE table 119 | 120 | | | sqlite | mysql | postgresql | 121 | |-----------------------|---------------|---------------|---------------| 122 | | Ada | 216.9 us | 496.2 ms | 42.64 ms | 123 | | Java | 1.698 ms | 504.9 ms | 45.03 ms | 124 | | Python | 122.5 ms | 498.6 ms | 41.24 ms | 125 | 126 | ## INSERT INTO table 127 | 128 | | | sqlite | mysql | postgresql | 129 | |-----------------------|---------------|---------------|---------------| 130 | | Ada | 73.59 us | 118.5 us | 160.6 us | 131 | | Java | 96.20 us | 241.4 us | 119.3 us | 132 | | Python | 3.684 us | 290.7 us | 119.1 us | 133 | 134 | ## SELECT * FROM table LIMIT 1 135 | 136 | | | sqlite | mysql | postgresql | 137 | |-----------------------|---------------|---------------|---------------| 138 | | Ada | 25.63 us | 75.60 us | 105.5 us | 139 | | Java | 5.096 us | 97.38 us | 105.6 us | 140 | | Python | 3.457 us | 47.31 us | 148.7 us | 141 | 142 | ## SELECT * FROM table LIMIT 10 143 | 144 | | | sqlite | mysql | postgresql | 145 | |-----------------------|---------------|---------------|---------------| 146 | | Ada | 27.60 us | 61.30 us | 99.43 us | 147 | | Java | 5.115 us | 101.7 us | 92.56 us | 148 | | Python | 8.766 us | 51.76 us | 128.0 us | 149 | 150 | ## SELECT * FROM table LIMIT 100 151 | 152 | | | sqlite | mysql | postgresql | 153 | |-----------------------|---------------|---------------|---------------| 154 | | Ada | 37.41 us | 131.1 us | 161.6 us | 155 | | Java | 15.53 us | 174.5 us | 223.8 us | 156 | | Python | 60.43 us | 102.0 us | 236.6 us | 157 | 158 | ## SELECT * FROM table LIMIT 500 159 | 160 | | | sqlite | mysql | postgresql | 161 | |-----------------------|---------------|---------------|---------------| 162 | | Ada | 78.14 us | 328.6 us | 305.7 us | 163 | | Java | 62.12 us | 462.2 us | 616.2 us | 164 | | Python | 297.8 us | 300.2 us | 462.2 us | 165 | 166 | ## SELECT * FROM table LIMIT 1000 167 | 168 | | | sqlite | mysql | postgresql | 169 | |-----------------------|---------------|---------------|---------------| 170 | | Ada | 132.0 us | 544.9 us | 456.6 us | 171 | | Java | 121.8 us | 728.2 us | 871.6 us | 172 | | Python | 605.6 us | 551.6 us | 730.3 us | 173 | 174 | ## SELECT 1 175 | 176 | | | sqlite | mysql | postgresql | 177 | |-----------------------|---------------|---------------|---------------| 178 | | Ada | 9.501 us | 35.60 us | 87.55 us | 179 | | Java | 5.629 us | 70.61 us | 104.4 us | 180 | | Python | 1.530 us | 78.13 us | 89.66 us | 181 | -------------------------------------------------------------------------------- /ado/Makefile.in: -------------------------------------------------------------------------------- 1 | NAME=sqlbench 2 | 3 | # You may edit this makefile as long as you keep these original 4 | # target names defined. 5 | MODE=debug 6 | GNATMAKE=@GNATMAKE@ 7 | GNATCLEAN=gnatclean 8 | SVN=svn 9 | INSTALL=@INSTALL@ 10 | DYNAMO=dynamo 11 | LN_S=@LN_S@ 12 | MKDIR=mkdir 13 | CP=cp 14 | LN=ln -s 15 | 16 | GPRPATH:=${NAME}.gpr 17 | 18 | 19 | 20 | distdir=sqlbench-@SQLBENCH_VERSION@ 21 | 22 | DIST_FILE=sqlbench-@SQLBENCH_VERSION@.tar.gz 23 | 24 | HAVE_MYSQL=@ADO_DB_MYSQL@ 25 | HAVE_SQLITE=@ADO_DB_SQLITE@ 26 | 27 | srcdir = . 28 | bindir = @bindir@ 29 | sbindir = @sbindir@ 30 | top_srcdir = @top_srcdir@ 31 | VPATH = @srcdir@ 32 | prefix = @prefix@ 33 | exec_prefix = @exec_prefix@ 34 | top_builddir = . 35 | dynamodir=${prefix}/share/dynamo 36 | includedir=${prefix}/share/ada/adainclude 37 | projectdir=${prefix}/share/ada/adainclude 38 | bindir=${prefix}/bin 39 | libdir=${prefix}/lib 40 | alidir=${libdir}/ada/adalib/ 41 | 42 | MAKE_ARGS=-XMODE=${MODE} 43 | 44 | all: build 45 | 46 | # Build executables for all mains defined by the project. 47 | build: 48 | test ! -f $(GPRPATH) || $(GNATMAKE) -m -p -P "$(GPRPATH)" $(MAKE_ARGS) 49 | 50 | # Not intended for manual invocation. 51 | # Invoked if automatic builds are enabled. 52 | # Analyzes only on those sources that have changed. 53 | # Does not build executables. 54 | autobuild: 55 | $(GNATMAKE) -gnatc -c -k -P "$(GPRPATH)" 56 | 57 | # Clean the root project of all build products. 58 | clean: 59 | -$(GNATCLEAN) -q -P "$(GPRPATH)" 60 | -rm -rf $(distdir) 61 | 62 | # Clean root project and all imported projects too. 63 | clean_tree: 64 | $(GNATCLEAN) -P "$(GPRPATH)" -r 65 | 66 | # Check *all* sources for errors, even those not changed. 67 | # Does not build executables. 68 | analyze: 69 | $(GNATMAKE) -f -gnatc -c -k -P "$(GPRPATH)" 70 | 71 | # Clean, then build executables for all mains defined by the project. 72 | rebuild: clean build 73 | 74 | # Rebuild the generated model files 75 | generate: 76 | $(DYNAMO) generate db 77 | 78 | install: uninstall 79 | $(INSTALL) bin/${NAME} $(prefix)/bin/${NAME} 80 | 81 | uninstall: 82 | rm -f ${bindir}/${NAME} 83 | -------------------------------------------------------------------------------- /ado/README.md: -------------------------------------------------------------------------------- 1 | ## Build 2 | 3 | To build the Ada program benchmark, you will need the following Ada projects: 4 | 5 | * ADO (https://github.com/stcarrez/ada-ado) 6 | * Ada Util (https://github.com/stcarrez/ada-util) 7 | 8 | Compile and install them before running the following commands: 9 | 10 | ``` 11 | ./configure 12 | make 13 | ``` 14 | 15 | ## Run 16 | 17 | MySQL 18 | ``` 19 | bin/sqlbench -mysql -repeat 100 20 | ``` 21 | 22 | PostgreSQL 23 | ``` 24 | bin/sqlbench -postgresql -repeat 100 25 | ``` 26 | 27 | SQLite 28 | ``` 29 | bin/sqlbench -sqlite -repeat 100 30 | ``` 31 | -------------------------------------------------------------------------------- /ado/aclocal.m4: -------------------------------------------------------------------------------- 1 | # Check whether we can use gprbuild or gnatmake 2 | AC_DEFUN(AM_GNAT_CHECK_GPRBUILD, 3 | [ 4 | AC_CHECK_PROGS(GPRBUILD, gprbuild, "") 5 | if test -n "$GPRBUILD"; then 6 | GNATMAKE="$GPRBUILD" 7 | else 8 | AC_CHECK_PROGS(GNATMAKE, gnatmake, "") 9 | fi 10 | 11 | AC_CHECK_PROGS(GPRCLEAN, gprclean, "") 12 | if test -n "$GPRCLEAN"; then 13 | GNATCLEAN="$GPRCLEAN" 14 | else 15 | AC_CHECK_PROGS(GNATCLEAN, gnatclean, "") 16 | fi 17 | ]) 18 | 19 | # Check if a GNAT project is available. 20 | # dnl AM_GNAT_CHECK_PROJECT([name],[path]) 21 | AC_DEFUN(AM_GNAT_CHECK_PROJECT, 22 | [ 23 | AC_MSG_CHECKING([whether $1 project exists]) 24 | echo "with \"$2\"; project conftest is for Source_Dirs use (); end conftest;" > conftest.gpr 25 | if AC_TRY_COMMAND([gnat ls -Pconftest.gpr system.ads > /dev/null 2>conftest.out]) 26 | then 27 | gnat_project_$1=yes 28 | AC_MSG_RESULT([yes, using $2]) 29 | gnat_project_with_$1="with \"$2\";"; 30 | else 31 | gnat_project_$1=no 32 | AC_MSG_RESULT(no) 33 | fi 34 | rm -f conftest.gpr 35 | ]) 36 | 37 | # Check if a GNAT project is available. 38 | # AM_GNAT_FIND_PROJECT([ada-util],[Ada Utility Library],[util],[link],[code-fail],[code-ok]) 39 | AC_DEFUN(AM_GNAT_FIND_PROJECT, 40 | [ 41 | AC_MSG_CHECKING([$2]) 42 | AC_ARG_WITH($1, 43 | AS_HELP_STRING([--with-$1=x], [Path for $2]), 44 | [ 45 | gnat_project_name_$3=${withval}/ 46 | if test -d "${withval}"; then 47 | gnat_project_name_$3=${withval}/$3 48 | fi 49 | ], 50 | [ 51 | gnat_project_name_$3=$3 52 | ]) 53 | AC_MSG_RESULT(trying ${gnat_project_name_$3}) 54 | 55 | rm -f conftest.gpr 56 | # Search in the GNAT project path. 57 | AC_MSG_CHECKING([whether ${gnat_project_name_$3} project exists in gnatmake's search path]) 58 | echo "with \"${gnat_project_name_$3}\"; project conftest is for Source_Dirs use (); end conftest;" > conftest.gpr 59 | if AC_TRY_COMMAND([gnat ls -Pconftest.gpr system.ads > /dev/null 2>conftest.out]) 60 | then 61 | gnat_project_$3=yes 62 | AC_MSG_RESULT(yes, using ${gnat_project_name_$3}) 63 | else 64 | gnat_project_$3=no 65 | AC_MSG_RESULT(no) 66 | 67 | # Search in ../$1-*/$3.gpr 68 | files=`ls -r ../$1/$3.gpr ../$3/$3.gpr ../$1-*/$3.gpr 2>/dev/null` 69 | for name in $files; do 70 | dir=`dirname $name` 71 | AC_MSG_CHECKING([for $2 project in ${dir}]) 72 | echo "with \"${name}\"; project conftest is for Source_Dirs use (); end conftest;" > conftest.gpr 73 | if AC_TRY_COMMAND([gnat ls -Pconftest.gpr system.ads > /dev/null 2>conftest.out]) 74 | then 75 | gnat_project_$3=yes 76 | gnat_project_name_$3=${name} 77 | AC_MSG_RESULT(yes, using ${name}) 78 | break 79 | else 80 | gnat_project_$3=no 81 | AC_MSG_RESULT(no) 82 | fi 83 | done 84 | fi 85 | rm -f conftest.gpr 86 | if test x${gnat_project_$3} = xyes; then 87 | gnat_project_with_$3="with \"${gnat_project_name_$3}\";"; 88 | gnat_project_dir_$3=`dirname ${gnat_project_name_$3}` 89 | if test ${gnat_project_dir_$3} = . ; then 90 | gnat_project_dir_$3= 91 | else 92 | gnat_project_dir_$3="${gnat_project_dir_$3}/" 93 | fi 94 | $6 95 | else 96 | gnat_project_dir_$3= 97 | gnat_project_name_$3= 98 | if test x"$5" != x; then 99 | AC_MSG_ERROR([$5 100 | You should build and install the $2 component. 101 | It must be available and found by ${GNATMAKE}. 102 | This project was not found in the ADA_PROJECT_PATH environment variable. 103 | This project was not found in ../$3 nor in ../$1-*. 104 | The component is available at $4. 105 | Please, download and configure $2. 106 | The current configuration was using: 107 | ${GNATMAKE} 108 | ADA_PROJECT_PATH=$ADA_PROJECT_PATH 109 | ]) 110 | fi 111 | fi 112 | ]) 113 | 114 | dnl Check whether the shared library support is enabled. 115 | AC_DEFUN(AM_SHARED_LIBRARY_SUPPORT, 116 | [ 117 | AC_MSG_CHECKING([shared library support]) 118 | ac_enable_shared=no 119 | AC_ARG_ENABLE(shared, 120 | [ --enable-shared Enable the shared libraries (disabled)], 121 | [case "${enableval}" in 122 | no|none) ac_enable_shared=no ;; 123 | *) ac_enable_shared=yes ;; 124 | esac])dnl 125 | 126 | AC_MSG_RESULT(${ac_enable_shared}) 127 | BUILDS_SHARED=$ac_enable_shared 128 | AC_SUBST(BUILDS_SHARED) 129 | ]) 130 | 131 | dnl Check whether the coverage support is enabled. 132 | AC_DEFUN(AM_COVERAGE_SUPPORT, 133 | [ 134 | AC_MSG_CHECKING([coverage support]) 135 | ac_enable_coverage=no 136 | AC_ARG_ENABLE(coverage, 137 | [ --enable-coverage build with coverage support -fprofile-arcs -ftest-coverage (disabled)], 138 | [case "${enableval}" in 139 | no|none) ac_enable_coverage=no ;; 140 | *) ac_enable_coverage=yes ;; 141 | esac])dnl 142 | 143 | AC_MSG_RESULT(${ac_enable_coverage}) 144 | BUILDS_COVERAGE=$ac_enable_coverage 145 | AC_SUBST(BUILDS_COVERAGE) 146 | ]) 147 | 148 | dnl Check whether the distrib/debug build is enabled. 149 | AC_DEFUN(AM_DISTRIB_SUPPORT, 150 | [ 151 | AC_MSG_CHECKING([distribution build]) 152 | ac_enable_distrib=yes 153 | ac_build_mode=distrib 154 | AC_ARG_ENABLE(distrib, 155 | [ --enable-distrib build for distribution, optimized and strip symbols (enabled)], 156 | [case "${enableval}" in 157 | no|none) ac_enable_distrib=no 158 | ac_build_mode=debug 159 | ;; 160 | *) ac_enable_distrib=yes 161 | ac_build_mode=distrib 162 | ;; 163 | esac])dnl 164 | 165 | AC_MSG_RESULT(${ac_enable_distrib}) 166 | BUILDS_DISTRIB=$ac_enable_distrib 167 | AC_SUBST(BUILDS_DISTRIB) 168 | 169 | MODE=$ac_build_mode 170 | AC_SUBST(MODE) 171 | ]) 172 | 173 | dnl Check whether the AWS support is enabled and find the aws GNAT project. 174 | AC_DEFUN(AM_GNAT_CHECK_AWS, 175 | [ 176 | dnl Define option to enable/disable AWS 177 | gnat_enable_aws=yes 178 | gnat_project_aws=no 179 | gnat_project_name_aws= 180 | AC_ARG_ENABLE(aws, 181 | [ --enable-aws Enable the AWS support (enabled)], 182 | [case "${enableval}" in 183 | no|none) gnat_enable_aws=no ;; 184 | *) gnat_enable_aws=yes ;; 185 | esac])dnl 186 | 187 | AC_MSG_CHECKING([AWS support is enabled]) 188 | AC_MSG_RESULT(${gnat_enable_aws}) 189 | 190 | if test T$gnat_enable_aws = Tyes; then 191 | dnl AC_MSG_NOTICE([Ada Web Server library (http://libre.adacore.com/libre/tools/aws/)]) 192 | AC_ARG_WITH(aws, 193 | AS_HELP_STRING([--with-aws=x], [Path for the Ada Web Server library (http://libre.adacore.com/libre/tools/aws/)]), 194 | [ 195 | gnat_project_name=${withval} 196 | ], 197 | [ 198 | gnat_project_name=aws 199 | ]) 200 | AM_GNAT_CHECK_PROJECT([aws],[${gnat_project_name}]) 201 | if test x$gnat_project_aws = xno; then 202 | gnat_enable_aws=no 203 | else 204 | gnat_project_aws=aws 205 | fi 206 | fi 207 | if test T$gnat_enable_aws = Tno; then 208 | $1 209 | else 210 | $2 211 | fi 212 | ]) 213 | 214 | dnl Setup installation paths 215 | dnl AM_UTIL_INSTALL([inc],[ali],[lib],[prj]) 216 | AC_DEFUN(AM_UTIL_INSTALL, 217 | [ 218 | gnat_prefix= 219 | for dir in $1 $2 $3 $4; do 220 | dir=`echo $dir | sed -e 's,\\\\,/,g'` 221 | # If we have a valid path, try to identify the common path prefix. 222 | if test x$gnat_prefix = x; then 223 | gnat_prefix=$dir 224 | else 225 | # echo "Dir=$dir" 226 | gnat_old_ifs=$IFS 227 | path= 228 | IFS='/\' 229 | for c in $dir; do 230 | if test x"$path" = x"/" || test x"$path" = x ; then 231 | case $c in 232 | c:|C:|d:|D:|e:|E:) 233 | try="$c" 234 | ;; 235 | *) 236 | try="/$c" 237 | ;; 238 | esac 239 | else 240 | try="$path/$c" 241 | fi 242 | # echo "gnat_prefix=$gnat_prefix try=$try path=$path c=$c" 243 | case $gnat_prefix in 244 | $try*) 245 | ;; 246 | *) 247 | break 248 | ;; 249 | esac 250 | path=$try 251 | done 252 | IFS=$gnat_old_ifs 253 | gnat_prefix=$path 254 | fi 255 | done 256 | ADA_INC_BASE=`echo $1 | sed -e 's,\\\\,/,g' | sed -e s,^$gnat_prefix/,,` 257 | ADA_ALI_BASE=`echo $2 | sed -e 's,\\\\,/,g' | sed -e s,^$gnat_prefix/,,` 258 | ADA_LIB_BASE=`echo $3 | sed -e 's,\\\\,/,g' | sed -e s,^$gnat_prefix/,,` 259 | ADA_PRJ_BASE=`echo $4 | sed -e 's,\\\\,/,g' | sed -e s,^$gnat_prefix/,,` 260 | 261 | AC_MSG_CHECKING([installation of Ada source files]) 262 | AC_MSG_RESULT(/${ADA_INC_BASE}) 263 | 264 | AC_MSG_CHECKING([installation of Ada ALI files]) 265 | AC_MSG_RESULT(/${ADA_ALI_BASE}) 266 | 267 | AC_MSG_CHECKING([installation of library files]) 268 | AC_MSG_RESULT(/${ADA_LIB_BASE}) 269 | 270 | AC_MSG_CHECKING([installation of GNAT project files]) 271 | AC_MSG_RESULT(/${ADA_PRJ_BASE}) 272 | 273 | AC_SUBST(ADA_INC_BASE) 274 | AC_SUBST(ADA_LIB_BASE) 275 | AC_SUBST(ADA_ALI_BASE) 276 | AC_SUBST(ADA_PRJ_BASE) 277 | ]) 278 | 279 | 280 | dnl Check by using xmlada-config where some files are installed. 281 | dnl The goad is to find or guess some installation paths. 282 | dnl XML/Ada Debian 283 | dnl *.ads /include/xmlada /usr/share/adainclude/xmlada 284 | dnl *.ali /lib/xmlada/static /usr/lib//ada/adalib/xmlada 285 | dnl *.so /lib/xmlada/static /usr/lib/ 286 | dnl *.prj /lib/gnat /usr/share/adainclude 287 | 288 | AC_DEFUN(AM_GNAT_CHECK_INSTALL, 289 | [ 290 | # 291 | gnat_prefix= 292 | gnat_xml_inc_dir= 293 | gnat_xml_ali_dir= 294 | gnat_xml_lib_dir= 295 | gnat_xml_prl_dir= 296 | 297 | AC_CHECK_PROGS(GPRINSTALL, gprinstall, "") 298 | if test x${gnat_xml_ada} = 'x'; then 299 | gnat_xml_ada=xmlada-config 300 | fi 301 | gnat_xml_config=`$gnat_xml_ada --sax 2>/dev/null` 302 | 303 | # echo "Config: $gnat_xml_config" 304 | for i in $gnat_xml_config; do 305 | # echo " Checking $i" 306 | case $i in 307 | -aI*) 308 | name=`echo $i | sed -e 's,-aI,,'` 309 | dir=`dirname $name` 310 | name=`basename $name` 311 | if test x$name = "xxmlada"; then 312 | gnat_xml_inc_dir=$dir 313 | else 314 | dir='' 315 | fi 316 | ;; 317 | 318 | -aO*) 319 | name=`echo $i | sed -e 's,-aO,,'` 320 | dir=`dirname $name` 321 | name=`basename $name` 322 | case $name in 323 | xmlada) 324 | gnat_xml_ali_dir=$dir 325 | ;; 326 | 327 | static|relocatable) 328 | name=`basename $dir` 329 | dir=`dirname $dir` 330 | if test x$name = "xxmlada"; then 331 | gnat_xml_ali_dir=$dir 332 | else 333 | dir='' 334 | fi 335 | ;; 336 | 337 | *) 338 | dir='' 339 | ;; 340 | 341 | esac 342 | ;; 343 | 344 | -largs) 345 | dir='' 346 | ;; 347 | 348 | -L*) 349 | dir=`echo $i | sed -e 's,-L,,'` 350 | gnat_xml_lib_dir=$dir 351 | ;; 352 | 353 | /*.a) 354 | dir=`dirname $i` 355 | name=`basename $dir` 356 | case $name in 357 | xmlada) 358 | dir=`dirname $dir` 359 | gnat_xml_lib_dir=$dir 360 | ;; 361 | 362 | static|relocatable) 363 | dir=`dirname $dir` 364 | name=`basename $dir` 365 | if test x$name = "xxmlada"; then 366 | dir=`dirname $dir` 367 | gnat_xml_lib_dir=$dir 368 | else 369 | dir='' 370 | fi 371 | ;; 372 | 373 | *) 374 | dir='' 375 | ;; 376 | 377 | esac 378 | ;; 379 | 380 | *) 381 | dir= 382 | ;; 383 | esac 384 | 385 | # If we have a valid path, try to identify the common path prefix. 386 | if test x$dir != "x"; then 387 | if test x$gnat_prefix = x; then 388 | gnat_prefix=$dir 389 | else 390 | # echo "Dir=$dir" 391 | gnat_old_ifs=$IFS 392 | path= 393 | IFS=/ 394 | for c in $dir; do 395 | if test x"$path" = x"/"; then 396 | try="/$c" 397 | else 398 | try="$path/$c" 399 | fi 400 | # echo "gnat_prefix=$gnat_prefix try=$try path=$path c=$c" 401 | case $gnat_prefix in 402 | $try*) 403 | ;; 404 | *) 405 | break 406 | ;; 407 | esac 408 | path=$try 409 | done 410 | IFS=$gnat_old_ifs 411 | gnat_prefix=$path 412 | fi 413 | fi 414 | done 415 | 416 | if test -f $gnat_prefix/lib/gnat/xmlada.gpr ; then 417 | gnat_xml_prj_dir=$gnat_prefix/lib/gnat 418 | elif test -f $gnat_xml_inc_dir/xmlada.gpr ; then 419 | gnat_xml_prj_dir=$gnat_xml_inc_dir 420 | elif test -f $gnat_prefix/share/gpr/xmlada.gpr ; then 421 | gnat_xml_prj_dir=$gnat_prefix/share/gpr 422 | else 423 | gnat_xml_prj_dir=$gnat_xml_inc_dir 424 | fi 425 | if test x${gnat_xml_inc_dir} = x ; then 426 | gnat_xml_inc_dir='include' 427 | fi 428 | if test x${gnat_xml_lib_dir} = x ; then 429 | gnat_xml_lib_dir='lib' 430 | fi 431 | if test x${gnat_xml_ali_dir} = x ; then 432 | gnat_xml_ali_dir='lib' 433 | fi 434 | if test x${gnat_xml_prj_dir} = x ; then 435 | gnat_xml_prj_dir='lib/gnat' 436 | fi 437 | ADA_INC_BASE=`echo $gnat_xml_inc_dir | sed -e s,^$gnat_prefix/,,` 438 | ADA_LIB_BASE=`echo $gnat_xml_lib_dir | sed -e s,^$gnat_prefix/,,` 439 | ADA_ALI_BASE=`echo $gnat_xml_ali_dir | sed -e s,^$gnat_prefix/,,` 440 | ADA_PRJ_BASE=`echo $gnat_xml_prj_dir | sed -e s,^$gnat_prefix/,,` 441 | AM_UTIL_INSTALL([${gnat_xml_inc_dir}],[${gnat_xml_ali_dir}],[${gnat_xml_lib_dir}],[${gnat_xml_prj_dir}]) 442 | ]) 443 | 444 | dnl Guess the installation path 445 | AC_DEFUN(AM_UTIL_CHECK_INSTALL, 446 | [ 447 | AC_CHECK_PROGS(GPRINSTALL, gprinstall, "") 448 | AM_GNAT_CHECK_PROJECT([util_config],[util_config]) 449 | 450 | # Search in the GNAT project path. 451 | AC_MSG_CHECKING([for util_config.gpr installation]) 452 | # echo "D:${gnat_project_with_util_config}" 453 | echo "${gnat_project_with_util_config} project t is for Source_Dirs use (); end t;" > t.gpr 454 | # cat t.gpr 455 | gnat_util_config_path=`$GNATMAKE -vP1 -Pt 2>&1 | awk '/Parsing.*util_config.gpr/ {print @S|@2}' | sed -e 's,",,g'` 456 | AC_MSG_RESULT(${gnat_util_config_path}) 457 | 458 | gnat_inc_dir= 459 | gnat_ali_dir= 460 | gnat_prj_dir= 461 | gnat_lib_dir= 462 | if test x${gnat_util_config_path} != x; then 463 | if test -f ${gnat_util_config_path}; then 464 | gnat_inc_dir=`awk '/Includedir/ {print @S|@3}' ${gnat_util_config_path} | sed -e 's,",,g' -e 's,;,,'` 465 | gnat_lib_dir=`awk '/Libdir/ {print @S|@3}' ${gnat_util_config_path} | sed -e 's,",,g' -e 's,;,,'` 466 | gnat_ali_dir=`awk '/Alidir/ {print @S|@3}' ${gnat_util_config_path} | sed -e 's,",,g' -e 's,;,,'` 467 | gnat_prj_dir=`dirname ${gnat_util_config_path}` 468 | fi 469 | fi 470 | if test x${gnat_prj_dir} != x; then 471 | AM_UTIL_INSTALL([${gnat_inc_dir}],[${gnat_ali_dir}],[${gnat_lib_dir}],[${gnat_prj_dir}]) 472 | else 473 | AM_GNAT_CHECK_INSTALL 474 | fi 475 | ]) 476 | 477 | # AM_TRY_ADA and AM_HAS_INTRINSIC_SYNC_COUNTERS are imported from GNATcoll aclocal.m4 478 | ############################################################# 479 | # Check whether gnatmake can compile, bind and link an Ada program 480 | # AM_TRY_ADA(gnatmake,filename,content,success,failure) 481 | ############################################################# 482 | 483 | AC_DEFUN(AM_TRY_ADA, 484 | [ 485 | cat > conftest.ada </dev/null 2>conftest.out]) 489 | then 490 | : Success 491 | $4 492 | else 493 | : Failure 494 | $5 495 | fi 496 | rm -rf conftest.ada 497 | ]) 498 | 499 | ############################################################# 500 | # Check whether platform/GNAT supports atomic increment/decrement 501 | # operations. 502 | # The following variable is then set: 503 | # SYNC_COUNTERS_IMPL 504 | # to either "intrinsic" or "mutex" 505 | # Code comes from the PolyORB configure.ac 506 | ############################################################# 507 | 508 | AC_DEFUN(AM_HAS_INTRINSIC_SYNC_COUNTERS, 509 | [ 510 | AC_MSG_CHECKING([whether platform supports atomic inc/dec]) 511 | AM_TRY_ADA([gnatmake], [check.adb], 512 | [ 513 | with Interfaces; use Interfaces; 514 | procedure Check is 515 | function Sync_Add_And_Fetch 516 | (Ptr : access Interfaces.Integer_32; 517 | Value : Interfaces.Integer_32) return Interfaces.Integer_32; 518 | pragma Import (Intrinsic, Sync_Add_And_Fetch, "__sync_add_and_fetch_4"); 519 | X : aliased Interfaces.Integer_32; 520 | Y : Interfaces.Integer_32 := 0; 521 | pragma Volatile (Y); 522 | -- On some platforms (e.g. i386), GCC has limited support for 523 | -- __sync_add_and_fetch_4 for the case where the result is not used. 524 | -- Here we want to test for general availability, so make Y volatile to 525 | -- prevent the store operation from being discarded. 526 | begin 527 | Y := Sync_Add_And_Fetch (X'Access, 1); 528 | end Check; 529 | ], 530 | [ 531 | AC_MSG_RESULT(yes) 532 | $1 533 | ],[ 534 | AC_MSG_RESULT(no) 535 | $2 536 | ]) 537 | 538 | rm -f check.adb check 539 | ]) 540 | 541 | # Prepare for using the GNAT project 542 | # AM_GNAT_LIBRARY_PROJECT([name]) 543 | AC_DEFUN(AM_GNAT_LIBRARY_PROJECT, 544 | [ 545 | # checking for local tools 546 | AM_GNAT_CHECK_GPRBUILD 547 | 548 | AC_PROG_MAKE_SET 549 | AC_PROG_INSTALL 550 | AC_PROG_LN_S 551 | AM_SHARED_LIBRARY_SUPPORT 552 | AM_DISTRIB_SUPPORT 553 | AM_COVERAGE_SUPPORT 554 | 555 | AC_MSG_CHECKING([number of processors]) 556 | NR_CPUS=`getconf _NPROCESSORS_CONF 2>/dev/null || getconf NPROCESSORS_CONF 2>/dev/null || echo 1` 557 | AC_MSG_RESULT($NR_CPUS) 558 | AC_SUBST(NR_CPUS) 559 | 560 | AM_UTIL_CHECK_INSTALL 561 | 562 | AC_MSG_CHECKING([preparing for GNAT project $1]) 563 | mkdir -p obj/$1/static obj/$1/relocatable lib/$1/static lib/$1/relocatable 564 | AC_MSG_RESULT(done) 565 | ]) 566 | 567 | -------------------------------------------------------------------------------- /ado/config.gpr: -------------------------------------------------------------------------------- 1 | abstract project Config is 2 | for Source_Dirs use (); 3 | 4 | type Yes_No is ("yes", "no"); 5 | 6 | type Library_Type_Type is ("relocatable", "static"); 7 | 8 | type Mode_Type is ("distrib", "debug", "optimize", "profile"); 9 | Mode : Mode_Type := external ("MODE", "debug"); 10 | 11 | Coverage : Yes_No := External ("COVERAGE", "no"); 12 | Processors := External ("PROCESSORS", "1"); 13 | 14 | package Builder is 15 | case Mode is 16 | when "debug" => 17 | for Default_Switches ("Ada") use ("-g", "-j" & Processors); 18 | when others => 19 | for Default_Switches ("Ada") use ("-g", "-O2", "-j" & Processors); 20 | end case; 21 | end Builder; 22 | 23 | package compiler is 24 | warnings := ("-gnatwua"); 25 | defaults := ("-gnat2012"); 26 | case Mode is 27 | when "distrib" => 28 | for Default_Switches ("Ada") use defaults & ("-gnatafno", "-gnatVa", "-gnatwa"); 29 | 30 | when "debug" => 31 | for Default_Switches ("Ada") use defaults & warnings 32 | & ("-gnata", "-gnatVaMI", "-gnaty3abcefhiklmnprstxM99"); 33 | 34 | when "optimize" => 35 | for Default_Switches ("Ada") use defaults & warnings 36 | & ("-gnatn", "-gnatp", "-fdata-sections", "-ffunction-sections"); 37 | 38 | when "profile" => 39 | for Default_Switches ("Ada") use defaults & warnings & ("-pg"); 40 | end case; 41 | 42 | case Coverage is 43 | when "yes" => 44 | for Default_Switches ("ada") use Compiler'Default_Switches ("Ada") & 45 | ("-fprofile-arcs", "-ftest-coverage"); 46 | when others => 47 | end case; 48 | end compiler; 49 | 50 | package binder is 51 | case Mode is 52 | when "debug" => 53 | for Default_Switches ("Ada") use ("-E"); 54 | 55 | when others => 56 | for Default_Switches ("Ada") use ("-E"); 57 | 58 | end case; 59 | end binder; 60 | 61 | package linker is 62 | case Mode is 63 | when "profile" => 64 | for Default_Switches ("Ada") use ("-pg"); 65 | 66 | when "distrib" => 67 | for Default_Switches ("Ada") use ("-s"); 68 | 69 | when "optimize" => 70 | for Default_Switches ("Ada") use ("-Wl,--gc-sections"); 71 | 72 | when others => 73 | null; 74 | end case; 75 | 76 | case Coverage is 77 | when "yes" => 78 | for Default_Switches ("ada") use Linker'Default_Switches ("ada") & 79 | ("-fprofile-arcs"); 80 | when others => 81 | end case; 82 | end linker; 83 | 84 | package Ide is 85 | for VCS_Kind use "Subversion"; 86 | end Ide; 87 | 88 | end Config; 89 | -------------------------------------------------------------------------------- /ado/config/mysql-create-table.sql: -------------------------------------------------------------------------------- 1 | CREATE table test_simple ( 2 | id INTEGER AUTO_INCREMENT, 3 | value INTEGER, 4 | PRIMARY KEY(id) 5 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 6 | -------------------------------------------------------------------------------- /ado/config/postgresql-create-table.sql: -------------------------------------------------------------------------------- 1 | CREATE table test_simple ( 2 | "id" SERIAL, 3 | "value" INTEGER, 4 | PRIMARY KEY("id") 5 | ) 6 | -------------------------------------------------------------------------------- /ado/config/sqlite-create-table.sql: -------------------------------------------------------------------------------- 1 | CREATE table test_simple ( 2 | id INTEGER PRIMARY KEY AUTOINCREMENT, 3 | value INTEGER 4 | ) 5 | -------------------------------------------------------------------------------- /ado/configure.ac: -------------------------------------------------------------------------------- 1 | dnl Autoconf configure script for sqlbench 2 | 3 | dnl Process this file with autoconf to produce a configure script. 4 | 5 | AC_INIT(src/sqlbench.ads) 6 | 7 | AC_CANONICAL_SYSTEM 8 | dnl AM_MAINTAINER_MODE 9 | 10 | # Current release settings 11 | SQLBENCH_MAJOR_VERSION=0 12 | SQLBENCH_MINOR_VERSION=2 13 | SQLBENCH_MICRO_VERSION=0 14 | SQLBENCH_VERSION=$SQLBENCH_MAJOR_VERSION.$SQLBENCH_MINOR_VERSION.$SQLBENCH_MICRO_VERSION 15 | AM_GNAT_CHECK_GPRBUILD 16 | # checking for local tools 17 | AC_PROG_CC 18 | AC_PROG_MAKE_SET 19 | AC_PROG_INSTALL 20 | AC_PROG_LN_S 21 | 22 | # Set the version number of the project 23 | AC_SUBST(SQLBENCH_VERSION) 24 | AC_SUBST(SQLBENCH_MAJOR_VERSION) 25 | AC_SUBST(SQLBENCH_MINOR_VERSION) 26 | AC_SUBST(SQLBENCH_MICRO_VERSION) 27 | 28 | EXEC_PREFIX="$prefix" 29 | AC_SUBST(EXEC_PREFIX) 30 | SQLBENCH_LIBDIR="lib" 31 | AC_SUBST(SQLBENCH_LIBDIR) 32 | 33 | AC_MSG_CHECKING([number of processors]) 34 | NR_CPUS=`getconf _NPROCESSORS_CONF 2>/dev/null || getconf NPROCESSORS_CONF 2>/dev/null || echo 1` 35 | AC_MSG_RESULT($NR_CPUS) 36 | AC_SUBST(NR_CPUS) 37 | ########################################## 38 | # Check to enable/disable shared library 39 | ########################################## 40 | AM_SHARED_LIBRARY_SUPPORT 41 | 42 | ########################################## 43 | # Ada Util library 44 | ########################################## 45 | AM_GNAT_FIND_PROJECT([ada-util],[Ada Utility Library],[utilada_sys], 46 | [git@github.com:stcarrez/ada-util.git], 47 | [Building sqlbench requires the Ada Utility Library.], 48 | [ 49 | UTIL_DIR=${gnat_project_dir_utilada_sys} 50 | ]) 51 | AC_SUBST(UTIL_DIR) 52 | 53 | ########################################## 54 | # Ada Database Objects library 55 | ########################################## 56 | AM_GNAT_FIND_PROJECT([ada-ado],[Ada Database Objects],[ado], 57 | [git@github.com:stcarrez/ada-ado.git], 58 | [Building sqlbench requires the Ada Database Objects Library.], 59 | [ 60 | ADO_DIR=${gnat_project_dir_ado} 61 | ]) 62 | AC_SUBST(ADO_DIR) 63 | AC_OUTPUT( 64 | Makefile sqlbench.gpr 65 | ) 66 | -------------------------------------------------------------------------------- /ado/install-sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # install - install a program, script, or datafile 4 | # This comes from X11R5 (mit/util/scripts/install.sh). 5 | # 6 | # Copyright 1991 by the Massachusetts Institute of Technology 7 | # 8 | # Permission to use, copy, modify, distribute, and sell this software and its 9 | # documentation for any purpose is hereby granted without fee, provided that 10 | # the above copyright notice appear in all copies and that both that 11 | # copyright notice and this permission notice appear in supporting 12 | # documentation, and that the name of M.I.T. not be used in advertising or 13 | # publicity pertaining to distribution of the software without specific, 14 | # written prior permission. M.I.T. makes no representations about the 15 | # suitability of this software for any purpose. It is provided "as is" 16 | # without express or implied warranty. 17 | # 18 | # Calling this script install-sh is preferred over install.sh, to prevent 19 | # `make' implicit rules from creating a file called install from it 20 | # when there is no Makefile. 21 | # 22 | # This script is compatible with the BSD install script, but was written 23 | # from scratch. It can only install one file at a time, a restriction 24 | # shared with many OS's install programs. 25 | 26 | 27 | # set DOITPROG to echo to test this script 28 | 29 | # Don't use :- since 4.3BSD and earlier shells don't like it. 30 | doit="${DOITPROG-}" 31 | 32 | 33 | # put in absolute paths if you don't have them in your path; or use env. vars. 34 | 35 | mvprog="${MVPROG-mv}" 36 | cpprog="${CPPROG-cp}" 37 | chmodprog="${CHMODPROG-chmod}" 38 | chownprog="${CHOWNPROG-chown}" 39 | chgrpprog="${CHGRPPROG-chgrp}" 40 | stripprog="${STRIPPROG-strip}" 41 | rmprog="${RMPROG-rm}" 42 | mkdirprog="${MKDIRPROG-mkdir}" 43 | 44 | transformbasename="" 45 | transform_arg="" 46 | instcmd="$mvprog" 47 | chmodcmd="$chmodprog 0755" 48 | chowncmd="" 49 | chgrpcmd="" 50 | stripcmd="" 51 | rmcmd="$rmprog -f" 52 | mvcmd="$mvprog" 53 | src="" 54 | dst="" 55 | dir_arg="" 56 | 57 | while [ x"$1" != x ]; do 58 | case $1 in 59 | -c) instcmd="$cpprog" 60 | shift 61 | continue;; 62 | 63 | -d) dir_arg=true 64 | shift 65 | continue;; 66 | 67 | -m) chmodcmd="$chmodprog $2" 68 | shift 69 | shift 70 | continue;; 71 | 72 | -o) chowncmd="$chownprog $2" 73 | shift 74 | shift 75 | continue;; 76 | 77 | -g) chgrpcmd="$chgrpprog $2" 78 | shift 79 | shift 80 | continue;; 81 | 82 | -s) stripcmd="$stripprog" 83 | shift 84 | continue;; 85 | 86 | -t=*) transformarg=`echo $1 | sed 's/-t=//'` 87 | shift 88 | continue;; 89 | 90 | -b=*) transformbasename=`echo $1 | sed 's/-b=//'` 91 | shift 92 | continue;; 93 | 94 | *) if [ x"$src" = x ] 95 | then 96 | src=$1 97 | else 98 | # this colon is to work around a 386BSD /bin/sh bug 99 | : 100 | dst=$1 101 | fi 102 | shift 103 | continue;; 104 | esac 105 | done 106 | 107 | if [ x"$src" = x ] 108 | then 109 | echo "install: no input file specified" 110 | exit 1 111 | else 112 | true 113 | fi 114 | 115 | if [ x"$dir_arg" != x ]; then 116 | dst=$src 117 | src="" 118 | 119 | if [ -d $dst ]; then 120 | instcmd=: 121 | chmodcmd="" 122 | else 123 | instcmd=mkdir 124 | fi 125 | else 126 | 127 | # Waiting for this to be detected by the "$instcmd $src $dsttmp" command 128 | # might cause directories to be created, which would be especially bad 129 | # if $src (and thus $dsttmp) contains '*'. 130 | 131 | if [ -f $src -o -d $src ] 132 | then 133 | true 134 | else 135 | echo "install: $src does not exist" 136 | exit 1 137 | fi 138 | 139 | if [ x"$dst" = x ] 140 | then 141 | echo "install: no destination specified" 142 | exit 1 143 | else 144 | true 145 | fi 146 | 147 | # If destination is a directory, append the input filename; if your system 148 | # does not like double slashes in filenames, you may need to add some logic 149 | 150 | if [ -d $dst ] 151 | then 152 | dst="$dst"/`basename $src` 153 | else 154 | true 155 | fi 156 | fi 157 | 158 | ## this sed command emulates the dirname command 159 | dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 160 | 161 | # Make sure that the destination directory exists. 162 | # this part is taken from Noah Friedman's mkinstalldirs script 163 | 164 | # Skip lots of stat calls in the usual case. 165 | if [ ! -d "$dstdir" ]; then 166 | defaultIFS=' 167 | ' 168 | IFS="${IFS-${defaultIFS}}" 169 | 170 | oIFS="${IFS}" 171 | # Some sh's can't handle IFS=/ for some reason. 172 | IFS='%' 173 | set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` 174 | IFS="${oIFS}" 175 | 176 | pathcomp='' 177 | 178 | while [ $# -ne 0 ] ; do 179 | pathcomp="${pathcomp}${1}" 180 | shift 181 | 182 | if [ ! -d "${pathcomp}" ] ; 183 | then 184 | $mkdirprog "${pathcomp}" 185 | else 186 | true 187 | fi 188 | 189 | pathcomp="${pathcomp}/" 190 | done 191 | fi 192 | 193 | if [ x"$dir_arg" != x ] 194 | then 195 | $doit $instcmd $dst && 196 | 197 | if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && 198 | if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && 199 | if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && 200 | if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi 201 | else 202 | 203 | # If we're going to rename the final executable, determine the name now. 204 | 205 | if [ x"$transformarg" = x ] 206 | then 207 | dstfile=`basename $dst` 208 | else 209 | dstfile=`basename $dst $transformbasename | 210 | sed $transformarg`$transformbasename 211 | fi 212 | 213 | # don't allow the sed command to completely eliminate the filename 214 | 215 | if [ x"$dstfile" = x ] 216 | then 217 | dstfile=`basename $dst` 218 | else 219 | true 220 | fi 221 | 222 | # Make a temp file name in the proper directory. 223 | 224 | dsttmp=$dstdir/#inst.$$# 225 | 226 | # Move or copy the file name to the temp name 227 | 228 | $doit $instcmd $src $dsttmp && 229 | 230 | trap "rm -f ${dsttmp}" 0 && 231 | 232 | # and set any options; do chmod last to preserve setuid bits 233 | 234 | # If any of these fail, we abort the whole thing. If we want to 235 | # ignore errors from any of these, just make sure not to ignore 236 | # errors from the above "$doit $instcmd $src $dsttmp" command. 237 | 238 | if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && 239 | if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && 240 | if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && 241 | if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && 242 | 243 | # Now rename the file to the real destination. 244 | 245 | $doit $rmcmd -f $dstdir/$dstfile && 246 | $doit $mvcmd $dsttmp $dstdir/$dstfile 247 | 248 | fi && 249 | 250 | 251 | exit 0 252 | -------------------------------------------------------------------------------- /ado/sqlbench.gpr.in: -------------------------------------------------------------------------------- 1 | with "@UTIL_DIR@config"; 2 | with "@UTIL_DIR@utilada_sys"; 3 | with "@ADO_DIR@ado_all"; 4 | 5 | project sqlbench is 6 | 7 | Mains := ("sqlbench-main.adb"); 8 | 9 | for Main use Mains; 10 | for Source_Dirs use ("src"); 11 | for Object_Dir use "./" & Config'Object_Dir & "/obj"; 12 | for Exec_Dir use "./" & Config'Exec_Dir & "/bin"; 13 | 14 | package Binder renames Config.Binder; 15 | package Builder is 16 | for Default_Switches ("Ada") use 17 | Config.Builder'Default_Switches ("Ada"); 18 | for Executable ("sqlbench-main.adb") use "sqlbench"; 19 | end Builder; 20 | 21 | package Compiler renames Config.Compiler; 22 | package Linker renames Config.Linker; 23 | 24 | end sqlbench; 25 | -------------------------------------------------------------------------------- /ado/sqlbench.properties: -------------------------------------------------------------------------------- 1 | ado.queries.load=true 2 | ado.queries.paths=db 3 | ado.drivers.load=false 4 | ado.entities.ignore=true 5 | 6 | mysql.database=mysql://localhost:3306/sqlbench?user=sqlbench&password=sqlbench&encoding=utf8&autocommit=0&socket=/var/run/mysqld/mysqld.sock 7 | postgresql.database=postgresql://localhost:5432/sqlbench?user=sqlbench&password=sqlbench&client_encoding=UTF8' 8 | sqlite.database=sqlite:///sqlbench.db?synchronous=OFF&encoding=UTF-8&create=on 9 | 10 | # Configuration for log4j 11 | log4j.rootCategory=DEBUG,console,result 12 | log4j.appender.console=Console 13 | log4j.appender.console.level=INFO 14 | log4j.appender.console.layout=level-message 15 | log4j.appender.result=File 16 | log4j.appender.result.File=sqlbench.log 17 | 18 | # Logger configuration 19 | log4j.logger.log=WARN 20 | log4j.logger.Util=WARN 21 | log4j.logger.ADO=WARN,result 22 | log4j.logger.ADO.Sessions=WARN 23 | log4j.logger.ADO.Statements=WARN 24 | log4j.logger.ADO.Databases=WARN 25 | 26 | dynamo_author_email=Stephane.Carrez@gmail.com 27 | dynamo_is_ado=TRUE 28 | dynamo_license=apache 29 | dynamo_is_gtk=FALSE 30 | dynamo_is_lib=FALSE 31 | dynamo_author=Stephane Carrez 32 | dynamo_is_web=FALSE 33 | dynamo_is_tool=FALSE 34 | -------------------------------------------------------------------------------- /ado/src/sqlbench-main.adb: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------- 2 | -- sqlbench-main -- Main SQL Bencharmk 3 | -- Copyright (C) 2018, 2019 Stephane Carrez 4 | -- Written by Stephane Carrez (Stephane.Carrez@gmail.com) 5 | -- 6 | -- Licensed under the Apache License, Version 2.0 (the "License"); 7 | -- you may not use this file except in compliance with the License. 8 | -- You may obtain a copy of the License at 9 | -- 10 | -- http://www.apache.org/licenses/LICENSE-2.0 11 | -- 12 | -- Unless required by applicable law or agreed to in writing, software 13 | -- distributed under the License is distributed on an "AS IS" BASIS, 14 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | -- See the License for the specific language governing permissions and 16 | -- limitations under the License. 17 | ----------------------------------------------------------------------- 18 | with Ada.Exceptions; 19 | with Ada.Command_Line; 20 | with Ada.Text_IO; 21 | with Ada.Strings.Unbounded; 22 | 23 | with Util.Log.Loggers; 24 | with Util.Measures; 25 | with Util.Strings; 26 | with Util.Files; 27 | 28 | with ADO; 29 | with ADO.Configs; 30 | with ADO.Drivers; 31 | with ADO.Connections; 32 | with ADO.Sessions; 33 | with ADO.Sessions.Factory; 34 | 35 | with Sqlbench.Simple; 36 | 37 | procedure Sqlbench.Main is 38 | 39 | use Ada.Strings.Unbounded; 40 | 41 | procedure Read_Line (Line : in String); 42 | procedure Read_Stat_Line (Line : in String); 43 | 44 | Log : constant Util.Log.Loggers.Logger := Util.Log.Loggers.Create ("Sqlbench.Main"); 45 | 46 | Thread_Count : Natural := 0; 47 | Rss_Size : Natural := 0; 48 | Hwm_Size : Natural := 0; 49 | User_Time : Natural := 0; 50 | Sys_Time : Natural := 0; 51 | 52 | procedure Read_Line (Line : in String) is 53 | Pos : Natural := Util.Strings.Index (Line, ASCII.HT); 54 | Last : Natural := Util.Strings.Rindex (Line, ' '); 55 | begin 56 | Log.Debug ("{0}", Line); 57 | 58 | if Pos = 0 then 59 | Pos := Util.Strings.Index (Line, ' '); 60 | end if; 61 | if Last = 0 then 62 | Last := Line'Last; 63 | end if; 64 | if Pos > 0 then 65 | if Util.Strings.Starts_With (Line, "Threads:") then 66 | Thread_Count := Natural'Value (Line (Pos + 1 .. Last)); 67 | elsif Util.Strings.Starts_With (Line, "VmRSS:") then 68 | Rss_Size := Natural'Value (Line (Pos + 1 .. Last)); 69 | elsif Util.Strings.Starts_With (Line, "VmHWM:") then 70 | Hwm_Size := Natural'Value (Line (Pos + 1 .. Last)); 71 | end if; 72 | end if; 73 | 74 | exception 75 | when Constraint_Error => 76 | null; 77 | end Read_Line; 78 | 79 | procedure Read_Stat_Line (Line : in String) is 80 | Pos : Natural := Line'First; 81 | Next : Natural; 82 | begin 83 | Log.Debug ("{0}", Line); 84 | 85 | for I in 1 .. 13 loop 86 | Pos := Util.Strings.Index (Line, ' ', Pos + 1); 87 | exit when Pos = 0; 88 | end loop; 89 | Next := Util.Strings.Index (Line, ' ', Pos + 1); 90 | User_Time := 10 * Natural'Value (Line (Pos + 1 .. Next - 1)); 91 | Pos := Next; 92 | Next := Util.Strings.Index (Line, ' ', Pos + 1); 93 | Sys_Time := 10 * Natural'Value (Line (Pos + 1 .. Next - 1)); 94 | 95 | exception 96 | when Constraint_Error => 97 | null; 98 | end Read_Stat_Line; 99 | 100 | Driver : Unbounded_String; 101 | Context : Sqlbench.Context_Type; 102 | Repeat : Sqlbench.Repeat_Type := 100; 103 | Output : Unbounded_String; 104 | Output_File : Ada.Text_IO.File_Type; 105 | Arg_Pos : Positive := 1; 106 | Arg_Count : constant Natural := Ada.Command_Line.Argument_Count; 107 | begin 108 | Util.Log.Loggers.Initialize ("sqlbench.properties"); 109 | 110 | -- Initialize the database drivers. 111 | ADO.Drivers.Initialize ("sqlbench.properties"); 112 | 113 | while Arg_Pos <= Arg_Count loop 114 | declare 115 | Arg : constant String := Ada.Command_Line.Argument (Arg_Pos); 116 | begin 117 | if Arg = "-sqlite" then 118 | Driver := To_Unbounded_String ("sqlite"); 119 | elsif Arg = "-mysql" then 120 | Driver := To_Unbounded_String ("mysql"); 121 | elsif Arg = "-postgresql" then 122 | Driver := To_Unbounded_String ("postgresql"); 123 | elsif Arg = "-repeat" and Arg_Pos + 1 <= Arg_Count then 124 | Arg_Pos := Arg_Pos + 1; 125 | Repeat := Repeat_Type'Value (Ada.Command_Line.Argument (Arg_Pos)); 126 | elsif Arg = "-o" and Arg_Pos + 1 <= Arg_Count then 127 | Arg_Pos := Arg_Pos + 1; 128 | Output := To_Unbounded_String (Ada.Command_Line.Argument (Arg_Pos)); 129 | else 130 | raise Constraint_Error; 131 | end if; 132 | 133 | exception 134 | when Constraint_Error => 135 | Ada.Text_IO.Put_Line (Ada.Text_IO.Standard_Error, 136 | "Usage: sql-bench [-sqlite] [-mysql] [-postgresql] " 137 | & "[-repeat count] [-o output]"); 138 | 139 | Ada.Command_Line.Set_Exit_Status (2); 140 | return; 141 | end; 142 | Arg_Pos := Arg_Pos + 1; 143 | end loop; 144 | 145 | -- Initialize the session factory to connect to the 146 | -- database defined by 'ado.database' property. 147 | Context.Factory.Create (ADO.Configs.Get_Config (To_String (Driver) & ".database")); 148 | Context.Session := Context.Factory.Get_Master_Session; 149 | Simple.Register (Context); 150 | 151 | for Test of Context.Tests loop 152 | Context.Repeat := Repeat * Test.Factor; 153 | 154 | declare 155 | T : Util.Measures.Stamp; 156 | begin 157 | Test.Handler (Context); 158 | Util.Measures.Report (Context.Perf, T, Test.Title, Positive (Context.Repeat)); 159 | 160 | exception 161 | when others => 162 | null; 163 | end; 164 | 165 | end loop; 166 | 167 | begin 168 | Util.Files.Read_File (Path => "/proc/self/status", Process => Read_Line'Access); 169 | 170 | exception 171 | when others => 172 | null; 173 | end; 174 | 175 | begin 176 | Util.Files.Read_File (Path => "/proc/self/stat", Process => Read_Stat_Line'Access); 177 | 178 | exception 179 | when others => 180 | null; 181 | end; 182 | if Length (Output) > 0 then 183 | Ada.Text_IO.Create (Output_File, Ada.Text_IO.Out_File, To_String (Output)); 184 | Ada.Text_IO.Set_Output (Output_File); 185 | end if; 186 | Ada.Text_IO.Put (""); 199 | Util.Measures.Write (Context.Perf, "SQL Benchmark", 200 | (if Length (Output) > 0 then 201 | Output_File else Ada.Text_IO.Standard_Output)); 202 | Ada.Text_IO.Put_Line (""); 203 | Ada.Text_IO.Flush; 204 | 205 | exception 206 | when E : ADO.Connections.Database_Error | ADO.Sessions.Connection_Error => 207 | Ada.Text_IO.Put_Line (Ada.Text_IO.Standard_Error, 208 | "Cannot connect to database: " 209 | & Ada.Exceptions.Exception_Message (E)); 210 | Ada.Command_Line.Set_Exit_Status (1); 211 | end Sqlbench.Main; 212 | -------------------------------------------------------------------------------- /ado/src/sqlbench-simple.adb: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------- 2 | -- sqlbench-simple -- Simple SQL benchmark 3 | -- Copyright (C) 2018 Stephane Carrez 4 | -- Written by Stephane Carrez (Stephane.Carrez@gmail.com) 5 | -- 6 | -- Licensed under the Apache License, Version 2.0 (the "License"); 7 | -- you may not use this file except in compliance with the License. 8 | -- You may obtain a copy of the License at 9 | -- 10 | -- http://www.apache.org/licenses/LICENSE-2.0 11 | -- 12 | -- Unless required by applicable law or agreed to in writing, software 13 | -- distributed under the License is distributed on an "AS IS" BASIS, 14 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | -- See the License for the specific language governing permissions and 16 | -- limitations under the License. 17 | ----------------------------------------------------------------------- 18 | with Ada.Strings.Unbounded; 19 | with ADO.Statements; 20 | with Util.Files; 21 | package body Sqlbench.Simple is 22 | 23 | use Ada.Strings.Unbounded; 24 | 25 | generic 26 | LIMIT : Positive; 27 | procedure Select_Table_N (Context : in out Context_Type); 28 | 29 | procedure Select_Table_N (Context : in out Context_Type) is 30 | DB : constant ADO.Sessions.Master_Session := Context.Get_Session; 31 | Count : Natural; 32 | Stmt : ADO.Statements.Query_Statement 33 | := DB.Create_Statement ("SELECT * FROM test_simple LIMIT " & Positive'Image (LIMIT)); 34 | begin 35 | for I in 1 .. Context.Repeat loop 36 | Stmt.Execute; 37 | Count := 0; 38 | while Stmt.Has_Elements loop 39 | Count := Count + 1; 40 | Stmt.Next; 41 | end loop; 42 | if Count /= LIMIT then 43 | raise Benchmark_Error with "Invalid result count:" & Natural'Image (Count); 44 | end if; 45 | end loop; 46 | end Select_Table_N; 47 | 48 | procedure Do_Static (Context : in out Context_Type); 49 | 50 | procedure Select_Static (Context : in out Context_Type); 51 | 52 | procedure Connect_Select_Static (Context : in out Context_Type); 53 | 54 | procedure Drop_Create (Context : in out Context_Type); 55 | 56 | procedure Insert (Context : in out Context_Type); 57 | 58 | procedure Select_Table_1 is new Select_Table_N (1); 59 | 60 | procedure Select_Table_10 is new Select_Table_N (10); 61 | 62 | procedure Select_Table_100 is new Select_Table_N (100); 63 | 64 | procedure Select_Table_500 is new Select_Table_N (500); 65 | 66 | procedure Select_Table_1000 is new Select_Table_N (1000); 67 | 68 | Create_SQL : Ada.Strings.Unbounded.Unbounded_String; 69 | 70 | procedure Register (Tests : in out Context_Type) is 71 | Driver : constant String := Tests.Get_Driver_Name; 72 | begin 73 | if Driver /= "sqlite" and Driver /= "postgresql" then 74 | Tests.Register (Do_Static'Access, "DO 1"); 75 | end if; 76 | Tests.Register (Select_Static'Access, "SELECT 1"); 77 | Tests.Register (Connect_Select_Static'Access, "CONNECT; SELECT 1; CLOSE"); 78 | Tests.Register (Drop_Create'Access, "DROP table; CREATE table", 1); 79 | Tests.Register (Insert'Access, "INSERT INTO table", 10); 80 | Tests.Register (Select_Table_1'Access, "SELECT * FROM table LIMIT 1"); 81 | Tests.Register (Select_Table_10'Access, "SELECT * FROM table LIMIT 10"); 82 | Tests.Register (Select_Table_100'Access, "SELECT * FROM table LIMIT 100"); 83 | Tests.Register (Select_Table_500'Access, "SELECT * FROM table LIMIT 500"); 84 | Tests.Register (Select_Table_1000'Access, "SELECT * FROM table LIMIT 1000"); 85 | Util.Files.Read_File (Tests.Get_Config_Path ("create-table.sql"), Create_SQL); 86 | end Register; 87 | 88 | procedure Do_Static (Context : in out Context_Type) is 89 | Stmt : ADO.Statements.Query_Statement := Context.Session.Create_Statement ("DO 1"); 90 | begin 91 | for I in 1 .. Context.Repeat loop 92 | Stmt.Execute; 93 | end loop; 94 | end Do_Static; 95 | 96 | procedure Select_Static (Context : in out Context_Type) is 97 | Stmt : ADO.Statements.Query_Statement := Context.Session.Create_Statement ("SELECT 1"); 98 | begin 99 | for I in 1 .. Context.Repeat loop 100 | Stmt.Execute; 101 | end loop; 102 | end Select_Static; 103 | 104 | procedure Connect_Select_Static (Context : in out Context_Type) is 105 | begin 106 | for I in 1 .. Context.Repeat loop 107 | declare 108 | DB : constant ADO.Sessions.Session := Context.Factory.Get_Session; 109 | Stmt : ADO.Statements.Query_Statement := DB.Create_Statement ("SELECT 1"); 110 | begin 111 | Stmt.Execute; 112 | end; 113 | end loop; 114 | end Connect_Select_Static; 115 | 116 | procedure Drop_Create (Context : in out Context_Type) is 117 | Drop_Stmt : ADO.Statements.Query_Statement 118 | := Context.Session.Create_Statement ("DROP TABLE test_simple"); 119 | Create_Stmt : ADO.Statements.Query_Statement 120 | := Context.Session.Create_Statement (To_String (Create_SQL)); 121 | begin 122 | for I in 1 .. Context.Repeat loop 123 | begin 124 | Drop_Stmt.Execute; 125 | Context.Session.Commit; 126 | exception 127 | when ADO.Statements.SQL_Error => 128 | Context.Session.Rollback; 129 | end; 130 | Context.Session.Begin_Transaction; 131 | Create_Stmt.Execute; 132 | Context.Session.Commit; 133 | Context.Session.Begin_Transaction; 134 | end loop; 135 | end Drop_Create; 136 | 137 | procedure Insert (Context : in out Context_Type) is 138 | Stmt : ADO.Statements.Query_Statement 139 | := Context.Session.Create_Statement ("INSERT INTO test_simple (value) VALUES (1)"); 140 | begin 141 | for I in 1 .. Context.Repeat loop 142 | Stmt.Execute; 143 | end loop; 144 | Context.Session.Commit; 145 | end Insert; 146 | 147 | end Sqlbench.Simple; 148 | -------------------------------------------------------------------------------- /ado/src/sqlbench-simple.ads: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------- 2 | -- sqlbench-simple -- Simple SQL benchmark 3 | -- Copyright (C) 2018 Stephane Carrez 4 | -- Written by Stephane Carrez (Stephane.Carrez@gmail.com) 5 | -- 6 | -- Licensed under the Apache License, Version 2.0 (the "License"); 7 | -- you may not use this file except in compliance with the License. 8 | -- You may obtain a copy of the License at 9 | -- 10 | -- http://www.apache.org/licenses/LICENSE-2.0 11 | -- 12 | -- Unless required by applicable law or agreed to in writing, software 13 | -- distributed under the License is distributed on an "AS IS" BASIS, 14 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | -- See the License for the specific language governing permissions and 16 | -- limitations under the License. 17 | ----------------------------------------------------------------------- 18 | 19 | package Sqlbench.Simple is 20 | 21 | procedure Register (Tests : in out Context_Type); 22 | 23 | end Sqlbench.Simple; 24 | -------------------------------------------------------------------------------- /ado/src/sqlbench.adb: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------- 2 | -- sqlbench -- SQL Benchmark 3 | -- Copyright (C) 2018 Stephane Carrez 4 | -- Written by Stephane Carrez (Stephane.Carrez@gmail.com) 5 | -- 6 | -- Licensed under the Apache License, Version 2.0 (the "License"); 7 | -- you may not use this file except in compliance with the License. 8 | -- You may obtain a copy of the License at 9 | -- 10 | -- http://www.apache.org/licenses/LICENSE-2.0 11 | -- 12 | -- Unless required by applicable law or agreed to in writing, software 13 | -- distributed under the License is distributed on an "AS IS" BASIS, 14 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | -- See the License for the specific language governing permissions and 16 | -- limitations under the License. 17 | ----------------------------------------------------------------------- 18 | with Util.Files; 19 | package body Sqlbench is 20 | 21 | -- ------------------------------ 22 | -- Register a benchmark handler under the given name. 23 | -- ------------------------------ 24 | procedure Register (Context : in out Context_Type; 25 | Handler : in Benchmark_Handler; 26 | Title : in String; 27 | Factor : in Repeat_Factor_Type := 100) is 28 | begin 29 | Context.Tests.Append (Benchmark_Test '(Len => Title'Length, 30 | Handler => Handler, 31 | Title => Title, 32 | Factor => Factor)); 33 | end Register; 34 | 35 | -- ------------------------------ 36 | -- Get the database session to make SQL requests on the database. 37 | -- ------------------------------ 38 | function Get_Session (Context : in Context_Type) return ADO.Sessions.Master_Session is 39 | begin 40 | return Context.Session; 41 | end Get_Session; 42 | 43 | -- ------------------------------ 44 | -- Get a benchmark configuration parameter. 45 | -- ------------------------------ 46 | function Get_Parameter (Context : in Context_Type; 47 | Name : in String) return String is 48 | begin 49 | return Context.Config.Get (Name, ""); 50 | end Get_Parameter; 51 | 52 | -- ------------------------------ 53 | -- Get a SQL configuration file path that depends on the database driver. 54 | -- The file is of the form: /- 55 | -- ------------------------------ 56 | function Get_Config_Path (Context : in Context_Type; 57 | Name : in String) return String is 58 | begin 59 | return Util.Files.Compose ("config", Context.Get_Driver_Name & "-" & Name); 60 | end Get_Config_Path; 61 | 62 | -- ------------------------------ 63 | -- Get the database driver name. 64 | -- ------------------------------ 65 | function Get_Driver_Name (Context : in Context_Type) return String is 66 | begin 67 | return Context.Session.Get_Driver.Get_Driver_Name; 68 | end Get_Driver_Name; 69 | 70 | end Sqlbench; 71 | -------------------------------------------------------------------------------- /ado/src/sqlbench.ads: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------- 2 | -- sqlbench -- SQL Benchmark 3 | -- Copyright (C) 2018 Stephane Carrez 4 | -- Written by Stephane Carrez (Stephane.Carrez@gmail.com) 5 | -- 6 | -- Licensed under the Apache License, Version 2.0 (the "License"); 7 | -- you may not use this file except in compliance with the License. 8 | -- You may obtain a copy of the License at 9 | -- 10 | -- http://www.apache.org/licenses/LICENSE-2.0 11 | -- 12 | -- Unless required by applicable law or agreed to in writing, software 13 | -- distributed under the License is distributed on an "AS IS" BASIS, 14 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | -- See the License for the specific language governing permissions and 16 | -- limitations under the License. 17 | ----------------------------------------------------------------------- 18 | with ADO.Sessions; 19 | with ADO.Sessions.Factory; 20 | private with Util.Measures; 21 | private with Util.Properties; 22 | private with Ada.Containers.Indefinite_Vectors; 23 | package Sqlbench is 24 | 25 | Benchmark_Error : exception; 26 | 27 | type Context_Type is tagged limited private; 28 | 29 | type Repeat_Type is new Positive range 1 .. 1_000_000; 30 | 31 | subtype Repeat_Factor_Type is Repeat_Type range 1 .. 100; 32 | 33 | type Benchmark_Handler is access not null procedure (Context : in out Context_Type); 34 | 35 | -- Register a benchmark handler under the given name. 36 | procedure Register (Context : in out Context_Type; 37 | Handler : in Benchmark_Handler; 38 | Title : in String; 39 | Factor : in Repeat_Factor_Type := 100) 40 | with Pre => Title'Length > 0; 41 | 42 | -- Get the database session to make SQL requests on the database. 43 | function Get_Session (Context : in Context_Type) return ADO.Sessions.Master_Session; 44 | 45 | -- Get a benchmark configuration parameter. 46 | function Get_Parameter (Context : in Context_Type; 47 | Name : in String) return String 48 | with Pre => Name'Length > 0; 49 | 50 | -- Get a SQL configuration file path that depends on the database driver. 51 | -- The file is of the form: /- 52 | function Get_Config_Path (Context : in Context_Type; 53 | Name : in String) return String 54 | with Pre => Name'Length > 0; 55 | 56 | -- Get the database driver name. 57 | function Get_Driver_Name (Context : in Context_Type) return String 58 | with Post => Get_Driver_Name'Result'Length > 0; 59 | 60 | private 61 | 62 | type Benchmark_Test (Len : Natural) is record 63 | Handler : Benchmark_Handler; 64 | Title : String (1 .. Len); 65 | Factor : Repeat_Factor_Type := 1; 66 | end record; 67 | 68 | package Benchmark_Test_Vectors is 69 | new Ada.Containers.Indefinite_Vectors (Index_Type => Positive, 70 | Element_Type => Benchmark_Test, 71 | "=" => "="); 72 | 73 | subtype Benchmark_Vector is Benchmark_Test_Vectors.Vector; 74 | subtype Benchmark_Cursor is Benchmark_Test_Vectors.Cursor; 75 | 76 | type Context_Type is tagged limited record 77 | Perf : Util.Measures.Measure_Set; 78 | Repeat : Repeat_Type := 1; 79 | Session : ADO.Sessions.Master_Session; 80 | Factory : ADO.Sessions.Factory.Session_Factory; 81 | Tests : Benchmark_Vector; 82 | Config : Util.Properties.Manager; 83 | end record; 84 | 85 | end Sqlbench; 86 | -------------------------------------------------------------------------------- /java/README.md: -------------------------------------------------------------------------------- 1 | ## Build 2 | 3 | To build the Java program benchmark, you must use Maven 4 | 5 | ``` 6 | mvn compile assembly:single 7 | ``` 8 | 9 | ## Run 10 | 11 | MySQL 12 | ``` 13 | java -jar target/sql-benchmark-1.0.jar -mysql -repeat 100 14 | ``` 15 | 16 | PostgreSQL 17 | ``` 18 | java -jar target/sql-benchmark-1.0.jar -postgresql -repeat 100 19 | ``` 20 | 21 | SQLite 22 | ``` 23 | java -jar target/sql-benchmark-1.0.jar -sqlite -repeat 100 24 | ``` 25 | -------------------------------------------------------------------------------- /java/config: -------------------------------------------------------------------------------- 1 | ../ado/config -------------------------------------------------------------------------------- /java/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | org.ciceron.sqlbenchmark 5 | sql-benchmark 6 | jar 7 | 1.0 8 | sql-benchmark 9 | http://maven.apache.org 10 | 11 | 12 | 1.8 13 | 1.8 14 | UTF-8 15 | 16 | 17 | 18 | 19 | The Apache Software License, Version 2.0 20 | http://www.apache.org/licenses/LICENSE-2.0.txt 21 | repo 22 | 23 | 24 | 25 | 26 | 27 | stcarrez 28 | Stephane Carrez 29 | Stephane.Carrez@gmail.com 30 | Open Source 31 | 32 | Architect 33 | Project Manager 34 | Chief Developer 35 | 36 | +1 37 | 38 | 39 | 40 | 41 | 42 | 43 | maven-assembly-plugin 44 | 45 | 46 | 47 | org.ciceron.sqlbenchmark.Main 48 | 49 | 50 | 51 | jar-with-dependencies 52 | 53 | false 54 | false 55 | 56 | 57 | 58 | 59 | maven-compiler-plugin 60 | 3.8.0 61 | 62 | 63 | -Xlint:all 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | org.xerial 73 | sqlite-jdbc 74 | 3.25.2 75 | 76 | 77 | org.postgresql 78 | postgresql 79 | 42.2.5 80 | 81 | 82 | mysql 83 | mysql-connector-java 84 | 5.1.47 85 | 86 | 87 | junit 88 | junit 89 | 3.8.1 90 | test 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /java/sql-benchmark.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /java/sqlbench.properties: -------------------------------------------------------------------------------- 1 | ado.queries.load=true 2 | ado.queries.paths=db 3 | ado.drivers.load=false 4 | 5 | mysql.database=jdbc:mysql://localhost:3306/sqlbench?user=sqlbench&password=sqlbench&encoding=utf8 6 | postgresql.database=jdbc:postgresql://localhost:5432/sqlbench?user=sqlbench&password=sqlbench 7 | sqlite.database=jdbc:sqlite:sqlbench.db?synchronous=OFF&encoding=UTF-8 8 | 9 | # Configuration for log4j 10 | log4j.rootCategory=DEBUG,console,result 11 | log4j.appender.console=Console 12 | log4j.appender.console.level=INFO 13 | log4j.appender.console.layout=level-message 14 | log4j.appender.result=File 15 | log4j.appender.result.File=sqlbench.log 16 | 17 | # Logger configuration 18 | log4j.logger.log=WARN 19 | log4j.logger.Util=WARN 20 | log4j.logger.ADO=INFO,result 21 | log4j.logger.ADO.Sessions=WARN 22 | log4j.logger.ADO.Statements=DEBUG 23 | 24 | dynamo_author_email=Stephane.Carrez@gmail.com 25 | dynamo_is_ado=TRUE 26 | dynamo_license=apache 27 | dynamo_is_gtk=FALSE 28 | dynamo_is_lib=FALSE 29 | dynamo_author=Stephane Carrez 30 | dynamo_is_web=FALSE 31 | dynamo_is_tool=FALSE 32 | -------------------------------------------------------------------------------- /java/src/main/java/org/ciceron/sqlbenchmark/Benchmark.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SQL Benchmark 3 | * Copyright (C) 2018 Stephane Carrez 4 | * Written by Stephane Carrez (Stephane.Carrez@gmail.com) 5 | * 6 | * Licensed to the Apache Software Foundation (ASF) under one 7 | * or more contributor license agreements. See the NOTICE file 8 | * distributed with this work for additional information 9 | * regarding copyright ownership. The ASF licenses this file 10 | * to you under the Apache License, Version 2.0 (the 11 | * "License"); you may not use this file except in compliance 12 | * with the License. You may obtain a copy of the License at 13 | * 14 | * http://www.apache.org/licenses/LICENSE-2.0 15 | * 16 | * Unless required by applicable law or agreed to in writing, 17 | * software distributed under the License is distributed on an 18 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 19 | * KIND, either express or implied. See the License for the 20 | * specific language governing permissions and limitations 21 | * under the License. 22 | */ 23 | package org.ciceron.sqlbenchmark; 24 | 25 | import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; 26 | import org.postgresql.ds.PGSimpleDataSource; 27 | import org.sqlite.SQLiteConfig; 28 | import org.sqlite.SQLiteDataSource; 29 | import org.sqlite.SQLiteOpenMode; 30 | 31 | import javax.sql.DataSource; 32 | import java.io.BufferedReader; 33 | import java.io.File; 34 | import java.io.FileInputStream; 35 | import java.io.FileReader; 36 | import java.io.IOException; 37 | import java.io.PrintStream; 38 | import java.sql.Connection; 39 | import java.sql.SQLException; 40 | import java.util.Map; 41 | import java.util.Properties; 42 | import java.util.TreeMap; 43 | 44 | public abstract class Benchmark { 45 | 46 | public static String getConfigPath(String name) { 47 | return "config/" + mDriverName + "-" + name; 48 | } 49 | 50 | static class Result { 51 | long count; 52 | long time; 53 | 54 | Result(long count, long time) { 55 | this.count = count; 56 | this.time = time; 57 | } 58 | } 59 | 60 | private static final TreeMap mResults = new TreeMap(); 61 | private static String mDriverName; 62 | static DataSource mDataSource; 63 | static Connection mConnection; 64 | static final Properties mConfig = new Properties(); 65 | static long mRepeat; 66 | private static long mBaseRepeat = 10; 67 | private String mTitle; 68 | private final int mFactor; 69 | 70 | public static void loadConfiguration(String path) throws IOException { 71 | FileInputStream input = new FileInputStream(path); 72 | mConfig.load(input); 73 | input.close(); 74 | } 75 | 76 | public static void setBaseRepeat(long value) { 77 | mBaseRepeat = value; 78 | } 79 | 80 | public static boolean setDatabase(String driver) throws SQLException { 81 | String config = (String) mConfig.get(driver + ".database"); 82 | 83 | mDriverName = driver; 84 | if ("mysql".equals(driver)) { 85 | 86 | // Load the MySQL driver. 87 | try { 88 | Class.forName("com.mysql.jdbc.Driver"); 89 | } catch (Exception ex) { 90 | System.err.println("Loading MySQL-Driver failed!"); 91 | } 92 | 93 | MysqlDataSource ds = new MysqlDataSource(); 94 | ds.setURL(config); 95 | mDataSource = ds; 96 | mConnection = mDataSource.getConnection(); 97 | mConnection.setAutoCommit(false); 98 | return true; 99 | } 100 | 101 | if ("postgresql".equals(driver)) { 102 | PGSimpleDataSource ds = new PGSimpleDataSource(); 103 | 104 | ds.setURL(config); 105 | mDataSource = ds; 106 | mConnection = mDataSource.getConnection(); 107 | mConnection.setAutoCommit(false); 108 | return true; 109 | } 110 | 111 | if ("sqlite".equals(driver)) { 112 | SQLiteDataSource ds = new SQLiteDataSource(); 113 | SQLiteConfig sqliteConfig = new SQLiteConfig(); 114 | sqliteConfig.setJournalMode(SQLiteConfig.JournalMode.WAL); 115 | sqliteConfig.setEncoding(SQLiteConfig.Encoding.UTF_8); 116 | sqliteConfig.setBusyTimeout(5000); 117 | sqliteConfig.setTransactionMode(SQLiteConfig.TransactionMode.EXCLUSIVE); 118 | sqliteConfig.setOpenMode(SQLiteOpenMode.READWRITE); 119 | sqliteConfig.setOpenMode(SQLiteOpenMode.CREATE); 120 | sqliteConfig.setOpenMode(SQLiteOpenMode.FULLMUTEX); 121 | 122 | ds.setConfig(sqliteConfig); 123 | ds.setUrl(config); 124 | mDataSource = ds; 125 | mConnection = mDataSource.getConnection(); 126 | mConnection.setAutoCommit(false); 127 | return true; 128 | } 129 | return false; 130 | } 131 | 132 | static void readProcessInfo() { 133 | int thread_count = 0; 134 | int rss_size = 0; 135 | int hwm_size = 0; 136 | int user_time = 0; 137 | int sys_time = 0; 138 | try { 139 | File f = new File("/proc/self/status"); 140 | 141 | BufferedReader b = new BufferedReader(new FileReader(f)); 142 | 143 | String line; 144 | while ((line = b.readLine()) != null) { 145 | String[] items = line.split("\\s+"); 146 | if (line.startsWith("Threads:") && items.length > 0) { 147 | thread_count = Integer.parseInt(items[1]); 148 | } else if (line.startsWith("VmRSS:")) { 149 | rss_size = Integer.parseInt(items[1]); 150 | } else if (line.startsWith("VmHWM:")) { 151 | hwm_size = Integer.parseInt(items[1]); 152 | } 153 | } 154 | } catch (IOException e) { 155 | // Ignore since /proc/self/status is available only under GNU/Linux. 156 | } 157 | try { 158 | File f = new File("/proc/self/stat"); 159 | 160 | BufferedReader b = new BufferedReader(new FileReader(f)); 161 | 162 | String line; 163 | while ((line = b.readLine()) != null) { 164 | String[] items = line.split("\\s+"); 165 | if (items.length > 14) { 166 | user_time = 10 * Integer.parseInt(items[13]); 167 | sys_time = 10 * Integer.parseInt(items[14]); 168 | break; 169 | } 170 | } 171 | } catch (IOException e) { 172 | // Ignore since /proc/self/stat is available only under GNU/Linux. 173 | } 174 | System.out.println(""); 178 | } 179 | 180 | static String formatTime(long time) { 181 | long us = time / 1000; 182 | long ms = us / 1000; 183 | if (ms > 1000) { 184 | long sec = ms / 1000; 185 | ms = ms % 1000; 186 | return String.format("%d.%03d s", sec, ms); 187 | } else if (ms > 100) { 188 | us = us % 1000; 189 | return String.format("%d.%d ms", ms, us / 100); 190 | } else if (ms > 10) { 191 | us = us % 1000; 192 | return String.format("%d.%02d ms", ms, us / 10); 193 | } else if (ms > 1) { 194 | us = us % 1000; 195 | return String.format("%d.%03d ms", ms, us); 196 | } else { 197 | return String.format("%d us", us); 198 | } 199 | } 200 | 201 | static void printReport(String output) throws IOException { 202 | if (output.length() > 0) { 203 | PrintStream o = new PrintStream(new File(output)); 204 | System.setOut(o); 205 | } 206 | readProcessInfo(); 207 | System.out.println(""); 208 | for (Map.Entry result : mResults.entrySet()) { 209 | System.out.println(""); 214 | System.out.println(""); 215 | } 216 | 217 | public static String getDriverName() { 218 | return mDriverName; 219 | } 220 | 221 | Benchmark() { 222 | mFactor = 100; 223 | } 224 | 225 | Benchmark(String title) { 226 | mTitle = title; 227 | mFactor = 100; 228 | } 229 | 230 | Benchmark(String title, int factor) { 231 | mTitle = title; 232 | mFactor = factor; 233 | } 234 | 235 | public Benchmark Set(String name) { 236 | mTitle = name; 237 | return this; 238 | } 239 | 240 | public String getName() { 241 | return mTitle; 242 | } 243 | 244 | public abstract void execute() throws SQLException; 245 | 246 | public void run() { 247 | 248 | long start = System.nanoTime(); 249 | mRepeat = mFactor * mBaseRepeat; 250 | try { 251 | execute(); 252 | } catch (SQLException ex) { 253 | System.err.println("Test " + getName() + " failed:"); 254 | System.err.println("SQLException: " + ex.getMessage()); 255 | System.err.println("SQLState: " + ex.getSQLState()); 256 | System.err.println("VendorError: " + ex.getErrorCode()); 257 | ex.printStackTrace(); 258 | } 259 | long end = System.nanoTime(); 260 | mResults.put(mTitle, new Result(mRepeat, end - start)); 261 | } 262 | } 263 | -------------------------------------------------------------------------------- /java/src/main/java/org/ciceron/sqlbenchmark/Main.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Main SQL Benchmark 3 | * Copyright (C) 2018 Stephane Carrez 4 | * Written by Stephane Carrez (Stephane.Carrez@gmail.com) 5 | * 6 | * Licensed to the Apache Software Foundation (ASF) under one 7 | * or more contributor license agreements. See the NOTICE file 8 | * distributed with this work for additional information 9 | * regarding copyright ownership. The ASF licenses this file 10 | * to you under the Apache License, Version 2.0 (the 11 | * "License"); you may not use this file except in compliance 12 | * with the License. You may obtain a copy of the License at 13 | * 14 | * http://www.apache.org/licenses/LICENSE-2.0 15 | * 16 | * Unless required by applicable law or agreed to in writing, 17 | * software distributed under the License is distributed on an 18 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 19 | * KIND, either express or implied. See the License for the 20 | * specific language governing permissions and limitations 21 | * under the License. 22 | */ 23 | package org.ciceron.sqlbenchmark; 24 | 25 | import java.io.IOException; 26 | import java.sql.SQLException; 27 | 28 | public class Main { 29 | 30 | private static void Usage() { 31 | System.err.println("Usage: java -jar sql-benchmark.jar [-sqlite|-mysql|-postgresql] [-repeat N] " 32 | + "[-o file]"); 33 | System.exit(2); 34 | } 35 | 36 | public static void main(String[] args) { 37 | String driver = "sqlite"; 38 | String output = ""; 39 | 40 | long repeat = 10; 41 | for (int i = 0; i < args.length; i++) { 42 | if ("-mysql".equals(args[i])) { 43 | driver = "mysql"; 44 | } else if ("-sqlite".equals(args[i])) { 45 | driver = "sqlite"; 46 | } else if ("-postgresql".equals(args[i])) { 47 | driver = "postgresql"; 48 | } else if ("-repeat".equals(args[i])) { 49 | i++; 50 | if (i == args.length) { 51 | System.err.println("Missing argument to -repeat option"); 52 | Usage(); 53 | } 54 | try { 55 | repeat = Long.parseLong(args[i]); 56 | } catch (NumberFormatException ex) { 57 | System.err.println("Repeat count is not a number"); 58 | Usage(); 59 | } 60 | } else if ("-o".equals(args[i])) { 61 | i++; 62 | if (i == args.length) { 63 | System.err.println("Missing argument to -repeat option"); 64 | Usage(); 65 | } 66 | output = args[i]; 67 | 68 | } else { 69 | Usage(); 70 | } 71 | } 72 | 73 | // Load the configuration file. 74 | try { 75 | Benchmark.loadConfiguration("sqlbench.properties"); 76 | } catch (IOException ex) { 77 | System.err.println("Cannot load sqlbench.properties file"); 78 | System.exit(1); 79 | } 80 | 81 | try { 82 | if (!Benchmark.setDatabase(driver)) { 83 | System.err.println("Cannot configure the database for driver: " + driver); 84 | System.exit(1); 85 | } 86 | Benchmark.setBaseRepeat(repeat); 87 | 88 | } catch (SQLException ex) { 89 | System.err.println("SQLException: " + ex.getMessage()); 90 | System.err.println("SQLState: " + ex.getSQLState()); 91 | System.err.println("VendorError: " + ex.getErrorCode()); 92 | System.exit(1); 93 | } 94 | try { 95 | Benchmark[] tests = Simple.Create(); 96 | 97 | for (Benchmark t : tests) { 98 | try { 99 | t.run(); 100 | 101 | } catch (Exception ex) { 102 | System.err.println("Test " + t.getName() + " failed:"); 103 | 104 | } 105 | } 106 | 107 | } catch (Exception e) { 108 | System.err.println(e); 109 | } 110 | 111 | try { 112 | Benchmark.printReport(output); 113 | } catch (IOException ex) { 114 | System.err.println(ex); 115 | System.exit(1); 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /java/src/main/java/org/ciceron/sqlbenchmark/Simple.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Simple SQL Benchmark 3 | * Copyright (C) 2018 Stephane Carrez 4 | * Written by Stephane Carrez (Stephane.Carrez@gmail.com) 5 | * 6 | * Licensed to the Apache Software Foundation (ASF) under one 7 | * or more contributor license agreements. See the NOTICE file 8 | * distributed with this work for additional information 9 | * regarding copyright ownership. The ASF licenses this file 10 | * to you under the Apache License, Version 2.0 (the 11 | * "License"); you may not use this file except in compliance 12 | * with the License. You may obtain a copy of the License at 13 | * 14 | * http://www.apache.org/licenses/LICENSE-2.0 15 | * 16 | * Unless required by applicable law or agreed to in writing, 17 | * software distributed under the License is distributed on an 18 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 19 | * KIND, either express or implied. See the License for the 20 | * specific language governing permissions and limitations 21 | * under the License. 22 | */ 23 | package org.ciceron.sqlbenchmark; 24 | 25 | import java.io.IOException; 26 | import java.nio.charset.StandardCharsets; 27 | import java.nio.file.Files; 28 | import java.nio.file.Paths; 29 | import java.sql.Connection; 30 | import java.sql.PreparedStatement; 31 | import java.sql.ResultSet; 32 | import java.sql.SQLException; 33 | import java.sql.Statement; 34 | 35 | public class Simple { 36 | 37 | private static String createSQL; 38 | 39 | public static Benchmark[] Create() throws IOException { 40 | 41 | byte[] encoded = Files.readAllBytes(Paths.get(Benchmark.getConfigPath("create-table.sql"))); 42 | createSQL = new String(encoded, StandardCharsets.UTF_8); 43 | 44 | if ("sqlite".equals(Benchmark.getDriverName())) { 45 | return new Benchmark[]{ 46 | new Select_Static(), 47 | new Connect_Select_Static(), 48 | new Drop_Create(), 49 | new Insert(), 50 | new Select_Table(1), 51 | new Select_Table(10), 52 | new Select_Table(100), 53 | new Select_Table(500), 54 | new Select_Table(1000) 55 | }; 56 | } 57 | if ("postgresql".equals(Benchmark.getDriverName())) { 58 | return new Benchmark[] { 59 | new Select_Static(), 60 | new Connect_Select_Static(), 61 | new Drop_Create(), 62 | new Insert(), 63 | new Select_Table(1), 64 | new Select_Table(10), 65 | new Select_Table(100), 66 | new Select_Table(500), 67 | new Select_Table(1000) 68 | }; 69 | } 70 | return new Benchmark[] { 71 | new Do_Static(), 72 | new Select_Static(), 73 | new Connect_Select_Static(), 74 | new Drop_Create(), 75 | new Insert(), 76 | new Select_Table(1), 77 | new Select_Table(10), 78 | new Select_Table(100), 79 | new Select_Table(500), 80 | new Select_Table(1000) 81 | }; 82 | } 83 | 84 | private static class Do_Static extends Benchmark { 85 | Do_Static() { 86 | super("DO 1"); 87 | } 88 | 89 | @Override 90 | public void execute() throws SQLException { 91 | Statement stmt = mConnection.createStatement(); 92 | 93 | for (int i = 0; i < mRepeat; i++) { 94 | stmt.execute("DO 1"); 95 | } 96 | stmt.close(); 97 | } 98 | } 99 | 100 | private static class Select_Static extends Benchmark { 101 | Select_Static() { 102 | super("SELECT 1"); 103 | } 104 | 105 | @Override 106 | public void execute() throws SQLException { 107 | Statement stmt = mConnection.createStatement(); 108 | 109 | for (int i = 0; i < mRepeat; i++) { 110 | stmt.execute("SELECT 1"); 111 | } 112 | stmt.close(); 113 | } 114 | } 115 | 116 | private static class Connect_Select_Static extends Benchmark { 117 | Connect_Select_Static() { 118 | super("CONNECT; SELECT 1; CLOSE"); 119 | } 120 | 121 | @Override 122 | public void execute() throws SQLException { 123 | 124 | for (int i = 0; i < mRepeat; i++) { 125 | Connection conn = mDataSource.getConnection(); 126 | Statement stmt = conn.createStatement(); 127 | stmt.execute("SELECT 1"); 128 | stmt.close(); 129 | conn.close(); 130 | } 131 | } 132 | } 133 | 134 | private static class Drop_Create extends Benchmark { 135 | Drop_Create() { 136 | super("DROP table; CREATE table", 1); 137 | } 138 | 139 | @Override 140 | public void execute() throws SQLException { 141 | 142 | for (int i = 0; i < mRepeat; i++) { 143 | Statement dropStmt = null; 144 | try { 145 | dropStmt = mConnection.createStatement(); 146 | dropStmt.execute("DROP TABLE IF EXISTS test_simple"); 147 | mConnection.commit(); 148 | } catch (SQLException ex) { 149 | 150 | } 151 | if (dropStmt != null) { 152 | dropStmt.close(); 153 | } 154 | Statement createStmt = mConnection.createStatement(); 155 | createStmt.execute(createSQL); 156 | createStmt.close(); 157 | mConnection.commit(); 158 | } 159 | } 160 | } 161 | 162 | private static class Insert extends Benchmark { 163 | Insert() { 164 | super("INSERT INTO table", 10); 165 | } 166 | 167 | @Override 168 | public void execute() throws SQLException { 169 | PreparedStatement insertStmt 170 | = mConnection.prepareStatement("INSERT INTO test_simple (value) VALUES (1)"); 171 | 172 | for (int i = 0; i < mRepeat; i++) { 173 | insertStmt.execute(); 174 | } 175 | insertStmt.close(); 176 | mConnection.commit(); 177 | } 178 | } 179 | 180 | private static class Select_Table extends Benchmark { 181 | private final int mExpectCount; 182 | 183 | Select_Table(int count) { 184 | super("SELECT * FROM table LIMIT " + count); 185 | mExpectCount = count; 186 | } 187 | 188 | @Override 189 | public void execute() throws SQLException { 190 | PreparedStatement stmt 191 | = mConnection.prepareStatement("SELECT * FROM test_simple LIMIT " + mExpectCount); 192 | 193 | for (int i = 0; i < mRepeat; i++) { 194 | if (stmt.execute()) { 195 | ResultSet rs = stmt.getResultSet(); 196 | int count = 0; 197 | while (rs.next()) { 198 | count++; 199 | } 200 | rs.close(); 201 | if (count != mExpectCount) { 202 | throw new SQLException("Invalid result count: " + count); 203 | } 204 | } else { 205 | throw new SQLException("No result"); 206 | } 207 | } 208 | stmt.close(); 209 | } 210 | } 211 | 212 | } 213 | -------------------------------------------------------------------------------- /java/src/test/java/org/ciceron/sqlbenchmark/AppTest.java: -------------------------------------------------------------------------------- 1 | package org.ciceron.sqlbenchmark; 2 | 3 | import junit.framework.Test; 4 | import junit.framework.TestCase; 5 | import junit.framework.TestSuite; 6 | 7 | /** 8 | * Unit test for simple Main. 9 | */ 10 | public class AppTest 11 | extends TestCase 12 | { 13 | /** 14 | * Create the test case 15 | * 16 | * @param testName name of the test case 17 | */ 18 | public AppTest( String testName ) 19 | { 20 | super( testName ); 21 | } 22 | 23 | /** 24 | * @return the suite of tests being tested 25 | */ 26 | public static Test suite() 27 | { 28 | return new TestSuite( AppTest.class ); 29 | } 30 | 31 | /** 32 | * Rigourous Test :-) 33 | */ 34 | public void testApp() 35 | { 36 | assertTrue( true ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /plot-memory.gpi: -------------------------------------------------------------------------------- 1 | set fit quiet 2 | reset 3 | set terminal pngcairo background "#ffffff" enhanced font "arial,16" fontscale 1.0 size 800,500 4 | set title textcolor rgb "blue" "Memory usage (RSS)" 5 | set ylabel "Memory in Kb" 6 | set xlabel "Driver" 7 | set key below 8 | # set style fill transparent solid 0.20 noborder 9 | set boxwidth 1 10 | set style fill solid 11 | set style data histograms 12 | 13 | # 85cbcf 14 | # 3984b6 15 | # 1d2e81 16 | plot "memory.dat" index 0 using 5:xtic(1) title "Ada" lc rgb "#3984b6", \ 17 | "memory.dat" index 1 using 5 title "Python" lc rgb "#1d2e81", \ 18 | "memory.dat" index 2 using 5 title "Java" lc rgb "#85cbcf" 19 | 20 | -------------------------------------------------------------------------------- /plot-mysql.gpi: -------------------------------------------------------------------------------- 1 | set fit quiet 2 | reset 3 | set terminal pngcairo background "#ffffff" enhanced font "arial,16" fontscale 1.0 size 800,500 4 | #set output benchmark.png 5 | set title textcolor rgb "blue" "MySQL: SELECT * FROM table LIMIT x" 6 | set ylabel "Time (us)" 7 | set xlabel "" 8 | set key below 9 | set style fill transparent solid 0.10 noborder 10 | plot \ 11 | "perf.dat" using 1:5 title "Java" with filledcurves x1 lc rgb "#85cbcf" fs transparent solid 1.0, \ 12 | "perf.dat" using 1:8 title "Python" with filledcurves x1 lc rgb "#1d2e81" fs transparent solid 1.0, \ 13 | "perf.dat" using 1:2 title "Ada" with filledcurves x1 lc rgb "#3984b6" fs transparent solid 1.0 14 | 15 | -------------------------------------------------------------------------------- /plot-postgresql.gpi: -------------------------------------------------------------------------------- 1 | set fit quiet 2 | reset 3 | set terminal pngcairo background "#ffffff" enhanced font "arial,16" fontscale 1.0 size 800,500 4 | #set output benchmark.png 5 | set title textcolor rgb "blue" "PostgreSQL: SELECT * FROM table LIMIT x" 6 | set ylabel "Time (us)" 7 | set xlabel "" 8 | set key below 9 | set style fill transparent solid 0.10 noborder 10 | plot \ 11 | "perf.dat" using 1:9 title "Python" with filledcurves x1 lc rgb "#1d2e81" fs transparent solid 1.0, \ 12 | "perf.dat" using 1:6 title "Java" with filledcurves x1 lc rgb "#85cbcf" fs transparent solid 1.0, \ 13 | "perf.dat" using 1:3 title "Ada" with filledcurves x1 lc rgb "#3984b6" fs transparent solid 1.0 14 | 15 | -------------------------------------------------------------------------------- /plot-sqlite.gpi: -------------------------------------------------------------------------------- 1 | set fit quiet 2 | reset 3 | set terminal pngcairo background "#ffffff" enhanced font "arial,16" fontscale 1.0 size 800,500 4 | #set output benchmark.png 5 | set title textcolor rgb "blue" "SQLite: SELECT * FROM table LIMIT x" 6 | set ylabel "Time (us)" 7 | set xlabel "" 8 | set key below 9 | set style fill transparent solid 0.10 noborder 10 | plot \ 11 | "perf.dat" using 1:10 title "Python" with filledcurves x1 lc rgb "#1d2e81" fs transparent solid 1, \ 12 | "perf.dat" using 1:4 title "Ada" with filledcurves x1 lc rgb "#3984b6" fs transparent solid 0.8,\ 13 | "perf.dat" using 1:7 title "Java" with filledcurves x1 lc rgb "#85cbcf" fs transparent solid 0.6 14 | 15 | -------------------------------------------------------------------------------- /plot-user-time.gpi: -------------------------------------------------------------------------------- 1 | set fit quiet 2 | reset 3 | set terminal pngcairo background "#ffffff" enhanced font "arial,16" fontscale 1.0 size 800,500 4 | set title textcolor rgb "blue" "CPU user time" 5 | set ylabel "Time (s)" 6 | set xlabel "Driver" 7 | set key below 8 | # set style fill transparent solid 0.20 noborder 9 | set boxwidth 1 10 | set style fill solid 11 | set style data histograms 12 | 13 | # 85cbcf 14 | # 3984b6 15 | # 1d2e81 16 | plot "memory.dat" index 0 using ($3/1000):xtic(1) title "Ada" lc rgb "#3984b6", \ 17 | "memory.dat" index 1 using ($3/1000) title "Python" lc rgb "#1d2e81", \ 18 | "memory.dat" index 2 using ($3/1000) title "Java" lc rgb "#85cbcf" 19 | 20 | -------------------------------------------------------------------------------- /python/README.md: -------------------------------------------------------------------------------- 1 | ## Requisites 2 | 3 | You must use Python3 to run the benchmarks and install the PostgreSQL support. 4 | 5 | ``` 6 | sudo apt-get install python3-psycopg2 7 | ``` 8 | 9 | ``` 10 | sudo apt-get install python3-mysqldb 11 | ``` 12 | 13 | ## Run 14 | 15 | MySQL 16 | ``` 17 | python3 src -mysql -r 100 18 | ``` 19 | 20 | PostgreSQL 21 | ``` 22 | python3 src -postgresql -r 100 23 | ``` 24 | 25 | SQLite 26 | ``` 27 | python3 src -sqlite -r 100 28 | ``` 29 | 30 | -------------------------------------------------------------------------------- /python/config: -------------------------------------------------------------------------------- 1 | ../ado/config -------------------------------------------------------------------------------- /python/sqlbench.properties: -------------------------------------------------------------------------------- 1 | ado.queries.load=true 2 | ado.queries.paths=db 3 | ado.drivers.load=false 4 | 5 | mysql.database=mysql://localhost:3306/sqlbench?user=sqlbench&encoding=utf8 6 | postgresql.database=postgresql://localhost:5432/sqlbench?user=sqlbench&password=sqlbench 7 | sqlite.database=jdbc:sqlite:sqlbench.db 8 | 9 | -------------------------------------------------------------------------------- /python/src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcarrez/sql-benchmark/52fa205c799c18c6458615b761ab613d1dd22c53/python/src/__init__.py -------------------------------------------------------------------------------- /python/src/__main__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | SQL Benchmark tests 4 | """ 5 | __author__ = "Stephane Carrez" 6 | __copyright__ = "Copyright (C) 2018 Stephane Carrez" 7 | __license__ = 'Apache License, Version 2.0' 8 | 9 | import argparse 10 | import benchmark 11 | import sqlite_benchmark 12 | import sqlite_simple 13 | import postgresql_benchmark 14 | import postgresql_simple 15 | import mysql_benchmark 16 | import mysql_simple 17 | import sys 18 | 19 | parser = argparse.ArgumentParser(description='SQL Benchmark') 20 | parser.add_argument('-repeat', dest='repeat', help='Repeat counter', type=int) 21 | parser.add_argument('-sqlite', help='Run the SQLite benchmarks', action="store_true") 22 | parser.add_argument('-postgresql', help='Run the PostgreSQL benchmarks', action="store_true") 23 | parser.add_argument('-mysql', help='Run the Mysql benchmarks', action="store_true") 24 | parser.add_argument('-o', dest='output', help='Write the result in the file') 25 | 26 | if __name__ == '__main__': 27 | 28 | result = parser.parse_args() 29 | benchmark.Benchmark.read_config("sqlbench.properties") 30 | if result.repeat: 31 | benchmark.Benchmark._repeat_base = result.repeat 32 | 33 | if result.sqlite: 34 | sqlite_benchmark.SQLiteBenchmark.setup() 35 | tests = sqlite_simple.create() 36 | 37 | if result.postgresql: 38 | postgresql_benchmark.PostgreSQLBenchmark.setup() 39 | tests = postgresql_simple.create() 40 | 41 | if result.mysql: 42 | mysql_benchmark.MysqlBenchmark.setup() 43 | tests = mysql_simple.create() 44 | 45 | if not tests: 46 | print("Missing -sqlite, -postgresql or -mysql option", file=sys.stderr) 47 | sys.exit(1) 48 | 49 | for test in tests: 50 | test.run() 51 | 52 | if result.output: 53 | sys.stdout = open(result.output, 'w') 54 | 55 | benchmark.Benchmark.print_report() 56 | -------------------------------------------------------------------------------- /python/src/benchmark.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | Benchmark class 4 | """ 5 | __author__ = "Stephane Carrez" 6 | __copyright__ = "Copyright (C) 2018 Stephane Carrez" 7 | __license__ = 'Apache License, Version 2.0' 8 | 9 | import time 10 | import traceback 11 | import configparser 12 | 13 | """ 14 | Benchmark context information. 15 | 16 | This class collects benchmark information in static properties and provides 17 | operations to print the final results in XML. 18 | """ 19 | class Benchmark: 20 | """ 21 | The results collected when running the benchmark. 22 | """ 23 | _results = {} 24 | 25 | """ 26 | The name of the database driver used to run the benchmark. 27 | """ 28 | _driver = '' 29 | 30 | """ 31 | The configuration properties. 32 | """ 33 | _config = {} 34 | 35 | """ 36 | The base repeat counter configured with -r option. 37 | """ 38 | _repeat_base = 10 39 | 40 | def __init__(self): 41 | self.repeat_factor = 100 42 | 43 | @staticmethod 44 | def read_config(path): 45 | try: 46 | with open(path) as f: 47 | for line in f: 48 | l = line.strip() 49 | if l and not l.startswith('#'): 50 | items = l.split('=') 51 | if len(items) > 0: 52 | name = items[0].strip() 53 | value = '='.join(items[1:]).strip().strip('"') 54 | Benchmark._config[name] = value 55 | except: 56 | print("Cannot read {0}".format(path)) 57 | 58 | @staticmethod 59 | def read_process_info(): 60 | thread_count = 0 61 | rss_size = 0 62 | hwm_size = 0 63 | sys_time = 0 64 | user_time = 0 65 | try: 66 | with open("/proc/self/status") as f: 67 | for line in f: 68 | line = line.strip() 69 | items = line.split() 70 | if line.startswith("Threads:") and len(items) > 0: 71 | thread_count = int(items[1]) 72 | elif line.startswith("VmRSS:") and len(items) > 0: 73 | rss_size = int(items[1]) 74 | elif line.startswith("VmHWM:") and len(items) > 0: 75 | hwm_size = int(items[1]) 76 | except: 77 | pass 78 | 79 | try: 80 | with open("/proc/self/stat") as f: 81 | for line in f: 82 | line = line.strip() 83 | items = line.split() 84 | if len(items) > 17: 85 | user_time = 10 * int(items[13]) 86 | sys_time = 10 * int(items[14]) 87 | except: 88 | pass 89 | 90 | print("") 95 | 96 | @staticmethod 97 | def format_time(t): 98 | us = int(t * 1000000.0) 99 | ms = int(us / 1000) 100 | if ms > 1000: 101 | sec = int(ms / 1000) 102 | ms = ms % 1000 103 | return "{0}.{1:03d} s".format(sec, ms) 104 | if ms > 100: 105 | us = us % 1000 106 | return "{0}.{1} ms".format(ms, int(us / 100)) 107 | if ms > 10: 108 | us = us % 1000 109 | return "{0}.{1:02d} ms".format(ms, int(us / 10)) 110 | if ms > 1: 111 | us = us % 1000 112 | return "{0}.{1:03d} ms".format(ms, us) 113 | return "{0} us".format(us) 114 | 115 | @staticmethod 116 | def print_report(): 117 | Benchmark.read_process_info() 118 | print("") 119 | for title, result in Benchmark._results.items(): 120 | t = result['time'] 121 | n = result['repeat'] 122 | print("") 125 | print("") 126 | 127 | def repeat(self): 128 | return Benchmark._repeat_base * self.repeat_factor 129 | 130 | def run(self): 131 | repeat = self.repeat() 132 | 133 | start = time.time() 134 | try: 135 | self.execute() 136 | except Exception as ex: 137 | print("Exception: ") 138 | print(ex) 139 | traceback.print_exc() 140 | 141 | end = time.time() 142 | dt = end - start 143 | Benchmark._results[self.title] = { 'repeat': repeat, 'time': dt } 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /python/src/mysql_benchmark.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | Mysql Benchmark class 4 | """ 5 | __author__ = "Stephane Carrez" 6 | __copyright__ = "Copyright (C) 2018 Stephane Carrez" 7 | __license__ = 'Apache License, Version 2.0' 8 | 9 | import benchmark 10 | import MySQLdb 11 | import urllib.parse 12 | 13 | """ 14 | Mysql Benchmark 15 | """ 16 | class MysqlBenchmark(benchmark.Benchmark): 17 | _databaseUri = '' 18 | _database = '' 19 | _hostname = 'localhost' 20 | _port = 3306 21 | _dbname = '' 22 | _username = '' 23 | _password = '' 24 | 25 | @staticmethod 26 | def setup(): 27 | database = benchmark.Benchmark._config.get('mysql.database') 28 | if not database: 29 | raise Exception("Missing 'mysql.database' configuration") 30 | if database.startswith("jdbc:mysql:"): 31 | database = database[11:] 32 | l = urllib.parse.urlparse(database) 33 | benchmark.Benchmark._driver = l.scheme 34 | MysqlBenchmark._hostname = l.hostname 35 | MysqlBenchmark._port = l.port 36 | MysqlBenchmark._dbname = l.path[1:] 37 | 38 | query = urllib.parse.parse_qs(l.query) 39 | value = query.get('user') 40 | if value: 41 | MysqlBenchmark._username = value[0] 42 | 43 | value = query.get('password') 44 | if value: 45 | MysqlBenchmark._password = value[0] 46 | 47 | MysqlBenchmark._database = MySQLdb.connect(host=MysqlBenchmark._hostname, 48 | port=MysqlBenchmark._port, 49 | user=MysqlBenchmark._username, 50 | passwd=MysqlBenchmark._password, 51 | db=MysqlBenchmark._dbname) 52 | 53 | def connection(self): 54 | return MysqlBenchmark._database 55 | 56 | def newConnection(self): 57 | return MySQLdb.connect(host=MysqlBenchmark._hostname, 58 | port=MysqlBenchmark._port, 59 | user=MysqlBenchmark._username, 60 | passwd=MysqlBenchmark._password, 61 | db=MysqlBenchmark._dbname) 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /python/src/mysql_simple.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | Mysql Benchmark tests 4 | """ 5 | __author__ = "Stephane Carrez" 6 | __copyright__ = "Copyright (C) 2018 Stephane Carrez" 7 | __license__ = 'Apache License, Version 2.0' 8 | 9 | import MySQLdb 10 | import mysql_benchmark 11 | 12 | class DoStatic(mysql_benchmark.MysqlBenchmark): 13 | def __init__(self): 14 | super().__init__() 15 | self.title = "DO 1" 16 | 17 | def execute(self): 18 | repeat = self.repeat() 19 | db = self.connection() 20 | stmt = db.cursor() 21 | 22 | for i in range(0, repeat): 23 | stmt.execute("DO 1") 24 | stmt.close() 25 | 26 | class SelectStatic(mysql_benchmark.MysqlBenchmark): 27 | def __init__(self): 28 | super().__init__() 29 | self.title = "SELECT 1" 30 | 31 | def execute(self): 32 | repeat = self.repeat() 33 | db = self.connection() 34 | stmt = db.cursor() 35 | 36 | for i in range(0, repeat): 37 | stmt.execute("SELECT 1") 38 | stmt.close() 39 | 40 | class ConnectSelectStatic(mysql_benchmark.MysqlBenchmark): 41 | def __init__(self): 42 | super().__init__() 43 | self.title = "CONNECT; SELECT 1; CLOSE" 44 | 45 | def execute(self): 46 | repeat = self.repeat() 47 | 48 | for i in range(0, repeat): 49 | db = self.newConnection() 50 | stmt = db.cursor() 51 | stmt.execute("SELECT 1") 52 | stmt.close() 53 | db.close() 54 | 55 | class DropCreate(mysql_benchmark.MysqlBenchmark): 56 | def __init__(self): 57 | super().__init__() 58 | self.title = "DROP table; CREATE table" 59 | self.repeat_factor = 1 60 | with open('config/mysql-create-table.sql') as f: 61 | self.create_sql = f.read() 62 | 63 | def execute(self): 64 | repeat = self.repeat() 65 | db = self.connection() 66 | drop_stmt = db.cursor() 67 | create_stmt = db.cursor() 68 | 69 | for i in range(0, repeat): 70 | try: 71 | drop_stmt.execute("DROP TABLE test_simple") 72 | db.commit() 73 | except: 74 | pass 75 | 76 | create_stmt.execute(self.create_sql) 77 | db.commit() 78 | 79 | drop_stmt.close() 80 | create_stmt.close() 81 | 82 | class Insert(mysql_benchmark.MysqlBenchmark): 83 | def __init__(self): 84 | super().__init__() 85 | self.title = "INSERT INTO table" 86 | self.repeat_factor = 10 87 | 88 | def execute(self): 89 | repeat = self.repeat() 90 | db = self.connection() 91 | stmt = db.cursor() 92 | 93 | for i in range(0, repeat): 94 | stmt.execute("INSERT INTO test_simple (value) VALUES (1)") 95 | 96 | stmt.close() 97 | db.commit() 98 | 99 | class SelectTable(mysql_benchmark.MysqlBenchmark): 100 | def __init__(self, count): 101 | super().__init__() 102 | self.title = "SELECT * FROM table LIMIT " + str(count) 103 | self.sql = "SELECT * FROM test_simple LIMIT " + str(count) 104 | self.expect_count = count 105 | 106 | def execute(self): 107 | repeat = self.repeat() 108 | db = self.connection() 109 | stmt = db.cursor() 110 | 111 | for i in range(0, repeat): 112 | stmt.execute(self.sql) 113 | row_count = 0 114 | for row in stmt: 115 | row_count = row_count + 1 116 | 117 | if row_count != self.expect_count: 118 | raise Exception('Invalid result count:' + str(row_count)) 119 | 120 | stmt.close() 121 | 122 | def create(): 123 | s = SelectStatic() 124 | return [DoStatic(), SelectStatic(), ConnectSelectStatic(), DropCreate(), Insert(), 125 | SelectTable(1), SelectTable(10), SelectTable(100), SelectTable(500), SelectTable(1000)] 126 | 127 | -------------------------------------------------------------------------------- /python/src/postgresql_benchmark.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | PostgreSQL Benchmark class 4 | """ 5 | __author__ = "Stephane Carrez" 6 | __copyright__ = "Copyright (C) 2018 Stephane Carrez" 7 | __license__ = 'Apache License, Version 2.0' 8 | 9 | import benchmark 10 | import psycopg2 11 | 12 | """ 13 | PostgreSQL Benchmark 14 | """ 15 | class PostgreSQLBenchmark(benchmark.Benchmark): 16 | _databaseUri = '' 17 | _database = '' 18 | 19 | @staticmethod 20 | def setup(): 21 | database = benchmark.Benchmark._config.get('postgresql.database') 22 | if not database: 23 | raise Exception("Missing 'postgresql.database' configuration") 24 | if database.startswith("jdbc:sqlite:"): 25 | database = database[12:] 26 | benchmark.Benchmark._driver = 'postgresql' 27 | PostgreSQLBenchmark._databaseUri = database 28 | PostgreSQLBenchmark._database = psycopg2.connect(database) 29 | 30 | def connection(self): 31 | return PostgreSQLBenchmark._database 32 | 33 | def newConnection(self): 34 | return psycopg2.connect(PostgreSQLBenchmark._databaseUri) 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /python/src/postgresql_simple.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | PostgreSQL Benchmark tests 4 | """ 5 | __author__ = "Stephane Carrez" 6 | __copyright__ = "Copyright (C) 2018 Stephane Carrez" 7 | __license__ = 'Apache License, Version 2.0' 8 | 9 | import psycopg2 10 | import postgresql_benchmark 11 | 12 | class SelectStatic(postgresql_benchmark.PostgreSQLBenchmark): 13 | def __init__(self): 14 | super().__init__() 15 | self.title = "SELECT 1" 16 | 17 | def execute(self): 18 | repeat = self.repeat() 19 | db = self.connection() 20 | stmt = db.cursor() 21 | 22 | for i in range(0, repeat): 23 | stmt.execute("SELECT 1") 24 | 25 | class ConnectSelectStatic(postgresql_benchmark.PostgreSQLBenchmark): 26 | def __init__(self): 27 | super().__init__() 28 | self.title = "CONNECT; SELECT 1; CLOSE" 29 | 30 | def execute(self): 31 | repeat = self.repeat() 32 | 33 | for i in range(0, repeat): 34 | db = self.newConnection() 35 | stmt = db.cursor() 36 | stmt.execute("SELECT 1") 37 | db.close() 38 | 39 | class DropCreate(postgresql_benchmark.PostgreSQLBenchmark): 40 | def __init__(self): 41 | super().__init__() 42 | self.title = "DROP table; CREATE table" 43 | self.repeat_factor = 1 44 | with open('config/postgresql-create-table.sql') as f: 45 | self.create_sql = f.read() 46 | 47 | def execute(self): 48 | repeat = self.repeat() 49 | db = self.connection() 50 | 51 | for i in range(0, repeat): 52 | stmt = db.cursor() 53 | try: 54 | stmt.execute("DROP TABLE test_simple") 55 | db.commit() 56 | except: 57 | db.rollback() 58 | 59 | stmt.execute(self.create_sql) 60 | db.commit() 61 | 62 | class Insert(postgresql_benchmark.PostgreSQLBenchmark): 63 | def __init__(self): 64 | super().__init__() 65 | self.title = "INSERT INTO table" 66 | self.repeat_factor = 10 67 | 68 | def execute(self): 69 | repeat = self.repeat() 70 | db = self.connection() 71 | stmt = db.cursor() 72 | 73 | for i in range(0, repeat): 74 | stmt.execute("INSERT INTO test_simple (value) VALUES (1)") 75 | db.commit() 76 | 77 | class SelectTable(postgresql_benchmark.PostgreSQLBenchmark): 78 | def __init__(self, count): 79 | super().__init__() 80 | self.title = "SELECT * FROM table LIMIT " + str(count) 81 | self.sql = "SELECT * FROM test_simple LIMIT " + str(count) 82 | self.expect_count = count 83 | 84 | def execute(self): 85 | repeat = self.repeat() 86 | db = self.connection() 87 | stmt = db.cursor() 88 | 89 | for i in range(0, repeat): 90 | stmt.execute(self.sql) 91 | row_count = 0 92 | for row in stmt: 93 | row_count = row_count + 1 94 | 95 | if row_count != self.expect_count: 96 | raise Exception('Invalid result count:' + str(row_count)) 97 | 98 | def create(): 99 | s = SelectStatic() 100 | return [SelectStatic(), ConnectSelectStatic(), DropCreate(), Insert(), 101 | SelectTable(1), SelectTable(10), SelectTable(100), SelectTable(500), SelectTable(1000)] 102 | 103 | -------------------------------------------------------------------------------- /python/src/sqlite_benchmark.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | SQLite Benchmark class 4 | """ 5 | __author__ = "Stephane Carrez" 6 | __copyright__ = "Copyright (C) 2018 Stephane Carrez" 7 | __license__ = 'Apache License, Version 2.0' 8 | 9 | import benchmark 10 | import sqlite3 11 | 12 | """ 13 | SQLite Benchmark 14 | """ 15 | class SQLiteBenchmark(benchmark.Benchmark): 16 | _databaseUri = '' 17 | _database = '' 18 | 19 | @staticmethod 20 | def setup(): 21 | database = benchmark.Benchmark._config.get('sqlite.database') 22 | if not database: 23 | raise Exception("Missing 'sqlite.database' configuration") 24 | if database.startswith("jdbc:sqlite:"): 25 | database = database[12:] 26 | benchmark.Benchmark._driver = 'sqlite' 27 | SQLiteBenchmark._databaseUri = database 28 | SQLiteBenchmark._database = sqlite3.connect(database) 29 | 30 | def connection(self): 31 | return SQLiteBenchmark._database 32 | 33 | def newConnection(self): 34 | return sqlite3.connect(SQLiteBenchmark._databaseUri) 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /python/src/sqlite_simple.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | SQLite Benchmark tests 4 | """ 5 | __author__ = "Stephane Carrez" 6 | __copyright__ = "Copyright (C) 2018 Stephane Carrez" 7 | __license__ = 'Apache License, Version 2.0' 8 | 9 | import sqlite3 10 | import sqlite_benchmark 11 | 12 | class SelectStatic(sqlite_benchmark.SQLiteBenchmark): 13 | def __init__(self): 14 | super().__init__() 15 | self.title = "SELECT 1" 16 | 17 | def execute(self): 18 | repeat = self.repeat() 19 | db = self.connection() 20 | stmt = db.cursor() 21 | 22 | for i in range(0, repeat): 23 | stmt.execute("SELECT 1") 24 | 25 | class ConnectSelectStatic(sqlite_benchmark.SQLiteBenchmark): 26 | def __init__(self): 27 | super().__init__() 28 | self.title = "CONNECT; SELECT 1; CLOSE" 29 | 30 | def execute(self): 31 | repeat = self.repeat() 32 | 33 | for i in range(0, repeat): 34 | db = self.newConnection() 35 | stmt = db.cursor() 36 | stmt.execute("SELECT 1") 37 | db.close() 38 | 39 | class DropCreate(sqlite_benchmark.SQLiteBenchmark): 40 | def __init__(self): 41 | super().__init__() 42 | self.title = "DROP table; CREATE table" 43 | self.repeat_factor = 1 44 | with open('config/sqlite-create-table.sql') as f: 45 | self.create_sql = f.read() 46 | 47 | def execute(self): 48 | repeat = self.repeat() 49 | db = self.connection() 50 | 51 | for i in range(0, repeat): 52 | stmt = db.cursor() 53 | try: 54 | stmt.execute("DROP TABLE test_simple") 55 | db.commit() 56 | except: 57 | pass 58 | 59 | stmt.execute(self.create_sql) 60 | db.commit() 61 | 62 | class Insert(sqlite_benchmark.SQLiteBenchmark): 63 | def __init__(self): 64 | super().__init__() 65 | self.title = "INSERT INTO table" 66 | self.repeat_factor = 10 67 | 68 | def execute(self): 69 | repeat = self.repeat() 70 | db = self.connection() 71 | stmt = db.cursor() 72 | 73 | for i in range(0, repeat): 74 | stmt.execute("INSERT INTO test_simple (value) VALUES (1)") 75 | db.commit() 76 | 77 | class SelectTable(sqlite_benchmark.SQLiteBenchmark): 78 | def __init__(self, count): 79 | super().__init__() 80 | self.title = "SELECT * FROM table LIMIT " + str(count) 81 | self.sql = "SELECT * FROM test_simple LIMIT " + str(count) 82 | self.expect_count = count 83 | 84 | def execute(self): 85 | repeat = self.repeat() 86 | db = self.connection() 87 | stmt = db.cursor() 88 | 89 | for i in range(0, repeat): 90 | stmt.execute(self.sql) 91 | row_count = 0 92 | for row in stmt: 93 | row_count = row_count + 1 94 | 95 | if row_count != self.expect_count: 96 | raise Exception('Invalid result count:' + str(row_count)) 97 | 98 | def create(): 99 | s = SelectStatic() 100 | return [SelectStatic(), ConnectSelectStatic(), DropCreate(), Insert(), 101 | SelectTable(1), SelectTable(10), SelectTable(100), SelectTable(500), SelectTable(1000)] 102 | 103 | -------------------------------------------------------------------------------- /run-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | PASS=1 5 | REPEAT=100 6 | 7 | usage() { 8 | echo "Usage: run-all.sh [-repeat N] [-pass num]" 9 | exit 2 10 | } 11 | 12 | while test $# -ne 0; do 13 | case $1 in 14 | -repeat) 15 | shift 16 | test $# -eq 0 && usage 17 | REPEAT=$1 18 | ;; 19 | 20 | -pass) 21 | shift 22 | test $# -eq 0 && usage 23 | PASS=$1 24 | ;; 25 | 26 | *) 27 | usage 28 | ;; 29 | esac 30 | shift 31 | done 32 | 33 | LANGUAGES="ado java python" 34 | DATABASES="sqlite mysql postgresql" 35 | 36 | # Check SQL benchmark programs are built. 37 | for L in $LANGUAGES; do 38 | case $L in 39 | ado) 40 | if test ! -f ado/bin/sqlbench; then 41 | echo "Please, build Ada SQL benchmark by running:" 42 | echo "cd ado && ./configure && make" 43 | exit 2 44 | fi 45 | ;; 46 | 47 | java) 48 | if test ! -f java/target/sql-benchmark-1.0.jar; then 49 | echo "Please, build Java SQL benchmark by running:" 50 | echo "cd java && mvn compile assembly:single" 51 | exit 2 52 | fi 53 | ;; 54 | 55 | python) 56 | ;; 57 | 58 | *) 59 | echo "Invalid language $L" 60 | exit 2; 61 | ;; 62 | esac 63 | done 64 | 65 | if test ! -f tools/bin/tool-main; then 66 | echo "Please, build the SQL benchmark aggrgation tool:" 67 | echo "cd tools && ./configure && make" 68 | exit 2 69 | fi 70 | 71 | mkdir -p results 72 | 73 | DIR=`pwd` 74 | FAIL=0 75 | FILES="" 76 | for D in $DATABASES; do 77 | 78 | for L in $LANGUAGES; do 79 | 80 | echo "Running SQL benchmark on $D for $L" 81 | case $L in 82 | ado) 83 | cd $DIR/ado && bin/sqlbench -$D -repeat $REPEAT -o ../results/$L-$D-$PASS.xml 84 | if test $? -ne 0; then 85 | echo "Execution of SQL benchmark on $D for $L failed" 86 | FAIL=1 87 | fi 88 | FILES="$FILES results/$L-$D-$PASS.xml" 89 | ;; 90 | 91 | java) 92 | cd $DIR/java && java -jar target/sql-benchmark-1.0.jar -$D -repeat $REPEAT -o ../results/$L-$D-$PASS.xml 93 | if test $? -ne 0; then 94 | echo "Execution of SQL benchmark on $D for $L failed" 95 | FAIL=1 96 | fi 97 | FILES="$FILES results/$L-$D-$PASS.xml" 98 | ;; 99 | 100 | python) 101 | cd $DIR/python && python3 src -$D -repeat $REPEAT -o ../results/$L-$D-$PASS.xml 102 | if test $? -ne 0; then 103 | echo "Execution of SQL benchmark on $D for $L failed" 104 | FAIL=1 105 | fi 106 | FILES="$FILES results/$L-$D-$PASS.xml" 107 | ;; 108 | 109 | *) 110 | ;; 111 | esac 112 | done 113 | 114 | done 115 | 116 | echo "Building the results" 117 | cd $DIR && tools/bin/tool-main $FILES 118 | 119 | -------------------------------------------------------------------------------- /sql-benchmark-results.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcarrez/sql-benchmark/52fa205c799c18c6458615b761ab613d1dd22c53/sql-benchmark-results.xls -------------------------------------------------------------------------------- /tools/Makefile.in: -------------------------------------------------------------------------------- 1 | NAME=tool 2 | 3 | # You may edit this makefile as long as you keep these original 4 | # target names defined. 5 | MODE=debug 6 | GNATMAKE=@GNATMAKE@ 7 | GNATCLEAN=gnatclean 8 | SVN=svn 9 | INSTALL=@INSTALL@ 10 | DYNAMO=dynamo 11 | LN_S=@LN_S@ 12 | MKDIR=mkdir 13 | CP=cp 14 | LN=ln -s 15 | 16 | GPRPATH:=${NAME}.gpr 17 | 18 | 19 | 20 | distdir=tool-@TOOL_VERSION@ 21 | 22 | DIST_FILE=tool-@TOOL_VERSION@.tar.gz 23 | 24 | 25 | srcdir = . 26 | bindir = @bindir@ 27 | sbindir = @sbindir@ 28 | top_srcdir = @top_srcdir@ 29 | VPATH = @srcdir@ 30 | prefix = @prefix@ 31 | exec_prefix = @exec_prefix@ 32 | top_builddir = . 33 | dynamodir=${prefix}/share/dynamo 34 | includedir=${prefix}/share/ada/adainclude 35 | projectdir=${prefix}/share/ada/adainclude 36 | bindir=${prefix}/bin 37 | libdir=${prefix}/lib 38 | alidir=${libdir}/ada/adalib/ 39 | 40 | MAKE_ARGS=-XMODE=${MODE} 41 | 42 | all: build 43 | 44 | # Build executables for all mains defined by the project. 45 | build: 46 | test ! -f $(GPRPATH) || $(GNATMAKE) -m -p -P "$(GPRPATH)" $(MAKE_ARGS) 47 | 48 | # Not intended for manual invocation. 49 | # Invoked if automatic builds are enabled. 50 | # Analyzes only on those sources that have changed. 51 | # Does not build executables. 52 | autobuild: 53 | $(GNATMAKE) -gnatc -c -k -P "$(GPRPATH)" 54 | 55 | # Clean the root project of all build products. 56 | clean: 57 | -$(GNATCLEAN) -q -P "$(GPRPATH)" 58 | -rm -rf $(distdir) 59 | 60 | # Clean root project and all imported projects too. 61 | clean_tree: 62 | $(GNATCLEAN) -P "$(GPRPATH)" -r 63 | 64 | # Check *all* sources for errors, even those not changed. 65 | # Does not build executables. 66 | analyze: 67 | $(GNATMAKE) -f -gnatc -c -k -P "$(GPRPATH)" 68 | 69 | # Clean, then build executables for all mains defined by the project. 70 | rebuild: clean build 71 | 72 | # Rebuild the generated model files 73 | generate: 74 | $(DYNAMO) generate db 75 | 76 | install: uninstall 77 | $(INSTALL) bin/${NAME} $(prefix)/bin/${NAME} 78 | 79 | uninstall: 80 | rm -f ${bindir}/${NAME} 81 | -------------------------------------------------------------------------------- /tools/aclocal.m4: -------------------------------------------------------------------------------- 1 | dnl Check if we are running under Windows with msys to use pwd -W which produces Windows paths such as d:/tool instead of /d/tool 2 | AC_DEFUN(AM_CHECK_HOST_PWD, 3 | [ 4 | if test x${awa_host_pwd_check} != xyes; then 5 | AC_CHECK_PROG(awa_has_msys, msysinfo, yes, no) 6 | if test x${awa_has_msys} = xyes; then 7 | awa_pwd_option="-W" 8 | else 9 | awa_pwd_option="" 10 | fi 11 | awa_host_pwd_check=yes 12 | fi 13 | ]) 14 | 15 | # Check whether we can use gprbuild or gnatmake 16 | AC_DEFUN(AM_GNAT_CHECK_GPRBUILD, 17 | [ 18 | AC_CHECK_PROGS(GPRBUILD, gprbuild, "") 19 | if test -n "$GPRBUILD"; then 20 | GNATMAKE="$GPRBUILD" 21 | else 22 | AC_CHECK_PROGS(GNATMAKE, gnatmake, "") 23 | fi 24 | 25 | if test -z "$GNATMAKE"; then 26 | AC_MSG_ERROR([gnatmake or gprbuild must be installed.]) 27 | fi; 28 | 29 | AC_CHECK_PROGS(GPRCLEAN, gprclean, "") 30 | if test -n "$GPRCLEAN"; then 31 | GNATCLEAN="$GPRCLEAN" 32 | else 33 | AC_CHECK_PROGS(GNATCLEAN, gnatclean, "") 34 | fi 35 | 36 | AC_CHECK_PROGS(GPRINSTALL, gprinstall, "") 37 | ]) 38 | 39 | # Check if a GNAT project is available. 40 | # dnl AM_GNAT_CHECK_PROJECT([name],[path]) 41 | AC_DEFUN(AM_GNAT_CHECK_PROJECT, 42 | [ 43 | AC_CACHE_CHECK([whether $1 project exists],[ac_cv_gnat_project_$1],[ 44 | echo "with \"$2\"; project conftest is for Source_Dirs use (); end conftest;" > conftest.gpr 45 | if AC_TRY_COMMAND([gnat ls -Pconftest.gpr system.ads > /dev/null 2>conftest.out]) 46 | then 47 | ac_cv_gnat_project_$1=yes 48 | ac_cv_gnat_project_with_$1="with \"$2\";"; 49 | else 50 | ac_cv_gnat_project_$1=no 51 | fi 52 | rm -f conftest.gpr]) 53 | ]) 54 | 55 | # Check if a GNAT project is available. 56 | # AM_GNAT_FIND_PROJECT([ada-util],[Ada Utility Library],[util],[link],[code-fail],[code-ok]) 57 | AC_DEFUN(AM_GNAT_FIND_PROJECT, 58 | [ 59 | AC_ARG_WITH($1, 60 | AS_HELP_STRING([--with-$1=x], [Path for $2]), 61 | [ 62 | if test "${withval}/" = "yes/"; then 63 | ac_cv_gnat_project_name_$3=${awa_build_root}$3 64 | else 65 | ac_cv_gnat_project_name_$3=${withval}/ 66 | if test -d "${withval}"; then 67 | ac_cv_gnat_project_name_$3=${withval}/$3 68 | fi 69 | fi 70 | ], 71 | [ 72 | ac_cv_gnat_project_name_$3=${awa_build_root}$3 73 | ]) 74 | 75 | AC_CACHE_CHECK([$2],[ac_cv_gnat_project_$3],[ 76 | rm -f conftest.gpr 77 | # Search in the GNAT project path. 78 | echo "with \"${ac_cv_gnat_project_name_$3}\"; project conftest is for Source_Dirs use (); end conftest;" > conftest.gpr 79 | if AC_TRY_COMMAND([gnat ls -Pconftest.gpr system.ads > /dev/null 2>conftest.out]) 80 | then 81 | ac_cv_gnat_project_$3=yes 82 | else 83 | ac_cv_gnat_project_$3=no 84 | 85 | # Search in ../$1-*/$3.gpr 86 | dir=`cd .. && pwd ${awa_pwd_option}` 87 | files=`ls -r $dir/$1/$3.gpr $dir/$3/$3.gpr $dir/$1-*/$3.gpr 2>/dev/null` 88 | for name in $files; do 89 | dir=`dirname $name` 90 | # AC_MSG_CHECKING([for $2 project in ${dir}]) 91 | echo "with \"${name}\"; project conftest is for Source_Dirs use (); end conftest;" > conftest.gpr 92 | if AC_TRY_COMMAND([gnat ls -Pconftest.gpr system.ads > /dev/null 2>conftest.out]) 93 | then 94 | ac_cv_gnat_project_$3=yes 95 | ac_cv_gnat_project_name_$3=${name} 96 | # AC_MSG_RESULT(yes, using ${name}) 97 | break 98 | else 99 | ac_cv_gnat_project_$3=no 100 | # AC_MSG_RESULT(no) 101 | fi 102 | done 103 | fi 104 | rm -f conftest.gpr 105 | 106 | if test x${ac_cv_gnat_project_$3} = xyes; then 107 | ac_cv_gnat_project_with_$3="with \"${ac_cv_gnat_project_name_$3}\";"; 108 | ac_cv_gnat_project_dir_$3=`dirname ${ac_cv_gnat_project_name_$3}` 109 | if test ${ac_cv_gnat_project_dir_$3} = . ; then 110 | ac_cv_gnat_project_dir_$3= 111 | else 112 | ac_cv_gnat_project_dir_$3="${ac_cv_gnat_project_dir_$3}/" 113 | fi 114 | else 115 | ac_cv_gnat_project_dir_$3= 116 | ac_cv_gnat_project_name_$3= 117 | fi 118 | ]) 119 | 120 | if test x${ac_cv_gnat_project_$3} = xyes; then 121 | $6 122 | else 123 | if test x"$5" != x; then 124 | AC_MSG_RESULT(no) 125 | AC_MSG_ERROR([$5 126 | You should build and install the $2 component. 127 | It must be available and found by ${GNATMAKE}. 128 | This project was not found in the ADA_PROJECT_PATH environment variable. 129 | This project was not found in ../$3 nor in ../$1-*. 130 | The component is available at $4. 131 | Please, download and configure $2. 132 | The current configuration was using: 133 | ${GNATMAKE} 134 | ADA_PROJECT_PATH=$ADA_PROJECT_PATH 135 | ]) 136 | fi 137 | fi 138 | ]) 139 | 140 | dnl Check for utilada_base GNAT project 141 | AC_DEFUN(AM_GNAT_FIND_ADA_UTIL, 142 | [ 143 | AM_GNAT_FIND_PROJECT([ada-util],[Ada Utility Library],[utilada_base], 144 | [git@github.com:stcarrez/ada-util.git], 145 | [Building $1 requires the Ada Utility Library.], 146 | [ 147 | UTIL_DIR=${ac_cv_gnat_project_dir_utilada_base} 148 | ]) 149 | AC_SUBST(UTIL_DIR) 150 | ]) 151 | 152 | dnl Check for elada GNAT project 153 | AC_DEFUN(AM_GNAT_FIND_ADA_EL, 154 | [ 155 | AM_GNAT_FIND_PROJECT([ada-el],[Ada Expression Language Library],[elada], 156 | [git@github.com:stcarrez/ada-el.git], 157 | [Building $1 requires the Ada EL Library.], 158 | [ 159 | EL_DIR=${ac_cv_gnat_project_dir_elada} 160 | ]) 161 | AC_SUBST(EL_DIR) 162 | ]) 163 | 164 | dnl Check for security GNAT project 165 | AC_DEFUN(AM_GNAT_FIND_ADA_SECURITY, 166 | [ 167 | AM_GNAT_FIND_PROJECT([ada-security],[Ada Security Library],[security], 168 | [git@github.com:stcarrez/ada-security.git], 169 | [Building $1 requires the Ada Security Library.], 170 | [ 171 | SECURITY_DIR=${ac_cv_gnat_project_dir_security} 172 | ]) 173 | AC_SUBST(SECURITY_DIR) 174 | ]) 175 | 176 | dnl Check for servletada GNAT project 177 | AC_DEFUN(AM_GNAT_FIND_ADA_SERVLET, 178 | [ 179 | AM_GNAT_FIND_PROJECT([ada-servlet],[Ada Servlet Library],[servletada], 180 | [git@github.com:stcarrez/ada-servlet.git], 181 | [Building $1 requires the Ada Servlet Library.], 182 | [ 183 | SERVLET_DIR=${ac_cv_gnat_project_dir_servletada} 184 | ]) 185 | AC_SUBST(SERVLET_DIR) 186 | ]) 187 | 188 | dnl Check for asf GNAT project 189 | AC_DEFUN(AM_GNAT_FIND_ADA_SERVER_FACES, 190 | [ 191 | AM_GNAT_FIND_PROJECT([ada-asf],[Ada Server Faces],[asf], 192 | [git@github.com:stcarrez/ada-asf.git], 193 | [Building $1 requires the Ada Server Faces Library.], 194 | [ 195 | ASF_DIR=${ac_cv_gnat_project_dir_asf} 196 | ]) 197 | AC_SUBST(ASF_DIR) 198 | ]) 199 | 200 | dnl Check for ado GNAT project 201 | AC_DEFUN(AM_GNAT_FIND_ADA_ADO, 202 | [ 203 | AM_GNAT_FIND_PROJECT([ada-ado],[Ada Database Objects],[ado], 204 | [git@github.com:stcarrez/ada-ado.git], 205 | [Building $1 requires the Ada Database Objects Library.], 206 | [ 207 | ADO_DIR=${ac_cv_gnat_project_dir_ado} 208 | ]) 209 | AC_SUBST(ADO_DIR) 210 | ]) 211 | 212 | dnl Check for wikiada GNAT project 213 | AC_DEFUN(AM_GNAT_FIND_ADA_WIKI, 214 | [ 215 | AM_GNAT_FIND_PROJECT([ada-wiki],[Ada Wiki Library],[wikiada], 216 | [git@github.com:stcarrez/ada-wiki.git], 217 | [Building $1 requires the Ada Wiki Library.], 218 | [ 219 | WIKI_DIR=${ac_cv_gnat_project_dir_wikiada} 220 | ]) 221 | AC_SUBST(WIKI_DIR) 222 | ]) 223 | 224 | dnl Check for swaggerada GNAT project 225 | AC_DEFUN(AM_GNAT_FIND_ADA_SWAGGER, 226 | [ 227 | AM_GNAT_FIND_PROJECT([swagger-ada],[Swagger Ada Library],[swagger], 228 | [git@github.com:stcarrez/swagger-ada.git], 229 | [Building $1 requires the Ada Swagger Library.], 230 | [ 231 | SWAGGER_DIR=${ac_cv_gnat_project_dir_swagger} 232 | ]) 233 | AC_SUBST(SWAGGER_DIR) 234 | ]) 235 | 236 | dnl Check for AWA GNAT project 237 | AC_DEFUN(AM_GNAT_FIND_ADA_AWA, 238 | [ 239 | AM_GNAT_FIND_PROJECT([awa],[Ada Web Application],[awa], 240 | [git@github.com:stcarrez/ada-awa.git], 241 | [Building $1 requires the Ada Web Application Library.], 242 | [ 243 | AWA_DIR=${ac_cv_gnat_project_dir_awa} 244 | ]) 245 | AC_SUBST(AWA_DIR) 246 | ]) 247 | 248 | dnl Check for XML/Ada_base GNAT project 249 | dnl AM_GNAT_FIND_PROJECT([code-found],[not-found]) 250 | AC_DEFUN(AM_GNAT_FIND_XML_ADA, 251 | [ 252 | gnat_xml_ada=xmlada-config 253 | AC_ARG_WITH(xmlada, 254 | AS_HELP_STRING([--with-xmlada=], [Path for XML/Ada]), 255 | [ 256 | if test T${withval} = Tno ; then 257 | HAVE_XML_ADA=no; 258 | else 259 | gnat_xml_ada=${withval}/xmlada-config; 260 | WITH_XML_ADA="with \"${withval}\";"; 261 | HAVE_XML_ADA='yes'; 262 | fi 263 | ], 264 | [ 265 | WITH_XML_ADA=''; 266 | HAVE_XML_ADA='yes'; 267 | ]) 268 | 269 | if test T$HAVE_XML_ADA = Tyes ; then 270 | 271 | AM_GNAT_CHECK_PROJECT([xmlada_sax],[xmlada_sax]) 272 | if test T$ac_cv_gnat_project_xmlada_sax = Tno; then 273 | AM_GNAT_CHECK_PROJECT([xmlada],[xmlada]) 274 | fi 275 | 276 | AC_CACHE_CHECK([XML/Ada version],[ac_cv_gnat_xmlada_version],[ 277 | if test T$HAVE_XML_ADA = Tyes ; then 278 | gnat_xmlada_version=`$gnat_xml_ada --version 2>/dev/null | sed -e 's, ,-,g'` 279 | else 280 | gnat_xmlada_version=none 281 | HAVE_XML_ADA='no' 282 | fi 283 | 284 | case $gnat_xmlada_version in 285 | XmlAda-3.2*) 286 | ac_cv_gnat_xmlada_version='3' 287 | ;; 288 | 289 | XmlAda-4.*|XmlAda-2013|XmlAda-2014) 290 | ac_cv_gnat_xmlada_version='4' 291 | ;; 292 | 293 | *) 294 | ac_cv_gnat_xmlada_version='none' 295 | HAVE_XML_ADA='no' 296 | ;; 297 | 298 | esac 299 | 300 | if test T$ac_cv_gnat_project_xmlada_sax = Tno; then 301 | if test T$ac_cv_gnat_project_xmlada != Tyes; then 302 | ac_cv_gnat_xmlada_version='none' 303 | HAVE_XML_ADA='no' 304 | fi 305 | else 306 | ac_cv_gnat_xmlada_version='4' 307 | HAVE_XML_ADA='yes' 308 | fi 309 | 310 | ]) 311 | else 312 | ac_cv_gnat_project_xmlada_sax='no' 313 | fi 314 | 315 | if test T$ac_cv_gnat_project_xmlada = Tyes; then 316 | WITH_XML_ADA="with \"xmlada\";"; 317 | fi 318 | if test T$ac_cv_gnat_project_xmlada_sax = Tyes; then 319 | WITH_XML_ADA="with \"xmlada_sax\";"; 320 | fi 321 | 322 | VERSION_XML_ADA=$ac_cv_gnat_xmlada_version 323 | 324 | case T$HAVE_XML_ADA in 325 | Tyes) 326 | $1 327 | ;; 328 | 329 | Tno) 330 | WITH_XML_ADA=''; 331 | VERSION_XML_ADA='none'; 332 | HAVE_XML_ADA='no' 333 | $2 334 | ;; 335 | 336 | esac 337 | 338 | AC_SUBST(WITH_XML_ADA) 339 | AC_SUBST(VERSION_XML_ADA) 340 | AC_SUBST(HAVE_XML_ADA) 341 | ]) 342 | 343 | dnl Check whether the shared library support is enabled. 344 | AC_DEFUN(AM_SHARED_LIBRARY_SUPPORT, 345 | [ 346 | AC_MSG_CHECKING([shared library support]) 347 | ac_enable_shared=no 348 | AC_ARG_ENABLE(shared, 349 | [ --enable-shared Enable the shared libraries (disabled)], 350 | [case "${enableval}" in 351 | no|none) ac_enable_shared=no ;; 352 | *) ac_enable_shared=yes ;; 353 | esac])dnl 354 | ac_enable_default_shared=no 355 | AC_ARG_ENABLE(default-shared, 356 | [ --enable-default-shared Use shared libraries by default (disabled)], 357 | [case "${enableval}" in 358 | no|none) ac_enable_default_shared=no ;; 359 | *) ac_enable_default_shared=yes ;; 360 | esac])dnl 361 | 362 | AC_MSG_RESULT(${ac_enable_shared}) 363 | BUILDS_SHARED=$ac_enable_shared 364 | AC_SUBST(BUILDS_SHARED) 365 | 366 | AC_MSG_CHECKING([default library type]) 367 | if test ${ac_enable_shared} = yes && test ${ac_enable_default_shared} = yes; then 368 | DEFAULT_LIBRARY_TYPE='relocatable' 369 | else 370 | DEFAULT_LIBRARY_TYPE='static' 371 | fi 372 | AC_MSG_RESULT(${DEFAULT_LIBRARY_TYPE}) 373 | AC_SUBST(DEFAULT_LIBRARY_TYPE) 374 | ]) 375 | 376 | dnl Check whether the coverage support is enabled. 377 | AC_DEFUN(AM_COVERAGE_SUPPORT, 378 | [ 379 | AC_MSG_CHECKING([coverage support]) 380 | ac_enable_coverage=no 381 | AC_ARG_ENABLE(coverage, 382 | [ --enable-coverage build with coverage support -fprofile-arcs -ftest-coverage (disabled)], 383 | [case "${enableval}" in 384 | no|none) ac_enable_coverage=no ;; 385 | *) ac_enable_coverage=yes ;; 386 | esac])dnl 387 | 388 | AC_MSG_RESULT(${ac_enable_coverage}) 389 | BUILDS_COVERAGE=$ac_enable_coverage 390 | AC_SUBST(BUILDS_COVERAGE) 391 | if test T$ac_enable_coverage = Tyes; then 392 | ac_build_mode='coverage' 393 | fi 394 | ]) 395 | 396 | dnl Check whether the distrib/debug build is enabled. 397 | AC_DEFUN(AM_DISTRIB_SUPPORT, 398 | [ 399 | AC_MSG_CHECKING([distribution build]) 400 | ac_enable_distrib=yes 401 | ac_quiet_mode=-q 402 | ac_build_mode=distrib 403 | AC_ARG_ENABLE(distrib, 404 | [ --enable-distrib build for distribution, optimized and strip symbols (enabled)], 405 | [case "${enableval}" in 406 | no|none) ac_enable_distrib=no 407 | ac_build_mode=debug 408 | ac_quiet_mode= 409 | ;; 410 | *) ac_enable_distrib=yes 411 | ac_build_mode=distrib 412 | ac_quiet_mode=-q 413 | ;; 414 | esac])dnl 415 | 416 | AC_MSG_RESULT(${ac_enable_distrib}) 417 | BUILDS_DISTRIB=$ac_enable_distrib 418 | AC_SUBST(BUILDS_DISTRIB) 419 | 420 | BUILDS_QUIET=$ac_quiet_mode 421 | AC_SUBST(BUILDS_QUIET) 422 | ]) 423 | 424 | dnl Check whether the AWS support is enabled and find the aws GNAT project. 425 | AC_DEFUN(AM_GNAT_CHECK_AWS, 426 | [ 427 | dnl Define option to enable/disable AWS 428 | gnat_enable_aws=yes 429 | gnat_project_aws=no 430 | gnat_project_name_aws= 431 | AC_ARG_ENABLE(aws, 432 | [ --enable-aws Enable the AWS support (enabled)], 433 | [case "${enableval}" in 434 | no|none) gnat_enable_aws=no ;; 435 | *) gnat_enable_aws=yes ;; 436 | esac])dnl 437 | 438 | AC_MSG_CHECKING([AWS support is enabled]) 439 | AC_MSG_RESULT(${gnat_enable_aws}) 440 | 441 | if test T$gnat_enable_aws = Tyes; then 442 | dnl AC_MSG_NOTICE([Ada Web Server library (http://libre.adacore.com/libre/tools/aws/)]) 443 | AC_ARG_WITH(aws, 444 | AS_HELP_STRING([--with-aws=x], [Path for the Ada Web Server library (http://libre.adacore.com/libre/tools/aws/)]), 445 | [ 446 | gnat_project_name=${withval} 447 | ], 448 | [ 449 | gnat_project_name=aws 450 | ]) 451 | AM_GNAT_CHECK_PROJECT([aws],[${gnat_project_name}]) 452 | if test x$ac_cv_gnat_project_aws = xno; then 453 | gnat_enable_aws=no 454 | else 455 | gnat_project_aws=aws 456 | fi 457 | fi 458 | if test T$gnat_enable_aws = Tno; then 459 | $1 460 | else 461 | $2 462 | fi 463 | ]) 464 | 465 | dnl Setup installation paths 466 | dnl AM_UTIL_INSTALL([inc],[ali],[lib],[prj]) 467 | AC_DEFUN(AM_UTIL_INSTALL, 468 | [ 469 | gnat_prefix= 470 | for dir in $1 $2 $3 $4; do 471 | dir=`echo $dir | sed -e 's,\\\\,/,g'` 472 | # If we have a valid path, try to identify the common path prefix. 473 | if test x$gnat_prefix = x; then 474 | gnat_prefix=$dir 475 | else 476 | # echo "Dir=$dir" 477 | gnat_old_ifs=$IFS 478 | path= 479 | IFS='/\' 480 | for c in $dir; do 481 | if test x"$path" = x"/" || test x"$path" = x ; then 482 | case $c in 483 | c:|C:|d:|D:|e:|E:) 484 | try="$c" 485 | ;; 486 | *) 487 | try="/$c" 488 | ;; 489 | esac 490 | else 491 | try="$path/$c" 492 | fi 493 | # echo "gnat_prefix=$gnat_prefix try=$try path=$path c=$c" 494 | case $gnat_prefix in 495 | $try*) 496 | ;; 497 | *) 498 | break 499 | ;; 500 | esac 501 | path=$try 502 | done 503 | IFS=$gnat_old_ifs 504 | gnat_prefix=$path 505 | fi 506 | done 507 | ADA_INC_BASE=`echo $1 | sed -e 's,\\\\,/,g' | sed -e s,^$gnat_prefix/,,` 508 | ADA_ALI_BASE=`echo $2 | sed -e 's,\\\\,/,g' | sed -e s,^$gnat_prefix/,,` 509 | ADA_LIB_BASE=`echo $3 | sed -e 's,\\\\,/,g' | sed -e s,^$gnat_prefix/,,` 510 | ADA_PRJ_BASE=`echo $4 | sed -e 's,\\\\,/,g' | sed -e s,^$gnat_prefix/,,` 511 | 512 | AC_MSG_CHECKING([installation of Ada source files]) 513 | AC_MSG_RESULT(/${ADA_INC_BASE}) 514 | 515 | AC_MSG_CHECKING([installation of Ada ALI files]) 516 | AC_MSG_RESULT(/${ADA_ALI_BASE}) 517 | 518 | AC_MSG_CHECKING([installation of library files]) 519 | AC_MSG_RESULT(/${ADA_LIB_BASE}) 520 | 521 | AC_MSG_CHECKING([installation of GNAT project files]) 522 | AC_MSG_RESULT(/${ADA_PRJ_BASE}) 523 | 524 | AC_SUBST(ADA_INC_BASE) 525 | AC_SUBST(ADA_LIB_BASE) 526 | AC_SUBST(ADA_ALI_BASE) 527 | AC_SUBST(ADA_PRJ_BASE) 528 | ]) 529 | 530 | 531 | dnl Check by using xmlada-config where some files are installed. 532 | dnl The goad is to find or guess some installation paths. 533 | dnl XML/Ada Debian 534 | dnl *.ads /include/xmlada /usr/share/adainclude/xmlada 535 | dnl *.ali /lib/xmlada/static /usr/lib//ada/adalib/xmlada 536 | dnl *.so /lib/xmlada/static /usr/lib/ 537 | dnl *.prj /lib/gnat /usr/share/adainclude 538 | 539 | AC_DEFUN(AM_GNAT_CHECK_INSTALL, 540 | [ 541 | # 542 | ac_cv_gnat_prefix= 543 | ac_cv_gnat_xml_inc_dir= 544 | ac_cv_gnat_xml_ali_dir= 545 | ac_cv_gnat_xml_lib_dir= 546 | ac_cv_gnat_xml_prl_dir= 547 | 548 | if test x${ac_cv_gnat_xml_ada} = 'x'; then 549 | ac_cv_gnat_xml_ada=xmlada-config 550 | fi 551 | ac_cv_gnat_xml_config=`$gnat_xml_ada --sax 2>/dev/null` 552 | 553 | # echo "Config: $gnat_xml_config" 554 | for i in $ac_cv_gnat_xml_config; do 555 | # echo " Checking $i" 556 | case $i in 557 | -aI*) 558 | name=`echo $i | sed -e 's,-aI,,'` 559 | dir=`dirname $name` 560 | name=`basename $name` 561 | if test x$name = "xxmlada"; then 562 | ac_cv_gnat_xml_inc_dir=$dir 563 | else 564 | dir='' 565 | fi 566 | ;; 567 | 568 | -aO*) 569 | name=`echo $i | sed -e 's,-aO,,'` 570 | dir=`dirname $name` 571 | name=`basename $name` 572 | case $name in 573 | xmlada) 574 | ac_cv_gnat_xml_ali_dir=$dir 575 | ;; 576 | 577 | static|relocatable) 578 | name=`basename $dir` 579 | dir=`dirname $dir` 580 | if test x$name = "xxmlada"; then 581 | ac_cv_gnat_xml_ali_dir=$dir 582 | else 583 | dir='' 584 | fi 585 | ;; 586 | 587 | *) 588 | dir='' 589 | ;; 590 | 591 | esac 592 | ;; 593 | 594 | -largs) 595 | dir='' 596 | ;; 597 | 598 | -L*) 599 | dir=`echo $i | sed -e 's,-L,,'` 600 | ac_cv_gnat_xml_lib_dir=$dir 601 | ;; 602 | 603 | /*.a) 604 | dir=`dirname $i` 605 | name=`basename $dir` 606 | case $name in 607 | xmlada) 608 | dir=`dirname $dir` 609 | ac_cv_gnat_xml_lib_dir=$dir 610 | ;; 611 | 612 | static|relocatable) 613 | dir=`dirname $dir` 614 | name=`basename $dir` 615 | if test x$name = "xxmlada"; then 616 | dir=`dirname $dir` 617 | ac_cv_gnat_xml_lib_dir=$dir 618 | else 619 | dir='' 620 | fi 621 | ;; 622 | 623 | *) 624 | dir='' 625 | ;; 626 | 627 | esac 628 | ;; 629 | 630 | *) 631 | dir= 632 | ;; 633 | esac 634 | 635 | # If we have a valid path, try to identify the common path prefix. 636 | if test x$dir != "x"; then 637 | if test x$ac_cv_gnat_prefix = x; then 638 | ac_cv_gnat_prefix=$dir 639 | else 640 | # echo "Dir=$dir" 641 | gnat_old_ifs=$IFS 642 | path= 643 | IFS=/ 644 | for c in $dir; do 645 | if test x"$path" = x"/"; then 646 | try="/$c" 647 | else 648 | try="$path/$c" 649 | fi 650 | # echo "gnat_prefix=$gnat_prefix try=$try path=$path c=$c" 651 | case $ac_cv_gnat_prefix in 652 | $try*) 653 | ;; 654 | *) 655 | break 656 | ;; 657 | esac 658 | path=$try 659 | done 660 | IFS=$gnat_old_ifs 661 | ac_cv_gnat_prefix=$path 662 | fi 663 | fi 664 | done 665 | 666 | if test -f $ac_cv_gnat_prefix/lib/gnat/xmlada.gpr ; then 667 | ac_cv_gnat_xml_prj_dir=$ac_cv_gnat_prefix/lib/gnat 668 | elif test -f $gnat_xml_inc_dir/xmlada.gpr ; then 669 | ac_cv_gnat_xml_prj_dir=$ac_cv_gnat_xml_inc_dir 670 | elif test -f $ac_cv_gnat_prefix/share/gpr/xmlada.gpr ; then 671 | ac_cv_gnat_xml_prj_dir=$ac_cv_gnat_prefix/share/gpr 672 | else 673 | ac_cv_gnat_xml_prj_dir=$gnat_xml_inc_dir 674 | fi 675 | if test x${ac_cv_gnat_xml_inc_dir} = x ; then 676 | ac_cv_gnat_xml_inc_dir='include' 677 | fi 678 | if test x${ac_cv_gnat_xml_lib_dir} = x ; then 679 | ac_cv_gnat_xml_lib_dir='lib' 680 | fi 681 | if test x${ac_cv_gnat_xml_ali_dir} = x ; then 682 | ac_cv_gnat_xml_ali_dir='lib' 683 | fi 684 | if test x${ac_cv_gnat_xml_prj_dir} = x ; then 685 | ac_cv_gnat_xml_prj_dir='lib/gnat' 686 | fi 687 | ADA_INC_BASE=`echo $ac_cv_gnat_xml_inc_dir | sed -e s,^$ac_cv_gnat_prefix/,,` 688 | ADA_LIB_BASE=`echo $ac_cv_gnat_xml_lib_dir | sed -e s,^$ac_cv_gnat_prefix/,,` 689 | ADA_ALI_BASE=`echo $ac_cv_gnat_xml_ali_dir | sed -e s,^$ac_cv_gnat_prefix/,,` 690 | ADA_PRJ_BASE=`echo $ac_cv_gnat_xml_prj_dir | sed -e s,^$ac_cv_gnat_prefix/,,` 691 | AM_UTIL_INSTALL([${ac_cv_gnat_xml_inc_dir}],[${ac_cv_gnat_xml_ali_dir}],[${ac_cv_gnat_xml_lib_dir}],[${ac_cv_gnat_xml_prj_dir}]) 692 | ]) 693 | 694 | # AM_TRY_ADA and AM_HAS_INTRINSIC_SYNC_COUNTERS are imported from GNATcoll aclocal.m4 695 | ############################################################# 696 | # Check whether gnatmake can compile, bind and link an Ada program 697 | # AM_TRY_ADA(gnatmake,filename,content,success,failure) 698 | ############################################################# 699 | 700 | AC_DEFUN(AM_TRY_ADA, 701 | [ 702 | cat > conftest.ada </dev/null 2>conftest.out]) 706 | then 707 | : Success 708 | $4 709 | else 710 | : Failure 711 | $5 712 | fi 713 | rm -rf conftest.ada 714 | ]) 715 | 716 | ############################################################# 717 | # Check whether platform/GNAT supports atomic increment/decrement 718 | # operations. 719 | # The following variable is then set: 720 | # SYNC_COUNTERS_IMPL 721 | # to either "intrinsic" or "mutex" 722 | # Code comes from the PolyORB configure.ac 723 | ############################################################# 724 | 725 | AC_DEFUN(AM_HAS_INTRINSIC_SYNC_COUNTERS, 726 | [ 727 | AC_MSG_CHECKING([whether platform supports atomic inc/dec]) 728 | AM_TRY_ADA([gnatmake], [check.adb], 729 | [ 730 | with Interfaces; use Interfaces; 731 | procedure Check is 732 | function Sync_Add_And_Fetch 733 | (Ptr : access Interfaces.Integer_32; 734 | Value : Interfaces.Integer_32) return Interfaces.Integer_32; 735 | pragma Import (Intrinsic, Sync_Add_And_Fetch, "__sync_add_and_fetch_4"); 736 | X : aliased Interfaces.Integer_32; 737 | Y : Interfaces.Integer_32 := 0; 738 | pragma Volatile (Y); 739 | -- On some platforms (e.g. i386), GCC has limited support for 740 | -- __sync_add_and_fetch_4 for the case where the result is not used. 741 | -- Here we want to test for general availability, so make Y volatile to 742 | -- prevent the store operation from being discarded. 743 | begin 744 | Y := Sync_Add_And_Fetch (X'Access, 1); 745 | end Check; 746 | ], 747 | [ 748 | AC_MSG_RESULT(yes) 749 | $1 750 | ],[ 751 | AC_MSG_RESULT(no) 752 | $2 753 | ]) 754 | 755 | rm -f check.adb check 756 | ]) 757 | 758 | # Prepare for using the GNAT project 759 | # AM_GNAT_LIBRARY_SETUP([name]) 760 | AC_DEFUN(AM_GNAT_LIBRARY_SETUP, 761 | [ 762 | AC_MSG_CHECKING([preparing for GNAT project $1]) 763 | mkdir -p obj/$1/static obj/$1/relocatable lib/$1/static lib/$1/relocatable 764 | AC_MSG_RESULT(done) 765 | ]) 766 | 767 | # Prepare for using the GNAT project 768 | # AM_GNAT_LIBRARY_PROJECT([name]) 769 | AC_DEFUN(AM_GNAT_LIBRARY_PROJECT, 770 | [ 771 | AC_ARG_WITH(build-root, 772 | AS_HELP_STRING([--with-build-root=PATH], [Path to find the Ada libraries]), 773 | [ 774 | awa_build_root=${withval}/ 775 | ], 776 | [ 777 | awa_build_root='' 778 | ]) 779 | 780 | if test x${awa_build_root} != x; then 781 | AM_CHECK_HOST_PWD 782 | awa_build_pwd=`cd ${awa_build_root} && pwd $pwd_option` 783 | if test x${awa_build_pwd} != x${awa_build_root}; then 784 | awa_build_root=${awa_build_pwd}/ 785 | fi 786 | fi 787 | 788 | # checking for local tools 789 | AC_CANONICAL_SYSTEM 790 | AM_GNAT_CHECK_GPRBUILD 791 | 792 | AC_PROG_MAKE_SET 793 | AC_PROG_INSTALL 794 | AC_PROG_LN_S 795 | AM_SHARED_LIBRARY_SUPPORT 796 | AM_DISTRIB_SUPPORT 797 | AM_COVERAGE_SUPPORT 798 | 799 | BUILD=$ac_build_mode 800 | AC_SUBST(BUILD) 801 | 802 | AC_CACHE_CHECK([number of processors],[ac_cv_proc_count],[ 803 | ac_cv_proc_count=`getconf _NPROCESSORS_CONF 2>/dev/null || getconf NPROCESSORS_CONF 2>/dev/null || echo 1` 804 | ]) 805 | NR_CPUS=$ac_cv_proc_count 806 | AC_SUBST(NR_CPUS) 807 | 808 | AM_GNAT_LIBRARY_SETUP($1) 809 | ]) 810 | 811 | dnl Check and retrieve the Ada Web Server version 812 | dnl HTTP Delete is supported after 2017 813 | AC_DEFUN(AM_GNAT_AWS_VERSION, 814 | [ 815 | AC_CACHE_CHECK([checking AWS version],[ac_cv_gnat_aws_version],[ 816 | 817 | cat > conftest.adb < conftest.gpr </dev/null 2>conftest.out]) 834 | then 835 | ac_cv_gnat_aws_version=`./conftest` 836 | else 837 | ac_cv_gnat_aws_version='none' 838 | fi 839 | rm -f conftest.gpr conftest.adb conftest.o conftest.ali 840 | rm -f b__conftest.ads b__conftest.adb b__conftest.o b__conftest.ali 841 | ]) 842 | 843 | AWS_VERSION=$ac_cv_gnat_aws_version 844 | AC_SUBST(AWS_VERSION) 845 | ]) 846 | -------------------------------------------------------------------------------- /tools/config.gpr: -------------------------------------------------------------------------------- 1 | abstract project Config is 2 | for Source_Dirs use (); 3 | 4 | type Yes_No is ("yes", "no"); 5 | 6 | type Library_Type_Type is ("relocatable", "static"); 7 | 8 | type Mode_Type is ("distrib", "debug", "optimize", "profile"); 9 | Mode : Mode_Type := external ("MODE", "debug"); 10 | 11 | Coverage : Yes_No := External ("COVERAGE", "no"); 12 | Processors := External ("PROCESSORS", "1"); 13 | 14 | package Builder is 15 | case Mode is 16 | when "debug" => 17 | for Default_Switches ("Ada") use ("-g", "-j" & Processors); 18 | when others => 19 | for Default_Switches ("Ada") use ("-g", "-O2", "-j" & Processors); 20 | end case; 21 | end Builder; 22 | 23 | package compiler is 24 | warnings := ("-gnatwua"); 25 | defaults := ("-gnat2012"); 26 | case Mode is 27 | when "distrib" => 28 | for Default_Switches ("Ada") use defaults & ("-gnatafno", "-gnatVa", "-gnatwa"); 29 | 30 | when "debug" => 31 | for Default_Switches ("Ada") use defaults & warnings 32 | & ("-gnata", "-gnatVaMI", "-gnaty3abcefhiklmnprstxM99"); 33 | 34 | when "optimize" => 35 | for Default_Switches ("Ada") use defaults & warnings 36 | & ("-gnatn", "-gnatp", "-fdata-sections", "-ffunction-sections"); 37 | 38 | when "profile" => 39 | for Default_Switches ("Ada") use defaults & warnings & ("-pg"); 40 | end case; 41 | 42 | case Coverage is 43 | when "yes" => 44 | for Default_Switches ("ada") use Compiler'Default_Switches ("Ada") & 45 | ("-fprofile-arcs", "-ftest-coverage"); 46 | when others => 47 | end case; 48 | end compiler; 49 | 50 | package binder is 51 | case Mode is 52 | when "debug" => 53 | for Default_Switches ("Ada") use ("-E"); 54 | 55 | when others => 56 | for Default_Switches ("Ada") use ("-E"); 57 | 58 | end case; 59 | end binder; 60 | 61 | package linker is 62 | case Mode is 63 | when "profile" => 64 | for Default_Switches ("Ada") use ("-pg"); 65 | 66 | when "distrib" => 67 | for Default_Switches ("Ada") use ("-s"); 68 | 69 | when "optimize" => 70 | for Default_Switches ("Ada") use ("-Wl,--gc-sections"); 71 | 72 | when others => 73 | null; 74 | end case; 75 | 76 | case Coverage is 77 | when "yes" => 78 | for Default_Switches ("ada") use Linker'Default_Switches ("ada") & 79 | ("-fprofile-arcs"); 80 | when others => 81 | end case; 82 | end linker; 83 | 84 | package Ide is 85 | for VCS_Kind use "Subversion"; 86 | end Ide; 87 | 88 | end Config; 89 | -------------------------------------------------------------------------------- /tools/configure.ac: -------------------------------------------------------------------------------- 1 | dnl Autoconf configure script for tool 2 | 3 | dnl Process this file with autoconf to produce a configure script. 4 | 5 | AC_INIT(src/tool.ads) 6 | 7 | # Current release settings 8 | TOOL_MAJOR_VERSION=0 9 | TOOL_MINOR_VERSION=2 10 | TOOL_MICRO_VERSION=0 11 | TOOL_VERSION=$TOOL_MAJOR_VERSION.$TOOL_MINOR_VERSION.$TOOL_MICRO_VERSION 12 | 13 | AM_GNAT_LIBRARY_PROJECT(tools) 14 | 15 | # checking for local tools 16 | AC_PROG_CC 17 | AC_PROG_MAKE_SET 18 | AC_PROG_INSTALL 19 | AC_PROG_LN_S 20 | 21 | # Set the version number of the project 22 | AC_SUBST(TOOL_VERSION) 23 | AC_SUBST(TOOL_MAJOR_VERSION) 24 | AC_SUBST(TOOL_MINOR_VERSION) 25 | AC_SUBST(TOOL_MICRO_VERSION) 26 | 27 | EXEC_PREFIX="$prefix" 28 | AC_SUBST(EXEC_PREFIX) 29 | TOOL_LIBDIR="lib" 30 | AC_SUBST(TOOL_LIBDIR) 31 | 32 | AM_GNAT_FIND_ADA_UTIL([Tools]) 33 | 34 | AC_OUTPUT( 35 | Makefile tool.gpr 36 | ) 37 | -------------------------------------------------------------------------------- /tools/install-sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # install - install a program, script, or datafile 4 | # This comes from X11R5 (mit/util/scripts/install.sh). 5 | # 6 | # Copyright 1991 by the Massachusetts Institute of Technology 7 | # 8 | # Permission to use, copy, modify, distribute, and sell this software and its 9 | # documentation for any purpose is hereby granted without fee, provided that 10 | # the above copyright notice appear in all copies and that both that 11 | # copyright notice and this permission notice appear in supporting 12 | # documentation, and that the name of M.I.T. not be used in advertising or 13 | # publicity pertaining to distribution of the software without specific, 14 | # written prior permission. M.I.T. makes no representations about the 15 | # suitability of this software for any purpose. It is provided "as is" 16 | # without express or implied warranty. 17 | # 18 | # Calling this script install-sh is preferred over install.sh, to prevent 19 | # `make' implicit rules from creating a file called install from it 20 | # when there is no Makefile. 21 | # 22 | # This script is compatible with the BSD install script, but was written 23 | # from scratch. It can only install one file at a time, a restriction 24 | # shared with many OS's install programs. 25 | 26 | 27 | # set DOITPROG to echo to test this script 28 | 29 | # Don't use :- since 4.3BSD and earlier shells don't like it. 30 | doit="${DOITPROG-}" 31 | 32 | 33 | # put in absolute paths if you don't have them in your path; or use env. vars. 34 | 35 | mvprog="${MVPROG-mv}" 36 | cpprog="${CPPROG-cp}" 37 | chmodprog="${CHMODPROG-chmod}" 38 | chownprog="${CHOWNPROG-chown}" 39 | chgrpprog="${CHGRPPROG-chgrp}" 40 | stripprog="${STRIPPROG-strip}" 41 | rmprog="${RMPROG-rm}" 42 | mkdirprog="${MKDIRPROG-mkdir}" 43 | 44 | transformbasename="" 45 | transform_arg="" 46 | instcmd="$mvprog" 47 | chmodcmd="$chmodprog 0755" 48 | chowncmd="" 49 | chgrpcmd="" 50 | stripcmd="" 51 | rmcmd="$rmprog -f" 52 | mvcmd="$mvprog" 53 | src="" 54 | dst="" 55 | dir_arg="" 56 | 57 | while [ x"$1" != x ]; do 58 | case $1 in 59 | -c) instcmd="$cpprog" 60 | shift 61 | continue;; 62 | 63 | -d) dir_arg=true 64 | shift 65 | continue;; 66 | 67 | -m) chmodcmd="$chmodprog $2" 68 | shift 69 | shift 70 | continue;; 71 | 72 | -o) chowncmd="$chownprog $2" 73 | shift 74 | shift 75 | continue;; 76 | 77 | -g) chgrpcmd="$chgrpprog $2" 78 | shift 79 | shift 80 | continue;; 81 | 82 | -s) stripcmd="$stripprog" 83 | shift 84 | continue;; 85 | 86 | -t=*) transformarg=`echo $1 | sed 's/-t=//'` 87 | shift 88 | continue;; 89 | 90 | -b=*) transformbasename=`echo $1 | sed 's/-b=//'` 91 | shift 92 | continue;; 93 | 94 | *) if [ x"$src" = x ] 95 | then 96 | src=$1 97 | else 98 | # this colon is to work around a 386BSD /bin/sh bug 99 | : 100 | dst=$1 101 | fi 102 | shift 103 | continue;; 104 | esac 105 | done 106 | 107 | if [ x"$src" = x ] 108 | then 109 | echo "install: no input file specified" 110 | exit 1 111 | else 112 | true 113 | fi 114 | 115 | if [ x"$dir_arg" != x ]; then 116 | dst=$src 117 | src="" 118 | 119 | if [ -d $dst ]; then 120 | instcmd=: 121 | chmodcmd="" 122 | else 123 | instcmd=mkdir 124 | fi 125 | else 126 | 127 | # Waiting for this to be detected by the "$instcmd $src $dsttmp" command 128 | # might cause directories to be created, which would be especially bad 129 | # if $src (and thus $dsttmp) contains '*'. 130 | 131 | if [ -f $src -o -d $src ] 132 | then 133 | true 134 | else 135 | echo "install: $src does not exist" 136 | exit 1 137 | fi 138 | 139 | if [ x"$dst" = x ] 140 | then 141 | echo "install: no destination specified" 142 | exit 1 143 | else 144 | true 145 | fi 146 | 147 | # If destination is a directory, append the input filename; if your system 148 | # does not like double slashes in filenames, you may need to add some logic 149 | 150 | if [ -d $dst ] 151 | then 152 | dst="$dst"/`basename $src` 153 | else 154 | true 155 | fi 156 | fi 157 | 158 | ## this sed command emulates the dirname command 159 | dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 160 | 161 | # Make sure that the destination directory exists. 162 | # this part is taken from Noah Friedman's mkinstalldirs script 163 | 164 | # Skip lots of stat calls in the usual case. 165 | if [ ! -d "$dstdir" ]; then 166 | defaultIFS=' 167 | ' 168 | IFS="${IFS-${defaultIFS}}" 169 | 170 | oIFS="${IFS}" 171 | # Some sh's can't handle IFS=/ for some reason. 172 | IFS='%' 173 | set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` 174 | IFS="${oIFS}" 175 | 176 | pathcomp='' 177 | 178 | while [ $# -ne 0 ] ; do 179 | pathcomp="${pathcomp}${1}" 180 | shift 181 | 182 | if [ ! -d "${pathcomp}" ] ; 183 | then 184 | $mkdirprog "${pathcomp}" 185 | else 186 | true 187 | fi 188 | 189 | pathcomp="${pathcomp}/" 190 | done 191 | fi 192 | 193 | if [ x"$dir_arg" != x ] 194 | then 195 | $doit $instcmd $dst && 196 | 197 | if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && 198 | if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && 199 | if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && 200 | if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi 201 | else 202 | 203 | # If we're going to rename the final executable, determine the name now. 204 | 205 | if [ x"$transformarg" = x ] 206 | then 207 | dstfile=`basename $dst` 208 | else 209 | dstfile=`basename $dst $transformbasename | 210 | sed $transformarg`$transformbasename 211 | fi 212 | 213 | # don't allow the sed command to completely eliminate the filename 214 | 215 | if [ x"$dstfile" = x ] 216 | then 217 | dstfile=`basename $dst` 218 | else 219 | true 220 | fi 221 | 222 | # Make a temp file name in the proper directory. 223 | 224 | dsttmp=$dstdir/#inst.$$# 225 | 226 | # Move or copy the file name to the temp name 227 | 228 | $doit $instcmd $src $dsttmp && 229 | 230 | trap "rm -f ${dsttmp}" 0 && 231 | 232 | # and set any options; do chmod last to preserve setuid bits 233 | 234 | # If any of these fail, we abort the whole thing. If we want to 235 | # ignore errors from any of these, just make sure not to ignore 236 | # errors from the above "$doit $instcmd $src $dsttmp" command. 237 | 238 | if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && 239 | if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && 240 | if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && 241 | if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && 242 | 243 | # Now rename the file to the real destination. 244 | 245 | $doit $rmcmd -f $dstdir/$dstfile && 246 | $doit $mvcmd $dsttmp $dstdir/$dstfile 247 | 248 | fi && 249 | 250 | 251 | exit 0 252 | -------------------------------------------------------------------------------- /tools/src/excel_writer/ieee_754-generic_double_precision.adb: -------------------------------------------------------------------------------- 1 | -- -- 2 | -- package Copyright (c) Dmitry A. Kazakov -- 3 | -- IEEE_754.Generic_Double_Precision Luebeck -- 4 | -- Implementation Summer, 2008 -- 5 | -- -- 6 | -- Last revision : 09:27 06 Nov 2016 -- 7 | -- -- 8 | -- This library is free software; you can redistribute it and/or -- 9 | -- modify it under the terms of the GNU General Public License as -- 10 | -- published by the Free Software Foundation; either version 2 of -- 11 | -- the License, or (at your option) any later version. This library -- 12 | -- is distributed in the hope that it will be useful, but WITHOUT -- 13 | -- ANY WARRANTY; without even the implied warranty of -- 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- 15 | -- General Public License for more details. You should have -- 16 | -- received a copy of the GNU General Public License along with -- 17 | -- this library; if not, write to the Free Software Foundation, -- 18 | -- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -- 19 | -- -- 20 | -- As a special exception, if other files instantiate generics from -- 21 | -- this unit, or you link this unit with other files to produce an -- 22 | -- executable, this unit does not by itself cause the resulting -- 23 | -- executable to be covered by the GNU General Public License. This -- 24 | -- exception does not however invalidate any other reasons why the -- 25 | -- executable file might be covered by the GNU Public License. -- 26 | --____________________________________________________________________-- 27 | 28 | package body IEEE_754.Generic_Double_Precision is 29 | 30 | Exponent_Bias : constant := 2**10 - 1; 31 | Exponent_First : constant := -51; 32 | Exponent_Last : constant := 2**11 - 1; 33 | Fraction_Bits : constant := 52; 34 | Mantissa_Bits : constant := 53; 35 | 36 | function Exponent (Value : Float_64) return Integer is 37 | pragma Inline (Exponent); 38 | begin 39 | return 40 | Integer 41 | ( Shift_Left (Unsigned_16 (Value (1)) and 16#7F#, 4) 42 | or Shift_Right (Unsigned_16 (Value (2)), 4) 43 | ); 44 | end Exponent; 45 | 46 | function Mantissa (Value : Float_64) return Unsigned_64 is 47 | pragma Inline (Mantissa); 48 | begin 49 | return 50 | ( Unsigned_64 (Value (8)) 51 | or Shift_Left (Unsigned_64 (Value (7)), 8 ) 52 | or Shift_Left (Unsigned_64 (Value (6)), 2*8) 53 | or Shift_Left (Unsigned_64 (Value (5)), 3*8) 54 | or Shift_Left (Unsigned_64 (Value (4)), 4*8) 55 | or Shift_Left (Unsigned_64 (Value (3)), 5*8) 56 | or Shift_Left (Unsigned_64 (Value (2)) and 16#0F#, 6*8) 57 | or 2 ** Fraction_Bits 58 | ); 59 | end Mantissa; 60 | 61 | procedure Normalize 62 | ( Value : Number; 63 | Mantissa : out Unsigned_64; 64 | Exponent : out Integer 65 | ) is 66 | begin 67 | if Number'Machine_Radix = 2 then 68 | -- 69 | -- The machine radix is binary. We can use the hardware 70 | -- representation attributes in order to get the exponent and 71 | -- the fraction. 72 | -- 73 | Exponent := Number'Exponent (Value) - Mantissa_Bits; 74 | Mantissa := Unsigned_64 (Number'Scaling (Value, -Exponent)); 75 | else 76 | -- 77 | -- OK, this gets more tricky. The number is normalized to be in 78 | -- the range 2**53 > X >= 2**52, by multiplying to the powers 79 | -- of two. Some optimization is made to factor out the powers 80 | -- 2**(2**n)). Though we do not use powers bigger than 30. 81 | -- 82 | declare 83 | Accum : Number := Value; 84 | Shift : Integer; 85 | begin 86 | Exponent := 0; 87 | if Accum < 2.0**Fraction_Bits then 88 | Shift := 24; 89 | while Shift > 0 loop 90 | if Accum < 2.0**(Mantissa_Bits - Shift) then 91 | Accum := Accum * 2.0**Shift; 92 | Exponent := Exponent - Shift; 93 | else 94 | Shift := Shift / 2; 95 | end if; 96 | end loop; 97 | elsif Accum >= 2.0**Mantissa_Bits then 98 | Shift := 8; 99 | while Shift > 0 loop 100 | if Accum >= 2.0**(Fraction_Bits + Shift) then 101 | Accum := Accum / 2.0**Shift; 102 | Exponent := Exponent + Shift; 103 | else 104 | Shift := Shift / 2; 105 | end if; 106 | end loop; 107 | end if; 108 | Mantissa := Unsigned_64 (Accum); 109 | end; 110 | end if; 111 | end Normalize; 112 | 113 | function From_IEEE (Value : Float_64) return Number is 114 | begin 115 | if 0 = (Value (1) and 16#7F#) 116 | and then 117 | Value (2) = 0 118 | and then 119 | Value (3) = 0 120 | and then 121 | Value (4) = 0 122 | and then 123 | Value (5) = 0 124 | and then 125 | Value (6) = 0 126 | and then 127 | Value (7) = 0 128 | and then 129 | Value (8) = 0 130 | then 131 | return 0.0; 132 | end if; 133 | declare 134 | Power : Integer := Exponent (Value); 135 | Fraction : Unsigned_64 := Mantissa (Value); 136 | Result : Number; 137 | begin 138 | if Power = Exponent_Last then 139 | if Fraction /= 2#1000_0000_0000# then 140 | raise Not_A_Number_Error; 141 | elsif Value (1) > 127 then 142 | raise Negative_Overflow_Error; 143 | else 144 | raise Positive_Overflow_Error; 145 | end if; 146 | elsif Power = 0 then -- Denormalized number 147 | Fraction := Fraction and 16#0F_FF_FF_FF_FF_FF_FF_FF#; 148 | Power := Exponent_First - Exponent_Bias; 149 | if Number'Machine_Radix = 2 then 150 | Result := Number'Scaling (Number (Fraction), Power); 151 | else 152 | Result := Number (Fraction) * 2.0 ** Power; 153 | end if; 154 | else -- Normalized number 155 | Power := Power - Exponent_Bias - Fraction_Bits; 156 | if Number'Machine_Radix = 2 then 157 | Result := Number'Scaling (Number (Fraction), Power); 158 | else 159 | Result := Number (Fraction) * 2.0 ** Power; 160 | end if; 161 | end if; 162 | if Value (1) > 127 then 163 | return -Result; 164 | else 165 | return Result; 166 | end if; 167 | exception 168 | when Constraint_Error => 169 | if Value (1) > 127 then 170 | raise Negative_Overflow_Error; 171 | else 172 | raise Positive_Overflow_Error; 173 | end if; 174 | end; 175 | end From_IEEE; 176 | 177 | function Is_NaN (Value : Float_64) return Boolean is 178 | begin 179 | return 180 | ( Exponent (Value) = Exponent_Last 181 | and then 182 | Mantissa (Value) /= 2 ** Fraction_Bits 183 | ); 184 | end Is_NaN; 185 | 186 | function Is_Negative (Value : Float_64) return Boolean is 187 | begin 188 | return Value (1) > 127; 189 | end Is_Negative; 190 | 191 | function Is_Real (Value : Float_64) return Boolean is 192 | begin 193 | return Exponent (Value) < Exponent_Last; 194 | end Is_Real; 195 | 196 | function To_IEEE (Value : Number) return Float_64 is 197 | begin 198 | if Value = 0.0 then 199 | return (others => 0); 200 | end if; 201 | declare 202 | Exponent : Integer; 203 | Fraction : Unsigned_64; 204 | Sign : Byte := 0; 205 | begin 206 | if Value > 0.0 then 207 | Normalize (Value, Fraction, Exponent); 208 | else 209 | Normalize (-Value, Fraction, Exponent); 210 | Sign := 2**7; 211 | end if; 212 | Exponent := Exponent + Exponent_Bias + Fraction_Bits; 213 | if Exponent < Exponent_First then 214 | -- Underflow, resuls in zero 215 | return (others => 0); 216 | elsif Exponent >= Exponent_Last then 217 | -- Overflow, results in infinities 218 | if Sign = 0 then 219 | return Positive_Infinity; 220 | else 221 | return Negative_Infinity; 222 | end if; 223 | elsif Exponent <= 0 then -- Denormalized 224 | Fraction := Shift_Right (Fraction, 1 - Exponent); 225 | Exponent := 0; 226 | end if; 227 | return 228 | ( Sign or Byte (Exponent / 2**4), 229 | ( Byte (Shift_Right (Fraction, 8*6) and 16#0F#) 230 | or Shift_Left (Byte (Exponent mod 2**4), 4) 231 | ), 232 | Byte (Shift_Right (Fraction, 8*5) and 16#FF#), 233 | Byte (Shift_Right (Fraction, 8*4) and 16#FF#), 234 | Byte (Shift_Right (Fraction, 8*3) and 16#FF#), 235 | Byte (Shift_Right (Fraction, 8*2) and 16#FF#), 236 | Byte (Shift_Right (Fraction, 8 ) and 16#FF#), 237 | Byte (Fraction and 16#FF#) 238 | ); 239 | end; 240 | end To_IEEE; 241 | 242 | end IEEE_754.Generic_Double_Precision; 243 | -------------------------------------------------------------------------------- /tools/src/excel_writer/ieee_754-generic_double_precision.ads: -------------------------------------------------------------------------------- 1 | -- -- 2 | -- package Copyright (c) Dmitry A. Kazakov -- 3 | -- IEEE_754.Generic_Double_Precision Luebeck -- 4 | -- Interface Summer, 2008 -- 5 | -- -- 6 | -- Last revision : 09:27 06 Nov 2016 -- 7 | -- -- 8 | -- This library is free software; you can redistribute it and/or -- 9 | -- modify it under the terms of the GNU General Public License as -- 10 | -- published by the Free Software Foundation; either version 2 of -- 11 | -- the License, or (at your option) any later version. This library -- 12 | -- is distributed in the hope that it will be useful, but WITHOUT -- 13 | -- ANY WARRANTY; without even the implied warranty of -- 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- 15 | -- General Public License for more details. You should have -- 16 | -- received a copy of the GNU General Public License along with -- 17 | -- this library; if not, write to the Free Software Foundation, -- 18 | -- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -- 19 | -- -- 20 | -- As a special exception, if other files instantiate generics from -- 21 | -- this unit, or you link this unit with other files to produce an -- 22 | -- executable, this unit does not by itself cause the resulting -- 23 | -- executable to be covered by the GNU General Public License. This -- 24 | -- exception does not however invalidate any other reasons why the -- 25 | -- executable file might be covered by the GNU Public License. -- 26 | --____________________________________________________________________-- 27 | 28 | generic 29 | type Number is digits <>; 30 | package IEEE_754.Generic_Double_Precision is 31 | pragma Pure (IEEE_754.Generic_Double_Precision); 32 | use Interfaces; 33 | -- 34 | -- Float_64 -- 64-bit double-precision IEEE 754 float. The memory layout 35 | -- is big endian, i.e. the byte containing the number's sign 36 | -- and the most significant bits of the exponent is the first array 37 | -- element. The byte containing the least significant bits of the 38 | -- mantissa is the last array element. 39 | -- 40 | type Float_64 is array (1..8) of Byte; 41 | Positive_Infinity : constant Float_64; 42 | Positive_Zero : constant Float_64; 43 | Negative_Infinity : constant Float_64; 44 | Negative_Zero : constant Float_64; 45 | -- 46 | -- From_IEEE -- Conversion from 32-bit single precision IEEE 754 float 47 | -- 48 | -- Value - The argument 49 | -- 50 | -- Returns : 51 | -- 52 | -- The corresponding floating-point number 53 | -- 54 | -- Exceptions : 55 | -- 56 | -- Not_A_Number_Error - Not a number 57 | -- Positive_Overflow_Error - Positive infinity or too big positive 58 | -- Negative_Overflow_Error - Negative infinity or too big negative 59 | -- 60 | function From_IEEE (Value : Float_64) return Number; 61 | -- 62 | -- Is_NaN -- NaN test 63 | -- 64 | -- Value - The argument 65 | -- 66 | -- Returns : 67 | -- 68 | -- True if Value is an IEEE NaN 69 | -- 70 | function Is_NaN (Value : Float_64) return Boolean; 71 | -- 72 | -- Is_Negative -- IEEE sign test 73 | -- 74 | -- Value - The argument 75 | -- 76 | -- Returns : 77 | -- 78 | -- True if Value has an IEEE sign 79 | -- 80 | function Is_Negative (Value : Float_64) return Boolean; 81 | -- 82 | -- Is_Real -- Value test 83 | -- 84 | -- Value - The argument 85 | -- 86 | -- This function tests if Value represents a real number. Infinities and 87 | -- NaN are not numbers. Both zeros are considered numbers. 88 | -- 89 | -- Returns : 90 | -- 91 | -- True if Value represents a real number 92 | -- 93 | function Is_Real (Value : Float_64) return Boolean; 94 | -- 95 | -- Normalize -- Split number into integer mantissa and binary exponent 96 | -- 97 | -- Value - The argument 98 | -- Mantissa - The mantissa 99 | -- Exponent - The binary exponent 100 | -- 101 | procedure Normalize 102 | ( Value : Number; 103 | Mantissa : out Unsigned_64; 104 | Exponent : out Integer 105 | ); 106 | -- 107 | -- To_IEEE -- Conversion to 32-bit single precision IEEE 754 float 108 | -- 109 | -- Value - The argument 110 | -- 111 | -- The value to big for normalized representation results in the 112 | -- corresponding IEEE infinities. Too small values are represented as 113 | -- IEEE zero. 114 | -- 115 | -- Returns : 116 | -- 117 | -- The corresponding IEEE 754 representation 118 | -- 119 | function To_IEEE (Value : Number) return Float_64; 120 | 121 | private 122 | pragma Inline (Is_NaN); 123 | pragma Inline (Is_Negative); 124 | pragma Inline (Is_Real); 125 | pragma Inline (Normalize); 126 | 127 | Positive_Infinity : constant Float_64 := (16#7F#,16#F0#,others => 0); 128 | Positive_Zero : constant Float_64 := (others => 0); 129 | Negative_Infinity : constant Float_64 := (16#FF#,16#F8#,others => 0); 130 | Negative_Zero : constant Float_64 := (16#80#,others => 0); 131 | 132 | end IEEE_754.Generic_Double_Precision; 133 | -------------------------------------------------------------------------------- /tools/src/excel_writer/ieee_754.ads: -------------------------------------------------------------------------------- 1 | -- -- 2 | -- package IEEE_754 Copyright (c) Dmitry A. Kazakov -- 3 | -- Interface Luebeck -- 4 | -- Summer, 2008 -- 5 | -- -- 6 | -- Last revision : 11:26 27 Jul 2008 -- 7 | -- -- 8 | -- This library is free software; you can redistribute it and/or -- 9 | -- modify it under the terms of the GNU General Public License as -- 10 | -- published by the Free Software Foundation; either version 2 of -- 11 | -- the License, or (at your option) any later version. This library -- 12 | -- is distributed in the hope that it will be useful, but WITHOUT -- 13 | -- ANY WARRANTY; without even the implied warranty of -- 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- 15 | -- General Public License for more details. You should have -- 16 | -- received a copy of the GNU General Public License along with -- 17 | -- this library; if not, write to the Free Software Foundation, -- 18 | -- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -- 19 | -- -- 20 | -- As a special exception, if other files instantiate generics from -- 21 | -- this unit, or you link this unit with other files to produce an -- 22 | -- executable, this unit does not by itself cause the resulting -- 23 | -- executable to be covered by the GNU General Public License. This -- 24 | -- exception does not however invalidate any other reasons why the -- 25 | -- executable file might be covered by the GNU Public License. -- 26 | --____________________________________________________________________-- 27 | 28 | with Interfaces; 29 | 30 | package IEEE_754 is 31 | pragma Pure (IEEE_754); 32 | 33 | subtype Byte is Interfaces.Unsigned_8; 34 | 35 | Not_A_Number_Error : exception; 36 | Positive_Overflow_Error : exception; 37 | Negative_Overflow_Error : exception; 38 | 39 | end IEEE_754; 40 | -------------------------------------------------------------------------------- /tools/src/tool-data.adb: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------- 2 | -- tool-data -- Perf data representation 3 | -- Copyright (C) 2018 Stephane Carrez 4 | -- Written by Stephane Carrez (Stephane.Carrez@gmail.com) 5 | -- 6 | -- Licensed under the Apache License, Version 2.0 (the "License"); 7 | -- you may not use this file except in compliance with the License. 8 | -- You may obtain a copy of the License at 9 | -- 10 | -- http://www.apache.org/licenses/LICENSE-2.0 11 | -- 12 | -- Unless required by applicable law or agreed to in writing, software 13 | -- distributed under the License is distributed on an "AS IS" BASIS, 14 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | -- See the License for the specific language governing permissions and 16 | -- limitations under the License. 17 | ----------------------------------------------------------------------- 18 | with Ada.Text_IO; 19 | with Ada.Strings.Fixed; 20 | with Util.Strings; 21 | with Util.Log.Loggers; 22 | with Util.Serialize.IO.XML; 23 | with Util.Strings.Tokenizers; 24 | with Excel_Out; 25 | package body Tool.Data is 26 | 27 | use type Ada.Containers.Count_Type; 28 | use type Ada.Text_IO.Positive_Count; 29 | 30 | Log : constant Util.Log.Loggers.Logger := Util.Log.Loggers.Create ("Tool.Data"); 31 | 32 | function Parse_Time (Value : in String) return Duration; 33 | function Get_Title (Value : in String) return String; 34 | function Get_Value (Value : in String) return Row_Count_Type; 35 | procedure Collect_Result (Into : in out Perf_Result; 36 | Driver : in Driver_Type; 37 | Result : in Result_Type); 38 | procedure Add_Driver (Benchmark : in out Benchmark_Info); 39 | function Format (Value : in Duration) return String; 40 | function Format_Us (Value : in Duration) return String; 41 | 42 | Empty_Perf : Perf_Map; 43 | Empty_Perf_Result : Perf_Result; 44 | 45 | function Parse_Time (Value : in String) return Duration is 46 | Pos : constant Natural := Util.Strings.Index (Value, ' '); 47 | Result : Duration; 48 | begin 49 | Result := Duration'Value (Value (Value'First .. Pos - 1)); 50 | if Value (Pos + 1 .. Value'Last) = "ns" then 51 | Result := Result / 1_000_000_000; 52 | elsif Value (Pos + 1 .. Value'Last) = "us" then 53 | Result := Result / 1_000_000; 54 | elsif Value (Pos + 1 .. Value'Last) = "ms" then 55 | Result := Result / 1_000; 56 | end if; 57 | return Result; 58 | end Parse_Time; 59 | 60 | function Get_Title (Value : in String) return String is 61 | Pos : constant Natural := Util.Strings.Rindex (Value, ' '); 62 | begin 63 | if Pos = 0 or Value'Length < String '("SELECT * FROM")'Length then 64 | return Value; 65 | end if; 66 | for C of Value (Pos + 1 .. Value'Last) loop 67 | if not (C in '0' .. '9') then 68 | return Value; 69 | end if; 70 | end loop; 71 | return Value (Value'First .. Pos - 1); 72 | end Get_Title; 73 | 74 | function Get_Value (Value : in String) return Row_Count_Type is 75 | Pos : constant Natural := Util.Strings.Rindex (Value, ' '); 76 | begin 77 | if Value'Length < String '("SELECT * FROM")'Length then 78 | return 0; 79 | else 80 | return Row_Count_Type'Value (Value (Pos + 1 .. Value'Last)); 81 | end if; 82 | 83 | exception 84 | when Constraint_Error => 85 | return 0; 86 | end Get_Value; 87 | 88 | function Format (Value : in Duration) return String is 89 | begin 90 | if Value < 0.000_001 then 91 | return Duration'Image (Value * 1_000_000_000) (1 .. 6) & " ns"; 92 | elsif Value < 0.001 then 93 | return Duration'Image (Value * 1_000_000) (1 .. 6) & " us"; 94 | elsif Value < 1.0 then 95 | return Duration'Image (Value * 1_000) (1 .. 6) & " ms"; 96 | else 97 | return Duration'Image (Value) (1 .. 6) & " s"; 98 | end if; 99 | end Format; 100 | 101 | function Format_Us (Value : in Duration) return String is 102 | Result : constant String := Duration'Image (Value * 1_000_000); 103 | Pos : Positive := Result'Last; 104 | begin 105 | -- Drop leading zeros. 106 | while Pos > Result'First and then Result (Pos) = '0' and then Result (Pos - 1) /= '.' loop 107 | Pos := Pos - 1; 108 | end loop; 109 | return Result (Result'First .. Pos); 110 | end Format_Us; 111 | 112 | procedure Collect_Result (Into : in out Perf_Result; 113 | Driver : in Driver_Type; 114 | Result : in Result_Type) is 115 | procedure Update (Item : in out Result_Type); 116 | 117 | procedure Update (Item : in out Result_Type) is 118 | begin 119 | Item.Count := Item.Count + Result.Count; 120 | Item.Time := Item.Time + Result.Time; 121 | end Update; 122 | begin 123 | while Into.Results.Length < Ada.Containers.Count_Type (Driver) loop 124 | Into.Results.Append (Result_Type '(Count => 0, Time => 0.0)); 125 | end loop; 126 | Into.Results.Update_Element (Driver, Update'Access); 127 | end Collect_Result; 128 | 129 | procedure Add_Driver (Benchmark : in out Benchmark_Info) is 130 | 131 | procedure Update_Driver (Key : in String; 132 | Driver : in out Driver_Result); 133 | 134 | Database : constant String := UBO.To_String (Benchmark.Driver); 135 | Language : constant String := UBO.To_String (Benchmark.Language); 136 | Pos : Driver_Cursor := Benchmark.Drivers.Find (Language & " " & Database); 137 | New_Driver : Driver_Result; 138 | 139 | procedure Update_Driver (Key : in String; 140 | Driver : in out Driver_Result) is 141 | pragma Unreferenced (Key); 142 | begin 143 | Driver.Count := Driver.Count + 1; 144 | Driver.Rss_Size := Driver.Rss_Size + Benchmark.Rss_Size; 145 | Driver.Peek_Rss := Driver.Peek_Rss + Benchmark.Peek_Rss_Size; 146 | Driver.Thread_Count := Driver.Thread_Count + Benchmark.Thread_Count; 147 | Driver.User_Time := Driver.User_Time + Benchmark.User_Time; 148 | Driver.Sys_Time := Driver.Sys_Time + Benchmark.Sys_Time; 149 | Driver.Language := Benchmark.Language_Index; 150 | Driver.Database := Benchmark.Database_Index; 151 | Driver.Index := Benchmark.Driver_Index; 152 | end Update_Driver; 153 | 154 | begin 155 | Log.Debug ("Adding driver {0} {1}", Language, Database); 156 | if UBO.Is_Null (Benchmark.Driver) or else UBO.Is_Null (Benchmark.Language) then 157 | return; 158 | end if; 159 | if not Driver_Maps.Has_Element (Pos) then 160 | New_Driver.Index := Driver_Type (Benchmark.Drivers.Length + 1); 161 | Benchmark.Drivers.Insert (Language & " " & Database, New_Driver); 162 | Pos := Benchmark.Drivers.Find (Language & " " & Database); 163 | end if; 164 | Benchmark.Database_Index := Benchmark.Databases.Find_Index (Database); 165 | Benchmark.Language_Index := Benchmark.Languages.Find_Index (Language); 166 | Benchmark.Driver_Index := Driver_Maps.Element (Pos).Index; 167 | Benchmark.Drivers.Update_Element (Pos, Update_Driver'Access); 168 | end Add_Driver; 169 | 170 | procedure Set_Member (Benchmark : in out Benchmark_Info; 171 | Field : in Benchmark_Fields; 172 | Value : in UBO.Object) is 173 | begin 174 | case Field is 175 | when FIELD_DRIVER => 176 | if not Benchmark.Databases.Contains (UBO.To_String (Value)) then 177 | Benchmark.Databases.Append (UBO.To_String (Value)); 178 | end if; 179 | Benchmark.Driver := Value; 180 | 181 | when FIELD_LANGUAGE => 182 | if not Benchmark.Languages.Contains (UBO.To_String (Value)) then 183 | Benchmark.Languages.Append (UBO.To_String (Value)); 184 | end if; 185 | Benchmark.Language := Value; 186 | 187 | when FIELD_THREADS => 188 | Benchmark.Thread_Count := UBO.To_Integer (Value); 189 | 190 | when FIELD_RSS_SIZE => 191 | Benchmark.Rss_Size := UBO.To_Integer (Value); 192 | 193 | when FIELD_PEEK_RSS_SIZE => 194 | Benchmark.Peek_Rss_Size := UBO.To_Integer (Value); 195 | 196 | when FIELD_USER_TIME => 197 | Benchmark.User_Time := UBO.To_Integer (Value); 198 | 199 | when FIELD_SYS_TIME => 200 | Benchmark.Sys_Time := UBO.To_Integer (Value); 201 | 202 | when FIELD_MEASURES => 203 | Add_Driver (Benchmark); 204 | 205 | when FIELD_COUNT => 206 | Benchmark.Count := Count_Type (UBO.To_Integer (Value)); 207 | 208 | when FIELD_TITLE => 209 | Benchmark.Title := Value; 210 | 211 | when FIELD_TOTAL => 212 | Benchmark.Time := Parse_Time (UBO.To_String (Value)); 213 | 214 | when FIELD_TIME => 215 | declare 216 | 217 | procedure Update (Key : in String; 218 | Item : in out Perf_Map); 219 | procedure Update_Perf_Result (Key : in Row_Count_Type; 220 | Item : in out Perf_Result); 221 | 222 | Main_Title : constant String := UBO.To_String (Benchmark.Title); 223 | Title : constant String := Get_Title (Main_Title); 224 | Value : constant Row_Count_Type := Get_Value (Main_Title); 225 | Pos : Benchmark_Cursor := Benchmark.Benchmarks.Find (Title); 226 | Result : Result_Type; 227 | 228 | procedure Update_Perf_Result (Key : in Row_Count_Type; 229 | Item : in out Perf_Result) is 230 | pragma Unreferenced (Key); 231 | begin 232 | Collect_Result (Item, Benchmark.Driver_Index, Result); 233 | end Update_Perf_Result; 234 | 235 | procedure Update (Key : in String; 236 | Item : in out Perf_Map) is 237 | pragma Unreferenced (Key); 238 | Pos : Perf_Cursor := Item.Find (Value); 239 | begin 240 | if not Perf_Result_Maps.Has_Element (Pos) then 241 | Item.Insert (Value, Empty_Perf_Result); 242 | Pos := Item.Find (Value); 243 | end if; 244 | Item.Update_Element (Pos, Update_Perf_Result'Access); 245 | end Update; 246 | 247 | begin 248 | Result.Count := Benchmark.Count; 249 | Result.Time := Benchmark.Time; 250 | if not Benchmark_Maps.Has_Element (Pos) then 251 | Benchmark.Benchmarks.Insert (Title, Empty_Perf); 252 | Pos := Benchmark.Benchmarks.Find (Title); 253 | end if; 254 | Benchmark.Benchmarks.Update_Element (Pos, Update'Access); 255 | end; 256 | 257 | end case; 258 | end Set_Member; 259 | 260 | Mapping : aliased Benchmark_Mapper.Mapper; 261 | Benchmark : aliased Benchmark_Info; 262 | 263 | procedure Read (Path : in String) is 264 | Mapper : Util.Serialize.Mappers.Processing; 265 | Reader : Util.Serialize.IO.XML.Parser; 266 | begin 267 | Benchmark.User_Time := 0; 268 | Benchmark.Sys_Time := 0; 269 | Benchmark.Thread_Count := 0; 270 | Benchmark.Rss_Size := 0; 271 | Benchmark.Peek_Rss_Size := 0; 272 | Benchmark.Language := UBO.Null_Object; 273 | Benchmark.Driver := UBO.Null_Object; 274 | Mapper.Add_Mapping ("benchmark", Mapping'Access); 275 | Benchmark_Mapper.Set_Context (Mapper, Benchmark'Access); 276 | Reader.Parse (Path, Mapper); 277 | end Read; 278 | 279 | procedure Save_Memory (Path : in String; 280 | Languages : in String) is 281 | 282 | procedure Process_Language (Token : in String; 283 | Done : out Boolean); 284 | 285 | File : Ada.Text_IO.File_Type; 286 | 287 | procedure Process_Language (Token : in String; 288 | Done : out Boolean) is 289 | L : constant Language_Type := Benchmark.Languages.Find_Index (Token); 290 | begin 291 | Done := False; 292 | for D in Benchmark.Drivers.Iterate loop 293 | declare 294 | Driver : constant Driver_Result := Driver_Maps.Element (D); 295 | begin 296 | if Driver.Language = L then 297 | Ada.Text_IO.Put (File, Benchmark.Databases.Element (Driver.Database)); 298 | Ada.Text_IO.Set_Col (File, 20); 299 | Ada.Text_IO.Put (File, Benchmark.Languages.Element (L)); 300 | Ada.Text_IO.Set_Col (File, 30); 301 | Ada.Text_IO.Put (File, Natural'Image (Driver.User_Time)); 302 | Ada.Text_IO.Set_Col (File, 40); 303 | Ada.Text_IO.Put (File, Natural'Image (Driver.Sys_Time)); 304 | Ada.Text_IO.Set_Col (File, 60); 305 | Ada.Text_IO.Put (File, Natural'Image (Driver.Peek_Rss)); 306 | Ada.Text_IO.Set_Col (File, 70); 307 | Ada.Text_IO.Put (File, Natural'Image (Driver.Thread_Count)); 308 | Ada.Text_IO.New_Line (File); 309 | end if; 310 | end; 311 | end loop; 312 | Ada.Text_IO.New_Line (File); 313 | Ada.Text_IO.New_Line (File); 314 | end Process_Language; 315 | 316 | begin 317 | Ada.Text_IO.Create (File => File, 318 | Mode => Ada.Text_IO.Out_File, 319 | Name => Path); 320 | Util.Strings.Tokenizers.Iterate_Tokens (Content => Languages, 321 | Pattern => ",", 322 | Process => Process_Language'Access); 323 | Ada.Text_IO.Close (File); 324 | end Save_Memory; 325 | 326 | procedure Save (Path : in String; 327 | Databases : in String; 328 | Languages : in String) is 329 | 330 | procedure Process_Database (Token : in String; 331 | Done : out Boolean); 332 | procedure Process_Language (Token : in String; 333 | Done : out Boolean); 334 | 335 | DB_Count : constant Natural := Ada.Strings.Fixed.Count (Databases, ",") + 1; 336 | DB_List : Database_Array_Index (1 .. DB_Count); 337 | Lang_Count : constant Natural := Ada.Strings.Fixed.Count (Languages, ",") + 1; 338 | Lang_List : Language_Array_Index (1 .. Lang_Count); 339 | Pos : Positive := 1; 340 | Col : Ada.Text_IO.Positive_Count; 341 | File : Ada.Text_IO.File_Type; 342 | 343 | procedure Process_Database (Token : in String; 344 | Done : out Boolean) is 345 | begin 346 | DB_List (Pos) := Benchmark.Databases.Find_Index (Token); 347 | Pos := Pos + 1; 348 | Done := False; 349 | end Process_Database; 350 | 351 | procedure Process_Language (Token : in String; 352 | Done : out Boolean) is 353 | begin 354 | Lang_List (Pos) := Benchmark.Languages.Find_Index (Token); 355 | Pos := Pos + 1; 356 | Done := False; 357 | end Process_Language; 358 | 359 | begin 360 | Util.Strings.Tokenizers.Iterate_Tokens (Content => Databases, 361 | Pattern => ",", 362 | Process => Process_Database'Access); 363 | Pos := 1; 364 | Util.Strings.Tokenizers.Iterate_Tokens (Content => Languages, 365 | Pattern => ",", 366 | Process => Process_Language'Access); 367 | 368 | Ada.Text_IO.Create (File => File, 369 | Mode => Ada.Text_IO.Out_File, 370 | Name => Path); 371 | 372 | -- Print performance results. 373 | Ada.Text_IO.Put (File, "# order is "); 374 | Ada.Text_IO.Put (File, Databases); 375 | Ada.Text_IO.Put (File, " and "); 376 | Ada.Text_IO.Put (File, Languages); 377 | Ada.Text_IO.New_Line (File); 378 | 379 | for C in Benchmark.Benchmarks.Iterate loop 380 | for P in Benchmark_Maps.Element (C).Iterate loop 381 | if Perf_Result_Maps.Key (P) > 0 then 382 | Ada.Text_IO.Put (File, Row_Count_Type'Image (Perf_Result_Maps.Key (P))); 383 | for DB_Index of DB_List loop 384 | for Lang_Index of Lang_List loop 385 | declare 386 | Database : constant String := Benchmark.Databases.Element (DB_Index); 387 | Language : constant String := Benchmark.Languages.Element (Lang_Index); 388 | Key : constant String := Language & " " & Database; 389 | Driver : constant Driver_Cursor := Benchmark.Drivers.Find (Key); 390 | R : Result_Type; 391 | Index : Driver_Type; 392 | begin 393 | if Driver_Maps.Has_Element (Driver) then 394 | Index := Driver_Maps.Element (Driver).Index; 395 | if Perf_Result_Maps.Element (P).Results.Last_Index >= Index then 396 | R := Perf_Result_Maps.Element (P).Results.Element (Index); 397 | if R.Count > 0 then 398 | Ada.Text_IO.Put 399 | (File, Format_Us (R.Time / Positive (R.Count))); 400 | else 401 | Ada.Text_IO.Put (File, " 0"); 402 | end if; 403 | else 404 | Ada.Text_IO.Put (File, " 0"); 405 | end if; 406 | else 407 | Ada.Text_IO.Put (File, " 0"); 408 | end if; 409 | end; 410 | end loop; 411 | end loop; 412 | Ada.Text_IO.New_Line (File); 413 | end if; 414 | end loop; 415 | end loop; 416 | 417 | -- Print results grouped by benchmark. 418 | for C in Benchmark.Benchmarks.Iterate loop 419 | for P in Benchmark_Maps.Element (C).Iterate loop 420 | declare 421 | Row_Count : constant Row_Count_Type := Perf_Result_Maps.Key (P); 422 | begin 423 | Ada.Text_IO.New_Line; 424 | Ada.Text_IO.Put ("## "); 425 | if Row_Count > 0 then 426 | Ada.Text_IO.Put (Benchmark_Maps.Key (C) & Row_Count_Type'Image (Row_Count)); 427 | else 428 | Ada.Text_IO.Put (Benchmark_Maps.Key (C)); 429 | end if; 430 | 431 | Ada.Text_IO.New_Line; 432 | Ada.Text_IO.New_Line; 433 | Ada.Text_IO.Put ("| "); 434 | Col := 25; 435 | for DB_Index of DB_List loop 436 | Ada.Text_IO.Set_Col (Col); 437 | Ada.Text_IO.Put ("| "); 438 | Ada.Text_IO.Put (Benchmark.Databases.Element (DB_Index)); 439 | Col := Col + 16; 440 | end loop; 441 | 442 | Ada.Text_IO.Set_Col (Col); 443 | Ada.Text_IO.Put_Line ("|"); 444 | 445 | Ada.Text_IO.Put ("|-----------------------|"); 446 | for DB_Index of DB_List loop 447 | Ada.Text_IO.Put ("---------------|"); 448 | end loop; 449 | Ada.Text_IO.New_Line; 450 | 451 | for L in 1 .. Benchmark.Languages.Last_Index loop 452 | declare 453 | Language : constant String := Benchmark.Languages.Element (L); 454 | begin 455 | Ada.Text_IO.Put ("| "); 456 | Ada.Text_IO.Put (Language); 457 | Col := 25; 458 | for DB_Index of DB_List loop 459 | declare 460 | Database : constant String := Benchmark.Databases.Element (DB_Index); 461 | Key : constant String := Language & " " & Database; 462 | Driver : constant Driver_Cursor := Benchmark.Drivers.Find (Key); 463 | R : Result_Type; 464 | Index : Driver_Type; 465 | begin 466 | Ada.Text_IO.Set_Col (Col); 467 | Ada.Text_IO.Put ("| "); 468 | if Driver_Maps.Has_Element (Driver) then 469 | Index := Driver_Maps.Element (Driver).Index; 470 | if Perf_Result_Maps.Element (P).Results.Last_Index >= Index then 471 | R := Perf_Result_Maps.Element (P).Results.Element (Index); 472 | if R.Count > 0 then 473 | Ada.Text_IO.Put 474 | (Format (R.Time / Positive (R.Count))); 475 | end if; 476 | end if; 477 | end if; 478 | end; 479 | Col := Col + 16; 480 | end loop; 481 | Ada.Text_IO.Set_Col (Col); 482 | Ada.Text_IO.Put_Line ("|"); 483 | end; 484 | end loop; 485 | end; 486 | end loop; 487 | end loop; 488 | end Save; 489 | 490 | procedure Save_Excel (Path : in String) is 491 | File : Excel_Out.Excel_Out_File; 492 | Row : Positive := 1; 493 | Col : Positive := 1; 494 | Font_Title : Excel_Out.Font_type; 495 | Font_Sub : Excel_Out.Font_type; 496 | Font_Cell : Excel_Out.Font_type; 497 | Fmt_Title : Excel_Out.Format_type; 498 | Fmt_Value : Excel_Out.Format_type; 499 | Fmt_Lang : Excel_Out.Format_type; 500 | Fmt_Database : Excel_Out.Format_type; 501 | begin 502 | File.Create (Path); 503 | File.Header ("Driver SQL Benchmark"); 504 | File.Footer ("sql-benchmark"); 505 | File.Margins (1.2, 1.1, 0.9, 0.8); 506 | File.Page_Setup (scaling_percents => 100, 507 | fit_width_with_n_pages => 0, 508 | orientation => Excel_Out.portrait, 509 | scale_or_fit => Excel_Out.fit); 510 | 511 | File.Write_column_width (1, 15); 512 | File.Write_column_width (2, 20); 513 | File.Write_column_width (3, 20); 514 | File.Write_column_width (4, 20); 515 | 516 | File.Define_font ("Calibri", 14, Font_Title, Excel_Out.bold); 517 | File.Define_font ("Calibri", 12, Font_Sub, Excel_Out.bold); 518 | File.Define_font ("Calibri", 12, Font_Cell, Excel_Out.regular); 519 | File.Define_format (font => Font_Title, 520 | number_format => Excel_Out.general, 521 | cell_format => Fmt_Title); 522 | 523 | File.Define_format (font => Font_Cell, 524 | number_format => Excel_Out.general, 525 | border => Excel_Out.box, 526 | cell_format => Fmt_Value); 527 | File.Define_format (font => Font_Sub, 528 | number_format => Excel_Out.general, 529 | cell_format => Fmt_Lang, 530 | border => Excel_Out.box); 531 | File.Define_format (font => Font_Sub, 532 | number_format => Excel_Out.general, 533 | cell_format => Fmt_Database, 534 | border => Excel_Out.box); 535 | 536 | for C in Benchmark.Benchmarks.Iterate loop 537 | for P in Benchmark_Maps.Element (C).Iterate loop 538 | declare 539 | Row_Count : constant Row_Count_Type := Perf_Result_Maps.Key (P); 540 | begin 541 | Row := Row + 2; 542 | File.Use_format (Fmt_Title); 543 | if Row_Count > 0 then 544 | File.Write (Row, 2, Benchmark_Maps.Key (C) & Row_Count_Type'Image (Row_Count)); 545 | else 546 | File.Write (Row, 2, Benchmark_Maps.Key (C)); 547 | end if; 548 | 549 | File.Use_format (Fmt_Database); 550 | Row := Row + 1; 551 | 552 | Col := 2; 553 | for Database of Benchmark.Databases loop 554 | File.Write (Row, Col, Database); 555 | Col := Col + 1; 556 | end loop; 557 | 558 | for L in 1 .. Benchmark.Languages.Last_Index loop 559 | declare 560 | Language : constant String := Benchmark.Languages.Element (L); 561 | begin 562 | Row := Row + 1; 563 | File.Use_format (Fmt_Lang); 564 | File.Write (Row, 1, Language); 565 | File.Use_format (Fmt_Value); 566 | Col := 2; 567 | for D in 1 .. Benchmark.Databases.Last_Index loop 568 | declare 569 | Database : constant String := Benchmark.Databases.Element (D); 570 | Key : constant String := Language & " " & Database; 571 | Driver : constant Driver_Cursor := Benchmark.Drivers.Find (Key); 572 | R : Result_Type; 573 | Index : Driver_Type; 574 | begin 575 | if Driver_Maps.Has_Element (Driver) then 576 | Index := Driver_Maps.Element (Driver).Index; 577 | if Perf_Result_Maps.Element (P).Results.Last_Index >= Index then 578 | R := Perf_Result_Maps.Element (P).Results.Element (Index); 579 | if R.Count > 0 then 580 | File.Write (Row, Col, Format (R.Time / Positive (R.Count))); 581 | end if; 582 | end if; 583 | end if; 584 | end; 585 | Col := Col + 1; 586 | end loop; 587 | end; 588 | end loop; 589 | end; 590 | end loop; 591 | end loop; 592 | File.Close; 593 | end Save_Excel; 594 | 595 | begin 596 | Mapping.Add_Mapping ("@driver", FIELD_DRIVER); 597 | Mapping.Add_Mapping ("@language", FIELD_LANGUAGE); 598 | Mapping.Add_Mapping ("@threads", FIELD_THREADS); 599 | Mapping.Add_Mapping ("@rss_size", FIELD_RSS_SIZE); 600 | Mapping.Add_Mapping ("@peek_rss_size", FIELD_PEEK_RSS_SIZE); 601 | Mapping.Add_Mapping ("@user_time", FIELD_USER_TIME); 602 | Mapping.Add_Mapping ("@sys_time", FIELD_SYS_TIME); 603 | Mapping.Add_Mapping ("measures/@title", FIELD_MEASURES); 604 | Mapping.Add_Mapping ("measures/time/@count", FIELD_COUNT); 605 | Mapping.Add_Mapping ("measures/time/@total", FIELD_TOTAL); 606 | Mapping.Add_Mapping ("measures/time/@title", FIELD_TITLE); 607 | Mapping.Add_Mapping ("measures/time", FIELD_TIME); 608 | end Tool.Data; 609 | -------------------------------------------------------------------------------- /tools/src/tool-data.ads: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------- 2 | -- tool-data -- Perf data representation 3 | -- Copyright (C) 2018 Stephane Carrez 4 | -- Written by Stephane Carrez (Stephane.Carrez@gmail.com) 5 | -- 6 | -- Licensed under the Apache License, Version 2.0 (the "License"); 7 | -- you may not use this file except in compliance with the License. 8 | -- You may obtain a copy of the License at 9 | -- 10 | -- http://www.apache.org/licenses/LICENSE-2.0 11 | -- 12 | -- Unless required by applicable law or agreed to in writing, software 13 | -- distributed under the License is distributed on an "AS IS" BASIS, 14 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | -- See the License for the specific language governing permissions and 16 | -- limitations under the License. 17 | ----------------------------------------------------------------------- 18 | with Ada.Containers.Vectors; 19 | with Ada.Containers.Ordered_Maps; 20 | with Ada.Containers.Indefinite_Ordered_Maps; 21 | private with Ada.Containers.Indefinite_Vectors; 22 | private with Util.Beans.Objects; 23 | private with Util.Serialize.Mappers.Record_Mapper; 24 | 25 | pragma No_Recursion; 26 | 27 | package Tool.Data is 28 | 29 | -- Type representing a number of times a benchmark test is executed. 30 | type Count_Type is new Natural; 31 | 32 | -- Type representing the number of rows associated with the benchmark. 33 | type Row_Count_Type is new Natural; 34 | 35 | -- Type representing a driver index. 36 | type Driver_Type is new Positive; 37 | 38 | -- Type representing a language index. 39 | type Language_Type is new Positive; 40 | 41 | -- Type representing a database index. 42 | type Database_Type is new Positive; 43 | 44 | type Driver_Result is record 45 | Index : Driver_Type := Driver_Type'First; 46 | Language : Language_Type := Language_Type'First; 47 | Database : Database_Type := Database_Type'First; 48 | Count : Count_Type := 0; 49 | Thread_Count : Natural := 0; 50 | Rss_Size : Natural := 0; 51 | Peek_Rss : Natural := 0; 52 | User_Time : Natural := 0; 53 | Sys_Time : Natural := 0; 54 | end record; 55 | 56 | type Result_Type is record 57 | Count : Count_Type; 58 | Time : Duration; 59 | end record; 60 | 61 | package Result_Vectors is 62 | new Ada.Containers.Vectors (Index_Type => Driver_Type, 63 | Element_Type => Result_Type, 64 | "=" => "="); 65 | 66 | type Perf_Result is record 67 | Value : Row_Count_Type := 0; 68 | Results : Result_Vectors.Vector; 69 | end record; 70 | 71 | package Perf_Result_Maps is 72 | new Ada.Containers.Ordered_Maps (Key_Type => Row_Count_Type, 73 | Element_Type => Perf_Result, 74 | "<" => "<", 75 | "=" => "="); 76 | subtype Perf_Map is Perf_Result_Maps.Map; 77 | subtype Perf_Cursor is Perf_Result_Maps.Cursor; 78 | 79 | package Benchmark_Maps is 80 | new Ada.Containers.Indefinite_Ordered_Maps (Key_Type => String, 81 | Element_Type => Perf_Map, 82 | "<" => "<", 83 | "=" => Perf_Result_Maps."="); 84 | subtype Benchmark_Map is Benchmark_Maps.Map; 85 | subtype Benchmark_Cursor is Benchmark_Maps.Cursor; 86 | 87 | procedure Read (Path : in String); 88 | 89 | procedure Save (Path : in String; 90 | Databases : in String; 91 | Languages : in String) with 92 | Pre => Databases'Length > 0 and Languages'Length > 0; 93 | 94 | procedure Save_Memory (Path : in String; 95 | Languages : in String) with 96 | Pre => Languages'Length > 0; 97 | 98 | procedure Save_Excel (Path : in String); 99 | 100 | private 101 | 102 | package UBO renames Util.Beans.Objects; 103 | 104 | package Driver_Maps is 105 | new Ada.Containers.Indefinite_Ordered_Maps (Key_Type => String, 106 | Element_Type => Driver_Result, 107 | "<" => "<"); 108 | subtype Driver_Map is Driver_Maps.Map; 109 | subtype Driver_Cursor is Driver_Maps.Cursor; 110 | 111 | package Language_Vectors is 112 | new Ada.Containers.Indefinite_Vectors (Index_Type => Language_Type, 113 | Element_Type => String); 114 | subtype Language_Vector is Language_Vectors.Vector; 115 | subtype Language_Cursor is Language_Vectors.Cursor; 116 | 117 | package Database_Vectors is 118 | new Ada.Containers.Indefinite_Vectors (Index_Type => Database_Type, 119 | Element_Type => String); 120 | subtype Database_Vector is Database_Vectors.Vector; 121 | subtype Database_Cursor is Database_Vectors.Cursor; 122 | 123 | -- Array of database index. 124 | type Database_Array_Index is array (Positive range <>) of Database_Type; 125 | 126 | -- Array of language index. 127 | type Language_Array_Index is array (Positive range <>) of Language_Type; 128 | 129 | type Benchmark_Fields is (FIELD_DRIVER, 130 | FIELD_LANGUAGE, 131 | FIELD_THREADS, 132 | FIELD_RSS_SIZE, 133 | FIELD_PEEK_RSS_SIZE, 134 | FIELD_USER_TIME, 135 | FIELD_SYS_TIME, 136 | FIELD_COUNT, 137 | FIELD_TIME, 138 | FIELD_TITLE, 139 | FIELD_MEASURES, 140 | FIELD_TOTAL); 141 | 142 | type Benchmark_Info is record 143 | Drivers : Driver_Map; 144 | Databases : Database_Vector; 145 | Languages : Language_Vector; 146 | Benchmarks : Benchmark_Map; 147 | Thread_Count : Natural := 0; 148 | Rss_Size : Natural := 0; 149 | Peek_Rss_Size : Natural := 0; 150 | User_Time : Natural := 0; 151 | Sys_Time : Natural := 0; 152 | Count : Count_Type := 0; 153 | Driver : UBO.Object; 154 | Language : UBO.Object; 155 | Title : UBO.Object; 156 | Time : Duration := 0.0; 157 | Driver_Index : Driver_Type := Driver_Type'First; 158 | Language_Index : Language_Type; 159 | Database_Index : Database_Type; 160 | end record; 161 | type Benchmark_Info_Access is access all Benchmark_Info; 162 | 163 | procedure Set_Member (Benchmark : in out Benchmark_Info; 164 | Field : in Benchmark_Fields; 165 | Value : in UBO.Object); 166 | 167 | package Benchmark_Mapper is 168 | new Util.Serialize.Mappers.Record_Mapper (Element_Type => Benchmark_Info, 169 | Element_Type_Access => Benchmark_Info_Access, 170 | Fields => Benchmark_Fields, 171 | Set_Member => Set_Member); 172 | 173 | end Tool.Data; 174 | -------------------------------------------------------------------------------- /tools/src/tool-main.adb: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------- 2 | -- tool-main -- Main tool program 3 | -- Copyright (C) 2018 Stephane Carrez 4 | -- Written by Stephane Carrez (Stephane.Carrez@gmail.com) 5 | -- 6 | -- Licensed under the Apache License, Version 2.0 (the "License"); 7 | -- you may not use this file except in compliance with the License. 8 | -- You may obtain a copy of the License at 9 | -- 10 | -- http://www.apache.org/licenses/LICENSE-2.0 11 | -- 12 | -- Unless required by applicable law or agreed to in writing, software 13 | -- distributed under the License is distributed on an "AS IS" BASIS, 14 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | -- See the License for the specific language governing permissions and 16 | -- limitations under the License. 17 | ----------------------------------------------------------------------- 18 | with Ada.Command_Line; 19 | 20 | with Util.Log.Loggers; 21 | with Tool.Data; 22 | procedure Tool.Main is 23 | 24 | Log : constant Util.Log.Loggers.Logger := Util.Log.Loggers.Create ("Tool.Main"); 25 | 26 | begin 27 | Util.Log.Loggers.Initialize ("tool.properties"); 28 | 29 | for I in 1 .. Ada.Command_Line.Argument_Count loop 30 | Tool.Data.Read (Ada.Command_Line.Argument (I)); 31 | end loop; 32 | 33 | Tool.Data.Save ("result.dat", "sqlite,mysql,postgresql", "Ada,Python,Java"); 34 | Tool.Data.Save_Memory ("memory.dat", "Ada,Python,Java"); 35 | Tool.Data.Save_Excel ("result.xls"); 36 | 37 | exception 38 | when E : others => 39 | Log.Error (Message => "Internal error:", 40 | E => E, 41 | Trace => True); 42 | end Tool.Main; 43 | -------------------------------------------------------------------------------- /tools/src/tool.ads: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------- 2 | -- tool -- Tool to reconcile the SQL benchmark results 3 | -- Copyright (C) 2018 Stephane Carrez 4 | -- Written by Stephane Carrez (Stephane.Carrez@gmail.com) 5 | -- 6 | -- Licensed under the Apache License, Version 2.0 (the "License"); 7 | -- you may not use this file except in compliance with the License. 8 | -- You may obtain a copy of the License at 9 | -- 10 | -- http://www.apache.org/licenses/LICENSE-2.0 11 | -- 12 | -- Unless required by applicable law or agreed to in writing, software 13 | -- distributed under the License is distributed on an "AS IS" BASIS, 14 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | -- See the License for the specific language governing permissions and 16 | -- limitations under the License. 17 | ----------------------------------------------------------------------- 18 | package Tool is 19 | pragma Pure; 20 | end Tool; 21 | -------------------------------------------------------------------------------- /tools/tool.gpr.in: -------------------------------------------------------------------------------- 1 | with "@UTIL_DIR@config"; 2 | with "@UTIL_DIR@utilada_sys"; 3 | with "@UTIL_DIR@utilada_xml"; 4 | 5 | project tool is 6 | 7 | Mains := ("tool-main.adb"); 8 | for Main use Mains; 9 | for Source_Dirs use ("src", "src/excel_writer"); 10 | for Object_Dir use "./" & Config'Object_Dir & "/obj"; 11 | for Exec_Dir use "./" & Config'Exec_Dir & "/bin"; 12 | 13 | package Binder renames Config.Binder; 14 | package Builder renames Config.Builder; 15 | package Compiler is 16 | for Default_Switches use Config.Compiler'Default_Switches; 17 | for Switches ("excel*") 18 | use ("-gnatnwua"); 19 | for Switches ("ieee_754*") 20 | use ("-gnatnwua"); 21 | end Compiler; 22 | package Linker renames Config.Linker; 23 | 24 | end tool; 25 | -------------------------------------------------------------------------------- /tools/tool.properties: -------------------------------------------------------------------------------- 1 | 2 | # Configuration for log4j 3 | log4j.rootCategory=DEBUG,console,result 4 | log4j.appender.console=Console 5 | log4j.appender.console.level=DEBUG 6 | log4j.appender.console.layout=level-message 7 | log4j.appender.result=File 8 | log4j.appender.result.File=tool.log 9 | 10 | # Logger configuration 11 | log4j.logger.log=WARN 12 | log4j.logger.Util.Properties=DEBUG 13 | log4j.logger.Util.Log=WARN 14 | log4j.logger.Util=DEBUG 15 | log4j.logger.Util.Serialize.Mappers=WARN 16 | log4j.logger.Util.Serialize.IO=INFO 17 | log4j.logger.Tool=DEBUG 18 | --------------------------------------------------------------------------------