├── .gitignore ├── .gitmodules ├── CHANGELOG ├── LICENSE ├── LICENSE.zentus ├── Makefile ├── Makefile.common ├── Makefile.package ├── NOTICE ├── README.md ├── README_BUILD.md ├── SQLiteJDBC.wiki ├── VERSION ├── amalgamation_version.sh ├── archive ├── nestedvm-2007-06-30.tgz ├── nestedvm-2009-08-09.tgz ├── regex3.8a.tar.gz └── sqlite-jdbc4-3.8.2-SNAPSHOT.jar ├── demo ├── AppletDemo.jar └── applet-demo.html ├── lib ├── inc_linux │ └── jni_md.h ├── inc_win │ ├── jni.h │ └── jni_md.h ├── jdbc-api-1.4.jar ├── junit-4.5.jar └── org │ └── sqlite │ └── OSInfo.class ├── maven-eclipse.xml ├── pom.xml └── src ├── main ├── ext │ └── extension-functions.c ├── java │ └── org │ │ └── sqlite │ │ ├── ExtendedCommand.java │ │ ├── Function.java │ │ ├── JDBC.java │ │ ├── SQLiteConfig.java │ │ ├── SQLiteConnection.java │ │ ├── SQLiteDataSource.java │ │ ├── SQLiteErrorCode.java │ │ ├── SQLiteJDBCLoader.java │ │ ├── SQLiteOpenMode.java │ │ ├── core │ │ ├── Codes.java │ │ ├── CoreConnection.java │ │ ├── CoreDatabaseMetaData.java │ │ ├── CorePreparedStatement.java │ │ ├── CoreResultSet.java │ │ ├── CoreStatement.java │ │ ├── DB.java │ │ ├── NativeDB.c │ │ ├── NativeDB.java │ │ └── StringEscaper.java │ │ ├── javax │ │ ├── SQLiteConnectionPoolDataSource.java │ │ └── SQLitePooledConnection.java │ │ ├── jdbc3 │ │ ├── JDBC3Connection.java │ │ ├── JDBC3DatabaseMetaData.java │ │ ├── JDBC3PreparedStatement.java │ │ ├── JDBC3ResultSet.java │ │ └── JDBC3Statement.java │ │ ├── jdbc4 │ │ ├── JDBC4Connection.java │ │ ├── JDBC4DatabaseMetaData.java │ │ ├── JDBC4PooledConnection.java │ │ ├── JDBC4PreparedStatement.java │ │ ├── JDBC4ResultSet.java │ │ └── JDBC4Statement.java │ │ └── util │ │ ├── OSInfo.java │ │ └── ResourceFinder.java ├── resources │ ├── java.sql.Driver │ └── org │ │ └── sqlite │ │ ├── SQLite.class │ │ └── native │ │ └── Mac │ │ └── x86_64 │ │ └── libsqlitejdbc.jnilib └── target │ ├── sample.db1121577371722804844 │ ├── sample.db3781345977843727311 │ ├── sample.db5118308387616140847 │ ├── sample.db5146130081809857960 │ ├── testdb.jar7561007154787325801 │ └── testdb.jar7707595110025748705 └── test └── java └── org └── sqlite ├── AllTests.java ├── BackupTest.java ├── ConnectionTest.java ├── DBMetaDataTest.java ├── EncryptedTest.java ├── ExtendedCommandTest.java ├── ExtensionTest.java ├── FetchSizeTest.java ├── InsertQueryTest.java ├── JDBCTest.java ├── OSInfoTest.java ├── PrepStmtTest.java ├── QueryTest.java ├── RSMetaDataTest.java ├── ReadUncommittedTest.java ├── SQLiteConfigTest.java ├── SQLiteConnectionPoolDataSourceTest.java ├── SQLiteDataSourceTest.java ├── SQLiteJDBCLoaderTest.java ├── StatementTest.java ├── TransactionTest.java ├── UDFTest.java ├── sample.db └── testdb.jar /.gitignore: -------------------------------------------------------------------------------- 1 | .* 2 | !.gitignore 3 | *~ 4 | *.iml 5 | 6 | /scratch/ 7 | /target/ 8 | /ext/ 9 | /ant -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "sqlcipher"] 2 | path = sqlcipher 3 | url = git@github.com:sqlcipher/sqlcipher.git 4 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | Work in progress: 2 | 3 | * Issue #107 - DatabaseMetaData.getPrimaryKeys does not always return all primary keys for multi-line table definitions. 4 | * Issue #109 - SQLiteConfig ignores calls to setDateStringFormat/setDateClass/setDatePrecision. 5 | * Issue #116 - Move to Java 6 6 | * Created new branch refactor/JDBC4 7 | * Jar is packaged as sqlite-jdbc4* 8 | * Issue #65 - Calling Statement.setMaxRows(N) has the effect of returning N+1 rows 9 | * Issue #64 - ArrayIndexOutOfBoundsException when calling ResultSetMetaData.getScale() for VARCHAR column types 10 | * Issue #56 - Implement getBinaryStream() in RS.java 11 | * Issue #45 - Stmt.close() should not close metadata 12 | * Issue #49 - PreparedStatement.getUpdateCount should return -1 if the current result is a ResultSet or no more results exist 13 | * Issue #48 - PreparedStatement.getResultSet should return null if current result is an update 14 | * Issue #67 - Bad ResultSet returned from DatabaseMetaData.getColumns(), if a given table doesn't exist 15 | * Issue #73 - DatabaseMetaData.getTables() Memory Leak 16 | * Issue #68 - DatabaseMetaData.getTables() erroneously returns INDEX, TRIGGER, and other non-table objects 17 | * Issue #53 - getImportedKeys throws Null Exception for foreign key without explicit primary column name 18 | * Issue #18 - Add support for ConnectionPool 19 | * Implemented javax.sql.ConnectionPoolDataSource - javax.SQLiteConnectionPoolDataSource 20 | * Issue #27 - Allow user to specify busy-timeout when opening a database connection 21 | * Added support for sqlite3_busy_timeout 22 | 1. Added configuration property "busy_timeout" to SQLiteConfig. 23 | 2. Exposed setBusyTimeout and getBusyTimeout on SQLiteConnection. 24 | 3. Default busy_timeout of 3 seconds (3000ms) remains the same. 25 | * Issue #60 - ExtendedCommand (e.g backup) not supported on Stmt.execute(String) 26 | * Issue #23 - getDate() returns wrong values 27 | * Added support for specifying a date storage class. For more info 28 | * Issue #54 - Implement PreparedStatement.setBinaryStream() 29 | * Added support for InputStreams on PreparedStatement 30 | 1. setBinaryStream() 31 | 2. setAsciiStream() 32 | 3. setUnicodeStream() 33 | * Issue #60 - ExtendedCommand (e.g backup) not supported on Stmt.execute(String) 34 | * Issue #23 - getDate() returns wrong values 35 | * Added support for specifying a date storage class. For more info 36 | * Issue #54 - Implement PreparedStatement.setBinaryStream() 37 | * Added support for InputStreams on PreparedStatement 38 | 1. setBinaryStream() 39 | 2. setAsciiStream() 40 | 3. setUnicodeStream() 41 | 42 | Release 3.7.15-SNAPSHOT-2 43 | * Fixed clean target to remove previous driver builds 44 | * Issue #42 - Using shared in-memory with URI filename 45 | * Added support for URI filenames 46 | 1. examples 47 | * Issue #47 - MetaData.getExportedKeys() returns empty string for a named foreign key 48 | * Issue #46 - org.sqlite.MetaData.getExportedKeys constructs incorrect SQL 49 | * Issue #44 - getExportedKeys throws Null Exception for foreign key without explicit primary column name 50 | 1. Now returns keys for foreign key definitions like "create table referring (id, foreign key references referred)" 51 | * Implemented getPercision(int) and getScale(int) on ResultSetMetaData. 52 | * Issue #43 - ResultSetMetaData does not return the SQL Type if there are no results from the query. 53 | 1. ResultSetMetaData.getColumnTypeName() now gets type from either 'create table' statement or CAST(expr AS TYPE) otherwise sqlite3_value_type. 54 | 2. ResultSetMetaData.getColumnType() now parses the result from getColumnTypeName() to return a type. 55 | 3. Driver recognizes the types listed at under 'Affinity Name Examples'. 56 | * Issue #36 - Fixed case where a calling PreparedStatement.clearParameters() after a ResultSet is opened, caused subsequent calls to the ResultSet to return null. 57 | 1. PreparedStatement.clearParameters() now uses sqlite3_clear_bindings instead of sqlite3_reset. 58 | 2. PreparedStatement.clearParameters() does not reset current ResultSet. 59 | 3. PreparedStatement now checks if value(s) are bound to the statement parameters before executing; Throwing an exception if they are not. 60 | * Issue #40 - Fixed case where a call to Statement.getGeneratedKeys() could lead to "database is locked" error. 61 | 1. Calling Statement.Close() on a Statement on which getGeneratedKeys() was called, now releases all resources properly. 62 | * Issue #33 - Fixed Statement.cancel() to work when called from another thread 63 | 64 | Release 3.7.15-SNAPSHOT 65 | * Issue #10 - Dropped pure java support 66 | * Issue #22 - Fixed DatabaseMetaData.supportsGetGeneratedKeys to return true since it's already supported 67 | * Issue #17 - Enabled Statement.setEscapeProcessing(boolean) method so driver can be used in Ant tasks 68 | * Issue #20 - Fixed MetaData.getExportedKeys() to return all foreign keys. 69 | * Issue #14 - Fixed DatabaseMetaData.getColumns() resultSet to populate COLUMN_DEF with column default values. 70 | * Fixed Statement.close() so that calling it is a no-op on a closed connection. 71 | * Issue #13- Added support for Java Standard Edition Service Provider mechanism 72 | * Issue #12 - Fixed MetaData.getColumns() to return "YES" or "NO" for IS_NULLABLE column 73 | * Issue #16 - Fixed Statement.executeUpdate() to return 0 for DDL and more accurate changes for DML. (Added sqlite3_total_changes to native library) 74 | * Issue #15 - Modified Connection.setReadOnly(boolean) to throw an Exception if readOnly mode is modified after opening a connection 75 | * Changed driver to include architecture name in temporary filename in order to avoid conflicts when multiple JVMs with different architectures running at the same time 76 | * Issue #11 - Enhanced MetaData.getPrimaryKeys(): 77 | 1. Return named primary keys and correct key sequence. 78 | 2. Also result set is ordered by column name as per JDBC spec. 79 | * Issue #1 - Added support for WAL JournalMode. 80 | * Issue #4 - Enhanced SQLiteDataSource, SQLiteConfig and Conn to enable setting the transaction mode. 81 | * Issue #5 - Fixed NativeDB.c errors when compiling with Visual Studio 2010. 82 | * Issue #2 - Fixed issue where SQLiteDataSource: setEncoding not working. And also enabled using UTF-8, UTF-16, UTF-16le, and UTF-16be. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /LICENSE.zentus: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006, David Crawshaw. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions 5 | are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 | ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 17 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 | SUCH DAMAGE. 24 | 25 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # use JDK1.5 to build native libraries 2 | 3 | include Makefile.common 4 | 5 | RESOURCE_DIR = src/main/resources 6 | 7 | .phony: all package win32 mac32 mac64 linux32 native deploy 8 | .phony: mac64 9 | 10 | all: package 11 | 12 | deploy: 13 | mvn deploy 14 | 15 | MVN:=mvn 16 | SRC:=src/main/java 17 | SQLITE_OUT:=$(TARGET)/$(sqlite)-$(OS_NAME)-$(OS_ARCH) 18 | #SQLITE_ARCHIVE:=$(TARGET)/$(sqlite)-amal.zip 19 | #SQLITE_UNPACKED:=$(TARGET)/sqlite-unpack.log 20 | #SQLITE_AMAL_DIR=$(TARGET)/$(SQLITE_AMAL_PREFIX) 21 | SQLCIPHER_DIR:=sqlcipher 22 | 23 | # Note that that SQLITE_OMIT_LOAD_EXTENSION cannot be disabled on Macs due 24 | # to a bug in the SQLITE automake config. To make matters worse, SQLITE 25 | # doesn't even include the function to test whether extensions can be 26 | # loaded unless SQLITE_OMIT_LOAD_EXTENSION = 0. Rather than try to patch 27 | # SQLITE, we just include that flag here to be explicit, AND so that compiling 28 | # the JNI code will function correctly and not try to test if extensions 29 | # are available. 30 | SQLITE_FLAGS:=\ 31 | -DSQLITE_OMIT_LOAD_EXTENSION \ 32 | -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT \ 33 | -DSQLITE_ENABLE_COLUMN_METADATA \ 34 | -DSQLITE_CORE \ 35 | -DSQLITE_ENABLE_FTS3 \ 36 | -DSQLITE_ENABLE_FTS3_PARENTHESIS \ 37 | -DSQLITE_ENABLE_RTREE \ 38 | -DSQLITE_ENABLE_STAT2 \ 39 | -DSQLITE_HAS_CODEC 40 | 41 | CFLAGS:= -I$(SQLITE_OUT) -I$(SQLITE_AMAL_DIR) $(CFLAGS) $(SQLITE_FLAGS) 42 | 43 | $(SQLITE_ARCHIVE): 44 | @mkdir -p $(@D) 45 | curl -o$@ http://www.sqlite.org/2013/$(SQLITE_AMAL_PREFIX).zip 46 | 47 | $(SQLITE_UNPACKED): $(SQLITE_ARCHIVE) 48 | unzip -qo $< -d $(TARGET) 49 | touch $@ 50 | 51 | $(SQLITE_OUT)/org/sqlite/%.class: src/main/java/org/sqlite/%.java 52 | @mkdir -p $(@D) 53 | $(JAVAC) -source 1.5 -target 1.5 -sourcepath $(SRC) -d $(SQLITE_OUT) $< 54 | 55 | jni-header: $(SRC)/org/sqlite/core/NativeDB.h 56 | 57 | $(SQLITE_OUT)/NativeDB.h: $(SQLITE_OUT)/org/sqlite/core/NativeDB.class 58 | $(JAVAH) -classpath $(SQLITE_OUT) -jni -o $@ org.sqlite.core.NativeDB 59 | # Apple uses different include path conventions. 60 | ifeq ($(OS_NAME),Mac) 61 | cp $@ $@.tmp 62 | perl -p -e "s/#include \/#include \/" $@.tmp > $@ 63 | rm $@.tmp 64 | endif 65 | 66 | 67 | test: 68 | mvn test 69 | 70 | 71 | clean: clean-native clean-java clean-tests 72 | 73 | 74 | $(SQLITE_OUT)/sqlite3.o: 75 | cd $(SQLCIPHER_DIR); CPPFLAGS="$(SQLITE_FLAGS)" ./configure; 76 | make -C $(SQLCIPHER_DIR) 77 | @mkdir -p $(@D) 78 | cp $(SQLCIPHER_DIR)/sqlite3.o $@ 79 | 80 | #$(SQLITE_OUT)/sqlite3.o : $(SQLITE_AMAL) 81 | # @mkdir -p $(@D) 82 | # perl -p -e "s/sqlite3_api;/sqlite3_api = 0;/g" \ 83 | # $(SQLITE_AMAL_DIR)/sqlite3ext.h > $(SQLITE_OUT)/sqlite3ext.h 84 | # insert a code for loading extension functions 85 | # perl -p -e "s/^opendb_out:/ if(!db->mallocFailed && rc==SQLITE_OK){ rc = RegisterExtensionFunctions(db); }\nopendb_out:/;" \ 86 | # $(SQLITE_AMAL_DIR)/sqlite3.c > $(SQLITE_OUT)/sqlite3.c 87 | # cat src/main/ext/*.c >> $(SQLITE_OUT)/sqlite3.c 88 | # $(CC) -o $@ -c $(CFLAGS) \ 89 | # -DSQLITE_ENABLE_LOAD_EXTENSION=1 \ 90 | # -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT \ 91 | # -DSQLITE_ENABLE_COLUMN_METADATA \ 92 | # -DSQLITE_CORE \ 93 | # -DSQLITE_ENABLE_FTS3 \ 94 | # -DSQLITE_ENABLE_FTS3_PARENTHESIS \ 95 | # -DSQLITE_ENABLE_RTREE \ 96 | # -DSQLITE_ENABLE_STAT2 \ 97 | # -DSQLITE_HAS_CODEC \ 98 | # $(SQLITE_FLAGS) \ 99 | # $(SQLITE_OUT)/sqlite3.c 100 | 101 | $(SQLITE_OUT)/$(LIBNAME): $(SQLITE_OUT)/sqlite3.o $(SRC)/org/sqlite/core/NativeDB.c $(SQLITE_OUT)/NativeDB.h 102 | @mkdir -p $(@D) 103 | $(CC) $(CFLAGS) -c -o $(SQLITE_OUT)/NativeDB.o $(SRC)/org/sqlite/core/NativeDB.c 104 | $(CC) $(CFLAGS) -o $@ $(SQLITE_OUT)/*.o $(LINKFLAGS) 105 | $(STRIP) $@ 106 | 107 | 108 | NATIVE_DIR=src/main/resources/org/sqlite/native/$(OS_NAME)/$(OS_ARCH) 109 | NATIVE_TARGET_DIR:=$(TARGET)/classes/org/sqlite/native/$(OS_NAME)/$(OS_ARCH) 110 | NATIVE_DLL:=$(NATIVE_DIR)/$(LIBNAME) 111 | 112 | native: $(SQLITE_OUT)/sqlite3.o $(NATIVE_DLL) 113 | 114 | $(NATIVE_DLL): $(SQLITE_OUT)/$(LIBNAME) 115 | @mkdir -p $(@D) 116 | cp $< $@ 117 | @mkdir -p $(NATIVE_TARGET_DIR) 118 | cp $< $(NATIVE_TARGET_DIR)/$(LIBNAME) 119 | 120 | 121 | win32: 122 | $(MAKE) native CC=i686-w64-mingw32-gcc OS_NAME=Windows OS_ARCH=x86 123 | 124 | linux32: 125 | $(MAKE) native OS_NAME=Linux OS_ARCH=i386 126 | 127 | sparcv9: 128 | $(MAKE) native OS_NAME=SunOS OS_ARCH=sparcv9 129 | 130 | mac32: 131 | $(MAKE) native OS_NAME=Mac OS_ARCH=i386 132 | 133 | mac64: 134 | $(MAKE) native OS_NAME=Mac OS_ARCH=x86_64 135 | 136 | 137 | package: $(NATIVE64_DLL) native 138 | rm -rf target/dependency-maven-plugin-markers 139 | $(MVN) package 140 | 141 | clean-native: 142 | rm -rf $(TARGET)/$(sqlite)-$(OS_NAME)* 143 | 144 | clean-java: 145 | rm -rf $(TARGET)/*classes 146 | rm -rf $(TARGET)/sqlite-jdbc-*jar 147 | 148 | clean-tests: 149 | rm -rf $(TARGET)/{surefire*,testdb.jar*} 150 | -------------------------------------------------------------------------------- /Makefile.common: -------------------------------------------------------------------------------- 1 | include VERSION 2 | 3 | ifndef JAVA_HOME 4 | $(error Set JAVA_HOME environment variable) 5 | endif 6 | 7 | libjdbc := $(wildcard lib/jdbc-*.jar) 8 | 9 | JAVA := "$$JAVA_HOME/bin/java" 10 | JAVAC := "$$JAVA_HOME/bin/javac" -Xbootclasspath/p:$(libjdbc) 11 | JAVAH := "$$JAVA_HOME/bin/javah" 12 | 13 | TARGET := target 14 | OSINFO_CLASS := org.sqlite.OSInfo 15 | OSINFO_PROG := lib/org/sqlite/OSInfo.class 16 | 17 | ## building OSInfo.java 18 | #$(info compiling OSInfo.java) 19 | #$(shell mkdir -p lib) 20 | #$(shell $(JAVAC) src/main/java/org/sqlite/OSInfo.java -d lib) 21 | 22 | OS_NAME := $(shell $(JAVA) -cp lib $(OSINFO_CLASS) --os) 23 | OS_ARCH := $(shell $(JAVA) -cp lib $(OSINFO_CLASS) --arch) 24 | LIB_FOLDER := $(shell $(JAVA) -cp lib $(OSINFO_CLASS)) 25 | 26 | # Windows uses different path separators, because they hate me 27 | ifeq ($(OS_NAME),Windows) 28 | sep := ; 29 | else 30 | sep := : 31 | endif 32 | 33 | sqlite := sqlite-$(version) 34 | 35 | jni_md := $(shell find -L "$(JAVA_HOME)" -name jni_md.h) 36 | ifneq ($(jni_md),) 37 | jni_include := $(shell dirname "$(jni_md)") 38 | endif 39 | 40 | 41 | # os=Default is meant to be generic unix/linux 42 | 43 | known_targets := Linux-i386 Linux-amd64 Mac-i386 Mac-x86_64 Windows-x86 Windows-amd64 SunOS-sparcv9 44 | target := $(OS_NAME)-$(OS_ARCH) 45 | 46 | ifeq (,$(findstring $(strip $(target)),$(known_targets))) 47 | target := Default 48 | endif 49 | 50 | Default_CC := gcc 51 | Default_STRIP := strip 52 | Default_CFLAGS := -I$(JAVA_HOME)/include -Isqlitejdbc/lib/inc_linux -Os -fPIC -fvisibility=hidden 53 | Default_LINKFLAGS := -shared 54 | Default_LIBNAME := libsqlitejdbc.so 55 | Default_SQLITE_FLAGS := 56 | 57 | Linux-i386_CC := gcc 58 | Linux-i386_STRIP := strip 59 | Linux-i386_CFLAGS := -I$(JAVA_HOME)/include -Ilib/inc_linux -O2 -fPIC -m32 -fvisibility=hidden 60 | Linux-i386_LINKFLAGS := -shared -static-libgcc 61 | Linux-i386_LIBNAME := libsqlitejdbc.so 62 | Linux-i386_SQLITE_FLAGS := 63 | 64 | Linux-amd64_CC := gcc 65 | Linux-amd64_STRIP := strip 66 | Linux-amd64_CFLAGS := -I$(JAVA_HOME)/include -Ilib/inc_linux -O2 -fPIC -m64 -fvisibility=hidden 67 | Linux-amd64_LINKFLAGS := -shared -static-libgcc 68 | Linux-amd64_LIBNAME := libsqlitejdbc.so 69 | Linux-amd64_SQLITE_FLAGS := 70 | 71 | SunOS-sparcv9_CC := gcc 72 | SunOS-sparcv9_STRIP := strip 73 | SunOS-sparcv9_CFLAGS := -I$(JAVA_HOME)/include -Ilib/inc_linux -O2 -fPIC -m64 -fvisibility=hidden 74 | SunOS-sparcv9_LINKFLAGS := -shared -static-libgcc 75 | SunOS-sparcv9_LIBNAME := libsqlitejdbc.so 76 | SunOS-sparcv9_SQLITE_FLAGS := 77 | 78 | Mac-i386_CC := gcc -arch $(OS_ARCH) 79 | Mac-i386_STRIP := strip -x 80 | Mac-i386_CFLAGS := -I$(JAVA_HOME)/include -O2 -fPIC -mmacosx-version-min=10.4 -fvisibility=hidden 81 | Mac-i386_LINKFLAGS := -dynamiclib 82 | #-static-libgcc 83 | Mac-i386_LIBNAME := libsqlitejdbc.jnilib 84 | Mac-i386_SQLITE_FLAGS := -DSQLITE_ENABLE_LOCKING_STYLE=0 85 | 86 | Mac-x86_64_CC := gcc -arch $(OS_ARCH) 87 | Mac-x86_64_STRIP := strip -x 88 | MAC_SDK := /Developer/SDKs/MacOSX10.7.sdk 89 | ifeq ($(wildcard MAC_SDK),) 90 | MAC_SDK := /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk 91 | endif 92 | Mac-x86_64_CFLAGS := -I$(MAC_SDK)/System/Library/Frameworks/JavaVM.framework/Headers -O2 -fPIC -mmacosx-version-min=10.5 -fvisibility=hidden 93 | Mac-x86_64_LINKFLAGS := -dynamiclib -lcrypto 94 | #-static-libgcc 95 | Mac-x86_64_LIBNAME := libsqlitejdbc.jnilib 96 | Mac-x86_64_SQLITE_FLAGS := 97 | 98 | Windows-x86_CC := i686-w64-mingw32-gcc 99 | Windows-x86_STRIP := strip 100 | Windows-x86_CFLAGS := -D_JNI_IMPLEMENTATION_ -Ilib/inc_win -O2 101 | Windows-x86_LINKFLAGS := -Wl,--kill-at -shared 102 | Windows-x86_LIBNAME := sqlitejdbc.dll 103 | Windows-x86_SQLITE_FLAGS := 104 | 105 | Windows-amd64_CC := x86_64-w64-mingw32-gcc 106 | Windows-amd64_STRIP := x86_64-w64-mingw32-strip 107 | Windows-amd64_CFLAGS := -D_JNI_IMPLEMENTATION_ -Ilib/inc_win -O2 108 | Windows-amd64_LINKFLAGS := -Wl,--kill-at -shared 109 | Windows-amd64_LIBNAME := sqlitejdbc.dll 110 | Windows-amd64_SQLITE_FLAGS := 111 | 112 | 113 | CC := $($(target)_CC) 114 | STRIP := $($(target)_STRIP) 115 | CFLAGS := $($(target)_CFLAGS) 116 | LINKFLAGS := $($(target)_LINKFLAGS) 117 | LIBNAME := $($(target)_LIBNAME) 118 | SQLITE_FLAGS := $($(target)_SQLITE_FLAGS) 119 | SQLITE_AMAL_PREFIX = sqlite-amalgamation-$(shell ./amalgamation_version.sh $(version)) 120 | CFLAGS := $(CFLAGS) 121 | ifneq ($(jni_include),) 122 | CFLAGS := $(CFLAGS) -I"$(jni_include)" 123 | endif 124 | 125 | ifeq ($(OS_NAME),Windows) 126 | NATIVE32_DLL = win32 127 | NATIVE64_DLL = win64 128 | else ifeq ($(OS_NAME),Linux) 129 | NATIVE32_DLL = linux32 130 | NATIVE64_DLL = linux64 131 | else ifeq ($(OS_NAME),Mac) 132 | NATIVE32_DLL = mac32 133 | NATIVE64_DLL = mac64 134 | endif 135 | -------------------------------------------------------------------------------- /Makefile.package: -------------------------------------------------------------------------------- 1 | RESOURCE_DIR=src/main/resources 2 | NATIVE_DIR=$(RESOURCE_DIR)/native 3 | RSYNC=rsync -av -e ssh --exclude=".svn" 4 | 5 | WIN_SERVER=localhost 6 | WIN_WORK=work/hg/sqlite-jdbc 7 | 8 | WIN64_SERVER=localhost 9 | WIN64_WORK=work/hg/sqlite-jdbc 10 | 11 | MAC_SERVER=172.29.62.21 12 | MAC_WORK=work/hg/sqlite-jdbc 13 | 14 | MAC_TIGER_SERVER=172.16.153.128 15 | MAC_TIGER_WORK=work/hg/sqlite-jdbc 16 | 17 | LINUX_SERVER=hx02 18 | LINUX_WORK=work/hg/sqlite-jdbc 19 | 20 | AMD_SERVER=hx02 21 | AMD_WORK=work/hg/sqlite-jdbc 22 | 23 | BUILD_CMD = hg pull -u && make clean-native && make native 24 | TEST_CMD = mvn test 25 | 26 | all: compile test 27 | 28 | .PHONY: compile test native clean 29 | 30 | include VERSION 31 | sqlite-version := sqlite-$(version) 32 | 33 | LIB_DIR=target/dll/$(sqlite-version) 34 | DLL_DIR=$(LIB_DIR)/native 35 | 36 | DLL_WIN=$(DLL_DIR)/Windows/x86/sqlitejdbc.dll 37 | DLL_WIN64=$(DLL_DIR)/Windows/amd64/sqlitejdbc.dll 38 | DLL_MAC=$(DLL_DIR)/Mac/x86_64/libsqlitejdbc.jnilib 39 | DLL_TIGER_MAC=$(DLL_DIR)/Mac/i386/libsqlitejdbc.jnilib 40 | DLL_LINUX=$(DLL_DIR)/Linux/i386/libsqlitejdbc.so 41 | DLL_AMD64=$(DLL_DIR)/Linux/amd64/libsqlitejdbc.so 42 | LIB_PUREJAVA=$(LIB_DIR)/purejava/SQLite.class 43 | 44 | 45 | $(LIB_PUREJAVA): 46 | ssh $(MAC_TIGER_SERVER) "source .zprofile && cd $(MAC_TIGER_WORK) && make purejava" 47 | mkdir -p $(LIB_DIR)/purejava 48 | scp $(MAC_TIGER_SERVER):./$(MAC_TIGER_WORK)/sqlitejdbc/build/org/sqlite/SQLite.class $(LIB_DIR)/purejava/ 49 | 50 | 51 | $(DLL_WIN): 52 | ssh $(WIN_SERVER) "source .zprofile && cd $(WIN_WORK) && $(BUILD_CMD)" 53 | mkdir -p $(DLL_DIR)/Windows 54 | $(RSYNC) $(WIN_SERVER):./$(WIN_WORK)/$(DLL_DIR)/Windows/ $(DLL_DIR)/Windows/ 55 | 56 | $(DLL_WIN64): 57 | ssh $(WIN64_SERVER) "source .zprofile && cd $(WIN64_WORK) && $(BUILD_CMD)" 58 | mkdir -p $(DLL_DIR)/Windows 59 | $(RSYNC) $(WIN64_SERVER):./$(WIN64_WORK)/$(DLL_DIR)/Windows/ $(DLL_DIR)/Windows/ 60 | 61 | $(DLL_MAC): 62 | ssh $(MAC_SERVER) "source .zprofile && cd $(MAC_WORK) && $(BUILD_CMD)" 63 | mkdir -p $(DLL_DIR)/Mac 64 | $(RSYNC) $(MAC_SERVER):./$(MAC_WORK)/$(DLL_DIR)/Mac/ $(DLL_DIR)/Mac/ 65 | 66 | $(DLL_TIGER_MAC): 67 | ssh $(MAC_TIGER_SERVER) "source .zprofile && cd $(MAC_TIGER_WORK) && $(BUILD_CMD)" 68 | mkdir -p $(DLL_DIR)/Mac 69 | $(RSYNC) $(MAC_TIGER_SERVER):./$(MAC_TIGER_WORK)/$(DLL_DIR)/Mac/ $(DLL_DIR)/Mac/ 70 | 71 | 72 | $(DLL_LINUX): 73 | ssh $(LINUX_SERVER) "source .zprofile && cd $(LINUX_WORK) && $(BUILD_CMD)" 74 | mkdir -p $(DLL_DIR)/Linux/i386 75 | $(RSYNC) $(LINUX_SERVER):./$(LINUX_WORK)/$(DLL_DIR)/Linux/i386/ $(DLL_DIR)/Linux/i386/ 76 | 77 | $(DLL_AMD64): 78 | ssh $(AMD_SERVER) "source .zprofile && cd $(AMD_WORK) && $(BUILD_CMD)" 79 | mkdir -p $(DLL_DIR)/Linux/amd64 80 | $(RSYNC) $(AMD_SERVER):./$(AMD_WORK)/$(DLL_DIR)/Linux/amd64/ $(DLL_DIR)/Linux/amd64/ 81 | 82 | $(DLL_DIR): 83 | mkdir -p $@ 84 | 85 | 86 | linux: $(DLL_LINUX) $(DLL_AMD64) 87 | mac: $(DLL_MAC) $(DLL_TIGER_MAC) 88 | 89 | native: $(DLL_DIR) $(DLL_WIN) $(DLL_WIN64) $(DLL_MAC) $(DLL_TIGER_MAC) $(DLL_LINUX) $(DLL_AMD64) 90 | 91 | 92 | 93 | compile-native: native 94 | cp -r $(DLL_DIR)/ $(RESOURCE_DIR)/native/ 95 | 96 | compile: compile-native $(LIB_PUREJAVA) 97 | cp $(LIB_PUREJAVA) $(RESOURCE_DIR)/org/sqlite 98 | 99 | test-native: 100 | ssh $(WIN_SERVER) "source .zprofile && cd $(WIN_WORK) && $(TEST_CMD)" 101 | ssh $(MAC_SERVER) "source .zprofile && cd $(MAC_WORK) && $(TEST_CMD)" 102 | ssh $(MAC_TIGER_SERVER) "source .zprofile && cd $(MAC_WORK) && $(TEST_CMD)" 103 | ssh $(LINUX_SERVER) "source .zprofile && source /etc/profile.d/java.sh && cd $(LINUX_WORK) && $(TEST_CMD)" 104 | ssh $(AMD_SERVER) "source .zprofile && cd $(AMD_WORK) && $(TEST_CMD)" 105 | 106 | test: 107 | ssh $(MAC_TIGER_SERVER) "source .zprofile && cd $(MAC_WORK) && $(TEST_CMD) -DargLine='-Dsqlite.purejava=true'" 108 | 109 | release: 110 | mvn release:prepare 111 | mvn release:perform 112 | 113 | release-xerial: 114 | mvn release:perform -Dtag=sqlite-jdbc-$(version) 115 | 116 | release-sourceforge: 117 | mvn release:perform -Darguments="-P sourceforge" -Dtag=sqlite-jdbc-$(version) 118 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | This product includes the following softwares developed by David Crawshaw. 2 | See LICENSE.zentus file. 3 | 4 | And also, NestedVM (Apache License Version 2.0) is used inside sqlite- -------------------------------------------------------------------------------- /README_BUILD.md: -------------------------------------------------------------------------------- 1 | How to compile a new version of SQLiteJDBC 2 | =========================================== 3 | Prerequisites 4 | ------------- 5 | 1. JDK 1.5 6 | 2. Perl 7 | 3. Maven 8 | 4. make 9 | 5. gcc 10 | 6. curl 11 | 7. unzip 12 | 13 | Build 14 | ----- 15 | 1. Edit the `VERSION` file and set the SQLite version to use. 16 | 2. Edit the version number in `pom.xml` to match `VERSION`. 17 | 3. Then, run: 18 | 19 | $ make 20 | 21 | 22 | How to submit a patch 23 | ===================== 24 | Bitbucket Pull Request 25 | ---------------------- 26 | 1. Fork this project on bitbucket 27 | 2. (make some change) 28 | 3. `hg commit -m 'what changes are made to the source'` 29 | 4. `hg push` 30 | 5. Create a pull request 31 | 32 | Patch file 33 | ---------- 34 | 1. Create a new issue on 35 | 2. Attach a patch file to issue 36 | 37 | 38 | How to build Win64 native library 39 | ================================= 40 | * Install cygwin with make, curl, unzip, and mingw64-x86_64-gcc-core 41 | * (You can install MinGW64 ) 42 | 43 | * After the installation, make sure your PATH environment variable 44 | points to `/usr/bin` before `/bin`. 45 | 46 | Here is the excerpt from 47 | 48 | The mingw-w64 toolchain has been officially added to Cygwin mirrors, 49 | you can find the basic C toolchain as mingw64-x86_64-gcc-core. The 50 | languages enabled are C, Ada, C++, Fortran, Object C and Objective 51 | C++. There is a known caveat where calling the compiler directly as 52 | "/bin/x86_64-w64-mingw32-gcc" will fail, use 53 | "/usr/bin/x86_64-w64-mingw32-gcc" instead and make sure that your PATH 54 | variable has "/usr/bin" before "/bin". 55 | 56 | * Instead, you can explicitly set the compiler: 57 | $ make native Windows-amd64_CC=/usr/bin/x86_64-w64-mingw32-gcc 58 | 59 | * Then, do 60 | $ make native 61 | 62 | 63 | How to build pure-java library 64 | ============================== 65 | ***The pure-java library is no longer supported as of version 3.7.15. 66 | *** 67 | 68 | * Use Mac OS X or Linux with gcc-3.x 69 | 70 | make purejava 71 | 72 | * The build will fail due to the broken regex libray, so copy the non-corrupted 73 | archive I downloaded: 74 | 75 | $ cp archive/regex3.8a.tar.gz target/build/nestedvm-2009-08-09/upstream/downlolad/ 76 | 77 | * then do 78 | 79 | 'make purejava' 80 | 81 | 82 | (for deployer only) How to build pure-java and native libraries 83 | =============================================================== 84 | make -fMakefile.package 85 | 86 | 87 | How to deploy to the maven repository 88 | ===================================== 89 | mvn deploy 90 | mvn deploy -Psourceforge 91 | (for uploading Sourceforge.jp repository, which are synchronized with the Maven 92 | central repository) 93 | -------------------------------------------------------------------------------- /SQLiteJDBC.wiki: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decamp/sqlcipher-jdbc/3ce4defeafa9d468b0b0a91b62d7ac98a5456ed8/SQLiteJDBC.wiki -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | version=3.8.2 2 | -------------------------------------------------------------------------------- /amalgamation_version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Used to generate the version for the amalgamation download zip. 3 | # http://www.sqlite.org/download.html#encoding 4 | # The version is encoded so that filenames sort in order of increasing version number when viewed using "ls". 5 | # For version 3.X.Y the filename encoding is 3XXYY00. For branch version 3.X.Y.Z, the encoding is 3XXYYZZ. 6 | version="" 7 | i=0 8 | export IFS="." 9 | for num in $1; do 10 | if [ $i -gt 0 ]; then 11 | if [ $num -le 9 ]; then 12 | eval num=0$num 13 | fi 14 | fi 15 | eval version=$version$num 16 | let i+=1 17 | done 18 | unset IFS 19 | echo "$version"00 -------------------------------------------------------------------------------- /archive/nestedvm-2007-06-30.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decamp/sqlcipher-jdbc/3ce4defeafa9d468b0b0a91b62d7ac98a5456ed8/archive/nestedvm-2007-06-30.tgz -------------------------------------------------------------------------------- /archive/nestedvm-2009-08-09.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decamp/sqlcipher-jdbc/3ce4defeafa9d468b0b0a91b62d7ac98a5456ed8/archive/nestedvm-2009-08-09.tgz -------------------------------------------------------------------------------- /archive/regex3.8a.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decamp/sqlcipher-jdbc/3ce4defeafa9d468b0b0a91b62d7ac98a5456ed8/archive/regex3.8a.tar.gz -------------------------------------------------------------------------------- /archive/sqlite-jdbc4-3.8.2-SNAPSHOT.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decamp/sqlcipher-jdbc/3ce4defeafa9d468b0b0a91b62d7ac98a5456ed8/archive/sqlite-jdbc4-3.8.2-SNAPSHOT.jar -------------------------------------------------------------------------------- /demo/AppletDemo.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decamp/sqlcipher-jdbc/3ce4defeafa9d468b0b0a91b62d7ac98a5456ed8/demo/AppletDemo.jar -------------------------------------------------------------------------------- /demo/applet-demo.html: -------------------------------------------------------------------------------- 1 | 2 | Applet Demo 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /lib/inc_linux/jni_md.h: -------------------------------------------------------------------------------- 1 | /* 2 | * %W% %E% 3 | * 4 | * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. 5 | * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. 6 | */ 7 | 8 | #ifndef _JAVASOFT_JNI_MD_H_ 9 | #define _JAVASOFT_JNI_MD_H_ 10 | 11 | #define JNIEXPORT __attribute__((__visibility__("default"))) 12 | #define JNIIMPORT 13 | #define JNICALL 14 | 15 | typedef int jint; 16 | #ifdef _LP64 /* 64-bit Solaris */ 17 | typedef long jlong; 18 | #else 19 | typedef long long jlong; 20 | #endif 21 | 22 | typedef signed char jbyte; 23 | 24 | #endif /* !_JAVASOFT_JNI_MD_H_ */ 25 | -------------------------------------------------------------------------------- /lib/inc_win/jni_md.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @(#)jni_md.h 1.14 03/12/19 3 | * 4 | * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 5 | * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. 6 | */ 7 | 8 | #ifndef _JAVASOFT_JNI_MD_H_ 9 | #define _JAVASOFT_JNI_MD_H_ 10 | 11 | #define JNIEXPORT __declspec(dllexport) 12 | #define JNIIMPORT __declspec(dllimport) 13 | #define JNICALL __stdcall 14 | 15 | typedef long jint; 16 | typedef __int64 jlong; 17 | typedef signed char jbyte; 18 | 19 | #endif /* !_JAVASOFT_JNI_MD_H_ */ 20 | -------------------------------------------------------------------------------- /lib/jdbc-api-1.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decamp/sqlcipher-jdbc/3ce4defeafa9d468b0b0a91b62d7ac98a5456ed8/lib/jdbc-api-1.4.jar -------------------------------------------------------------------------------- /lib/junit-4.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decamp/sqlcipher-jdbc/3ce4defeafa9d468b0b0a91b62d7ac98a5456ed8/lib/junit-4.5.jar -------------------------------------------------------------------------------- /lib/org/sqlite/OSInfo.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decamp/sqlcipher-jdbc/3ce4defeafa9d468b0b0a91b62d7ac98a5456ed8/lib/org/sqlite/OSInfo.class -------------------------------------------------------------------------------- /maven-eclipse.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | org.xerial 5 | sqlite-jdbc4 6 | 3.8.2-SNAPSHOT 7 | SQLite JDBC 8 | SQLite JDBC library 9 | 10 | 11 | org.sonatype.oss 12 | oss-parent 13 | 7 14 | 15 | 16 | 17 | UTF-8 18 | 19 | 20 | 21 | 22 | The Apache Software License, Version 2.0 23 | http://www.apache.org/licenses/LICENSE-2.0.txt 24 | repo 25 | 26 | 27 | 28 | 29 | 30 | leo 31 | Taro L. Saito 32 | leo@xerial.org 33 | Xerial Project 34 | 35 | Architect 36 | Project Manager 37 | Chief Developer 38 | 39 | +9 40 | 41 | 42 | 43 | 44 | 45 | 46 | src/main/java 47 | 48 | 49 | src/main/resources 50 | 51 | org/** 52 | 53 | 54 | 55 | src/main/resources 56 | META-INF/services 57 | 58 | java.sql.Driver 59 | 60 | 61 | 62 | ${basedir} 63 | META-INF/maven/${project.groupId}/${project.artifactId} 64 | 65 | VERSION 66 | LICENSE* 67 | 68 | 69 | 70 | 71 | 72 | 73 | src/test/java 74 | 75 | **/*.java 76 | 77 | 78 | 79 | src/test/resources 80 | 81 | 82 | 83 | 84 | 85 | org.apache.maven.plugins 86 | maven-compiler-plugin 87 | 3.1 88 | 89 | 1.5 90 | 1.6 91 | 92 | 93 | 94 | 95 | org.apache.maven.plugins 96 | maven-surefire-report-plugin 97 | 2.6 98 | 99 | 100 | 101 | maven-release-plugin 102 | 2.1 103 | 104 | 105 | deploy 106 | false 107 | true 108 | scm:hg:ssh://hg@bitbucket.org/xerial/sqlite-jdbc 109 | 110 | 111 | 112 | 113 | org.apache.maven.plugins 114 | maven-gpg-plugin 115 | 1.4 116 | 117 | true 118 | 119 | 120 | 121 | sign-artifacts 122 | verify 123 | 124 | sign 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | scm:hg:https://bitbucket.org/xerial/sqlite-jdbc 135 | scm:hg:ssh://hg@bitbucket.org/xerial/sqlite-jdbc 136 | https://bitbucket.org/xerial/sqlite-jdbc 137 | 138 | 139 | 140 | 141 | junit 142 | junit 143 | 4.8.2 144 | test 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /src/main/java/org/sqlite/ExtendedCommand.java: -------------------------------------------------------------------------------- 1 | //-------------------------------------- 2 | // sqlite-jdbc Project 3 | // 4 | // ExtendedCommand.java 5 | // Since: Mar 12, 2010 6 | // 7 | // $URL$ 8 | // $Author$ 9 | //-------------------------------------- 10 | package org.sqlite; 11 | 12 | import java.sql.SQLException; 13 | import java.util.regex.Matcher; 14 | import java.util.regex.Pattern; 15 | 16 | import org.sqlite.core.DB; 17 | 18 | /** 19 | * parsing SQLite specific extension of SQL command 20 | * 21 | * @author leo 22 | * 23 | */ 24 | public class ExtendedCommand 25 | { 26 | public static interface SQLExtension 27 | { 28 | public void execute(DB db) throws SQLException; 29 | } 30 | 31 | /** 32 | * Parses extended commands of "backup" or "restore" for SQLite database. 33 | * @param sql One of the extended commands:
34 | * backup sourceDatabaseName to destinationFileName OR restore targetDatabaseName from sourceFileName 35 | * @return BackupCommand object if the argument is a backup command; RestoreCommand object if 36 | * the argument is a restore command; 37 | * @throws SQLException 38 | */ 39 | public static SQLExtension parse(String sql) throws SQLException { 40 | if (sql == null) 41 | return null; 42 | 43 | if (sql.startsWith("backup")) 44 | return BackupCommand.parse(sql); 45 | else if (sql.startsWith("restore")) 46 | return RestoreCommand.parse(sql); 47 | 48 | return null; 49 | } 50 | 51 | /** 52 | * Remove the quotation mark from string. 53 | * @param s String with quotation mark. 54 | * @return String with quotation mark removed. 55 | */ 56 | public static String removeQuotation(String s) { 57 | if (s == null) 58 | return s; 59 | 60 | if ((s.startsWith("\"") && s.endsWith("\"")) || (s.startsWith("'") && s.endsWith("'"))) 61 | return s.substring(1, s.length() - 1); 62 | else 63 | return s; 64 | } 65 | 66 | public static class BackupCommand implements SQLExtension 67 | { 68 | public final String srcDB; 69 | public final String destFile; 70 | 71 | /** 72 | * Constructs a BackupCommand instance that backup the database to a target file. 73 | * @param srcDB Source database name. 74 | * @param destFile Target file name. 75 | */ 76 | public BackupCommand(String srcDB, String destFile) { 77 | this.srcDB = srcDB; 78 | this.destFile = destFile; 79 | } 80 | 81 | private static Pattern backupCmd = Pattern 82 | .compile("backup(\\s+(\"[^\"]*\"|'[^\']*\'|\\S+))?\\s+to\\s+(\"[^\"]*\"|'[^\']*\'|\\S+)"); 83 | 84 | /** 85 | * Parses SQLite database backup command and creates a BackupCommand object. 86 | * @param sql SQLite database backup command. 87 | * @return BackupCommand object. 88 | * @throws SQLException 89 | */ 90 | public static BackupCommand parse(String sql) throws SQLException { 91 | if (sql != null) { 92 | Matcher m = backupCmd.matcher(sql); 93 | if (m.matches()) { 94 | String dbName = removeQuotation(m.group(2)); 95 | String dest = removeQuotation(m.group(3)); 96 | if (dbName == null || dbName.length() == 0) 97 | dbName = "main"; 98 | 99 | return new BackupCommand(dbName, dest); 100 | } 101 | } 102 | throw new SQLException("syntax error: " + sql); 103 | } 104 | 105 | public void execute(DB db) throws SQLException { 106 | db.backup(srcDB, destFile, null); 107 | } 108 | 109 | } 110 | 111 | public static class RestoreCommand implements SQLExtension 112 | { 113 | public final String targetDB; 114 | public final String srcFile; 115 | private static Pattern restoreCmd = Pattern 116 | .compile("restore(\\s+(\"[^\"]*\"|'[^\']*\'|\\S+))?\\s+from\\s+(\"[^\"]*\"|'[^\']*\'|\\S+)"); 117 | 118 | /** 119 | * Constructs a RestoreCommand instance that restores the database from a given source file. 120 | * @param targetDB Target database name 121 | * @param srcFile Source file name 122 | */ 123 | public RestoreCommand(String targetDB, String srcFile) { 124 | this.targetDB = targetDB; 125 | this.srcFile = srcFile; 126 | } 127 | 128 | /** 129 | * Parses SQLite database restore command and creates a RestoreCommand object. 130 | * @param sql SQLite restore backup command 131 | * @return RestoreCommand object. 132 | * @throws SQLException 133 | */ 134 | public static RestoreCommand parse(String sql) throws SQLException { 135 | if (sql != null) { 136 | Matcher m = restoreCmd.matcher(sql); 137 | if (m.matches()) { 138 | String dbName = removeQuotation(m.group(2)); 139 | String dest = removeQuotation(m.group(3)); 140 | if (dbName == null || dbName.length() == 0) 141 | dbName = "main"; 142 | return new RestoreCommand(dbName, dest); 143 | } 144 | } 145 | throw new SQLException("syntax error: " + sql); 146 | } 147 | 148 | /** 149 | * @see org.sqlite.ExtendedCommand.SQLExtension#execute(org.sqlite.core.DB) 150 | */ 151 | public void execute(DB db) throws SQLException { 152 | db.restore(targetDB, srcFile, null); 153 | } 154 | } 155 | 156 | } 157 | -------------------------------------------------------------------------------- /src/main/java/org/sqlite/Function.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 David Crawshaw 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package org.sqlite; 17 | 18 | import java.sql.Connection; 19 | import java.sql.SQLException; 20 | 21 | import org.sqlite.core.Codes; 22 | import org.sqlite.core.DB; 23 | 24 | /** Provides an interface for creating SQLite user-defined functions. 25 | * 26 | *

A subclass of org.sqlite.Function can be registered with 27 | * Function.create() and called by the name it was given. All 28 | * functions must implement xFunc(), which is called when SQLite 29 | * runs the custom function.

30 | * 31 | * Eg. 32 | * 33 | *
 34 |  *      Class.forName("org.sqlite.JDBC");
 35 |  *      Connection conn = DriverManager.getConnection("jdbc:sqlite:");
 36 |  *
 37 |  *      Function.create(conn, "myFunc", new Function() {
 38 |  *          protected void xFunc() {
 39 |  *              System.out.println("myFunc called!");
 40 |  *          }
 41 |  *      });
 42 |  *
 43 |  *      conn.createStatement().execute("select myFunc();");
 44 |  *  
45 | * 46 | *

Arguments passed to a custom function can be accessed using the 47 | * protected functions provided. args() returns 48 | * the number of arguments passed, while 49 | * value_<type>(int) returns the value of the specific 50 | * argument. Similarly a function can return a value using the 51 | * result(<type>) function.

52 | * 53 | *

Aggregate functions are not yet supported, but coming soon.

54 | * 55 | */ 56 | public abstract class Function 57 | { 58 | private SQLiteConnection conn; 59 | private DB db; 60 | 61 | long context = 0; // pointer sqlite3_context* 62 | long value = 0; // pointer sqlite3_value** 63 | int args = 0; 64 | 65 | /** 66 | * Registers a given function with the connection. 67 | * @param conn The connection. 68 | * @param name The name of the function. 69 | * @param f The function to register. 70 | */ 71 | public static final void create(Connection conn, String name, Function f) 72 | throws SQLException { 73 | if (conn == null || !(conn instanceof SQLiteConnection)) { 74 | throw new SQLException("connection must be to an SQLite db"); 75 | } 76 | if (conn.isClosed()) { 77 | throw new SQLException("connection closed"); 78 | } 79 | 80 | f.conn = (SQLiteConnection)conn; 81 | f.db = f.conn.db(); 82 | 83 | if (name == null || name.length() > 255) { 84 | throw new SQLException("invalid function name: '"+name+"'"); 85 | } 86 | 87 | if (f.db.create_function(name, f) != Codes.SQLITE_OK) { 88 | throw new SQLException("error creating function"); 89 | } 90 | } 91 | 92 | /** 93 | * Removes a named function from the given connection. 94 | * @param conn The connection to remove the function from. 95 | * @param name The name of the function. 96 | * @throws SQLException 97 | */ 98 | public static final void destroy(Connection conn, String name) 99 | throws SQLException { 100 | if (conn == null || !(conn instanceof SQLiteConnection)) { 101 | throw new SQLException("connection must be to an SQLite db"); 102 | } 103 | ((SQLiteConnection)conn).db().destroy_function(name); 104 | } 105 | 106 | 107 | /** 108 | * Called by SQLite as a custom function. Should access arguments 109 | * through value_*(int), return results with 110 | * result(*) and throw errors with error(String). 111 | */ 112 | protected abstract void xFunc() throws SQLException; 113 | 114 | 115 | /** 116 | * Returns the number of arguments passed to the function. 117 | * Can only be called from xFunc(). 118 | */ 119 | protected synchronized final int args() 120 | throws SQLException { checkContext(); return args; } 121 | 122 | /** 123 | * Called by xFunc to return a value. 124 | * @param value 125 | */ 126 | protected synchronized final void result(byte[] value) 127 | throws SQLException { checkContext(); db.result_blob(context, value); } 128 | 129 | /** 130 | * Called by xFunc to return a value. 131 | * @param value 132 | */ 133 | protected synchronized final void result(double value) 134 | throws SQLException { checkContext(); db.result_double(context,value);} 135 | 136 | /** 137 | * Called by xFunc to return a value. 138 | * @param value 139 | */ 140 | protected synchronized final void result(int value) 141 | throws SQLException { checkContext(); db.result_int(context, value); } 142 | 143 | /** 144 | * Called by xFunc to return a value. 145 | * @param value 146 | */ 147 | protected synchronized final void result(long value) 148 | throws SQLException { checkContext(); db.result_long(context, value); } 149 | 150 | /** 151 | * Called by xFunc to return a value. 152 | */ 153 | protected synchronized final void result() 154 | throws SQLException { checkContext(); db.result_null(context); } 155 | 156 | /** 157 | * Called by xFunc to return a value. 158 | * @param value 159 | */ 160 | protected synchronized final void result(String value) 161 | throws SQLException { checkContext(); db.result_text(context, value); } 162 | 163 | /** 164 | * Called by xFunc to throw an error. 165 | * @param err 166 | */ 167 | protected synchronized final void error(String err) 168 | throws SQLException { checkContext(); db.result_error(context, err); } 169 | 170 | /** 171 | * Called by xFunc to access the value of an argument. 172 | * @param arg 173 | */ 174 | protected synchronized final int value_bytes(int arg) 175 | throws SQLException {checkValue(arg); return db.value_bytes(this,arg);} 176 | 177 | /** 178 | * Called by xFunc to access the value of an argument. 179 | * @param arg 180 | */ 181 | protected synchronized final String value_text(int arg) 182 | throws SQLException {checkValue(arg); return db.value_text(this,arg);} 183 | 184 | /** 185 | * Called by xFunc to access the value of an argument. 186 | * @param arg 187 | */ 188 | protected synchronized final byte[] value_blob(int arg) 189 | throws SQLException {checkValue(arg); return db.value_blob(this,arg); } 190 | 191 | /** 192 | * Called by xFunc to access the value of an argument. 193 | * @param arg 194 | */ 195 | protected synchronized final double value_double(int arg) 196 | throws SQLException {checkValue(arg); return db.value_double(this,arg);} 197 | 198 | /** 199 | * Called by xFunc to access the value of an argument. 200 | * @param arg 201 | */ 202 | protected synchronized final int value_int(int arg) 203 | throws SQLException {checkValue(arg); return db.value_int(this, arg); } 204 | 205 | /** 206 | * Called by xFunc to access the value of an argument. 207 | * @param arg 208 | */ 209 | protected synchronized final long value_long(int arg) 210 | throws SQLException { checkValue(arg); return db.value_long(this,arg); } 211 | 212 | /** 213 | * Called by xFunc to access the value of an argument. 214 | * @param arg 215 | */ 216 | protected synchronized final int value_type(int arg) 217 | throws SQLException {checkValue(arg); return db.value_type(this,arg); } 218 | 219 | 220 | /** 221 | * @throws SQLException 222 | */ 223 | private void checkContext() throws SQLException { 224 | if (conn == null || conn.db() == null || context == 0) { 225 | throw new SQLException("no context, not allowed to read value"); 226 | } 227 | } 228 | 229 | /** 230 | * @param arg 231 | * @throws SQLException 232 | */ 233 | private void checkValue(int arg) throws SQLException { 234 | if (conn == null || conn.db() == null || value == 0) { 235 | throw new SQLException("not in value access state"); 236 | } 237 | if (arg >= args) { 238 | throw new SQLException("arg "+arg+" out bounds [0,"+args+")"); 239 | } 240 | } 241 | 242 | 243 | /** 244 | * Provides an interface for creating SQLite user-defined aggregate functions. 245 | * @see Function 246 | */ 247 | public static abstract class Aggregate 248 | extends Function 249 | implements Cloneable 250 | { 251 | /** 252 | * @see org.sqlite.Function#xFunc() 253 | */ 254 | protected final void xFunc() {} 255 | 256 | /** 257 | * Defines the abstract aggregate callback function 258 | * @throws SQLException 259 | * @see http://www.sqlite.org/c3ref/aggregate_context.html 260 | */ 261 | protected abstract void xStep() throws SQLException; 262 | 263 | /** 264 | * Defines the abstract aggregate callback function 265 | * @throws SQLException 266 | * @see http://www.sqlite.org/c3ref/aggregate_context.html 267 | */ 268 | protected abstract void xFinal() throws SQLException; 269 | 270 | /** 271 | * @see java.lang.Object#clone() 272 | */ 273 | public Object clone() throws CloneNotSupportedException { 274 | return super.clone(); 275 | } 276 | } 277 | } 278 | -------------------------------------------------------------------------------- /src/main/java/org/sqlite/JDBC.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 David Crawshaw 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | package org.sqlite; 18 | 19 | import java.sql.*; 20 | import java.util.Properties; 21 | import java.util.logging.Logger; 22 | 23 | 24 | public class JDBC implements Driver 25 | { 26 | public static final String PREFIX1 = "jdbc:sqlite:"; 27 | public static final String PREFIX2 = "jdbc:sqlcipher:"; 28 | 29 | static { 30 | try { 31 | DriverManager.registerDriver(new JDBC()); 32 | } 33 | catch (SQLException e) { 34 | e.printStackTrace(); 35 | } 36 | } 37 | 38 | /** 39 | * @see java.sql.Driver#getMajorVersion() 40 | */ 41 | public int getMajorVersion() { 42 | return SQLiteJDBCLoader.getMajorVersion(); 43 | } 44 | 45 | /** 46 | * @see java.sql.Driver#getMinorVersion() 47 | */ 48 | public int getMinorVersion() { 49 | return SQLiteJDBCLoader.getMinorVersion(); 50 | } 51 | 52 | /** 53 | * @see java.sql.Driver#jdbcCompliant() 54 | */ 55 | public boolean jdbcCompliant() { 56 | return false; 57 | } 58 | 59 | @Override 60 | public Logger getParentLogger() throws SQLFeatureNotSupportedException { 61 | throw new SQLFeatureNotSupportedException( "getParentLogger" ); 62 | } 63 | 64 | /** 65 | * @see java.sql.Driver#acceptsURL(java.lang.String) 66 | */ 67 | public boolean acceptsURL(String url) { 68 | return isValidURL(url); 69 | } 70 | 71 | /** 72 | * Validates a URL 73 | * @param url 74 | * @return true if the URL is valid, false otherwise 75 | */ 76 | public static boolean isValidURL(String url) { 77 | return extractPrefix( url ) != null; 78 | } 79 | 80 | /** 81 | * @see java.sql.Driver#getPropertyInfo(java.lang.String, java.util.Properties) 82 | */ 83 | public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException { 84 | return SQLiteConfig.getDriverPropertyInfo(); 85 | } 86 | 87 | /** 88 | * @see java.sql.Driver#connect(java.lang.String, java.util.Properties) 89 | */ 90 | public Connection connect(String url, Properties info) throws SQLException { 91 | return createConnection(url, info); 92 | } 93 | 94 | /** 95 | * Creates a new database connection to a given URL. 96 | * @param url the URL 97 | * @param prop the properties 98 | * @return a Connection object that represents a connection to the URL 99 | * @throws SQLException 100 | * @see java.sql.Driver#connect(java.lang.String, java.util.Properties) 101 | */ 102 | public static Connection createConnection(String url, Properties prop) throws SQLException { 103 | url = url == null ? null : url.trim(); 104 | String prefix = extractPrefix(url); 105 | String address = extractAddress(url, prefix); 106 | if(address == null) { 107 | throw new SQLException("invalid database address: " + url); 108 | } 109 | return new SQLiteConnection(url, address, prop); 110 | } 111 | 112 | 113 | private static String extractPrefix(String url) { 114 | if( url == null ) { 115 | return null; 116 | } 117 | url = url.toLowerCase(); 118 | return url.startsWith( PREFIX1 ) ? PREFIX1 : 119 | url.startsWith( PREFIX2 ) ? PREFIX2 : null; 120 | } 121 | 122 | /** 123 | * Gets the location to the database from a given URL and prefix. 124 | * @param url The URL to extract the location from. 125 | * @param prefix The prefix of the db connection. 126 | * @return The location to the database. 127 | */ 128 | private static String extractAddress(String url, String prefix) { 129 | if( url == null || prefix == null ) { 130 | return null; 131 | } 132 | // if no file name is given use a memory database 133 | return url.length() == prefix.length() ? ":memory:" : url.substring( prefix.length() ); 134 | } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /src/main/java/org/sqlite/SQLiteConnection.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 David Crawshaw 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package org.sqlite; 17 | 18 | import java.sql.SQLException; 19 | import java.util.Properties; 20 | import java.util.concurrent.Executor; 21 | 22 | import org.sqlite.jdbc4.JDBC4Connection; 23 | 24 | public class SQLiteConnection extends JDBC4Connection 25 | { 26 | /** 27 | * Constructor to create a connection to a database at the given location. 28 | * @param url The location of the database. 29 | * @param fileName The database. 30 | * @throws SQLException 31 | */ 32 | public SQLiteConnection(String url, String fileName) throws SQLException { 33 | this(url, fileName, new Properties()); 34 | } 35 | 36 | /** 37 | * Constructor to create a pre-configured connection to a database at the 38 | * given location. 39 | * @param url The location of the database file. 40 | * @param fileName The database. 41 | * @param prop The configurations to apply. 42 | * @throws SQLException 43 | */ 44 | public SQLiteConnection(String url, String fileName, Properties prop) throws SQLException { 45 | super(url, fileName, prop); 46 | } 47 | 48 | @Override 49 | public void setSchema( String schema ) throws SQLException { 50 | //TODO: Implement 51 | } 52 | 53 | @Override 54 | public String getSchema() throws SQLException { 55 | //TODO: Implement 56 | return null; 57 | } 58 | 59 | @Override 60 | public void abort( Executor executor ) throws SQLException { 61 | //TODO: Implement 62 | } 63 | 64 | @Override 65 | public void setNetworkTimeout( Executor executor, int milliseconds ) throws SQLException { 66 | //TODO: Implement 67 | } 68 | 69 | @Override 70 | public int getNetworkTimeout() throws SQLException { 71 | //TODO: Implement 72 | return 0; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/org/sqlite/SQLiteErrorCode.java: -------------------------------------------------------------------------------- 1 | /*-------------------------------------------------------------------------- 2 | * Copyright 2009 Taro L. Saito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *--------------------------------------------------------------------------*/ 16 | //-------------------------------------- 17 | // sqlite-jdbc Project 18 | // 19 | // SQLiteErrorCode.java 20 | // Since: Apr 21, 2009 21 | // 22 | // $URL$ 23 | // $Author$ 24 | //-------------------------------------- 25 | package org.sqlite; 26 | 27 | /** 28 | * SQLite3 error code 29 | * 30 | * @author leo 31 | * @see http://www.sqlite.org/c3ref/c_abort.html 32 | * 33 | */ 34 | public enum SQLiteErrorCode { 35 | 36 | UNKNOWN_ERROR(-1, "unknown error"), 37 | SQLITE_OK(0, "Successful result"), 38 | /* beginning-of-error-codes */ 39 | SQLITE_ERROR(1, "SQL error or missing database"), 40 | SQLITE_INTERNAL(2, "Internal logic error in SQLite"), 41 | SQLITE_PERM(3, " Access permission denied"), 42 | SQLITE_ABORT(4, " Callback routine requested an abort"), 43 | SQLITE_BUSY(5, " The database file is locked"), 44 | SQLITE_LOCKED(6, " A table in the database is locked"), 45 | SQLITE_NOMEM(7, " A malloc() failed"), 46 | SQLITE_READONLY(8, " Attempt to write a readonly database"), 47 | SQLITE_INTERRUPT(9, " Operation terminated by sqlite3_interrupt()"), 48 | SQLITE_IOERR(10, " Some kind of disk I/O error occurred"), 49 | SQLITE_CORRUPT(11, " The database disk image is malformed"), 50 | SQLITE_NOTFOUND(12, " NOT USED. Table or record not found"), 51 | SQLITE_FULL(13, " Insertion failed because database is full"), 52 | SQLITE_CANTOPEN(14, " Unable to open the database file"), 53 | SQLITE_PROTOCOL(15, " NOT USED. Database lock protocol error"), 54 | SQLITE_EMPTY(16, " Database is empty"), 55 | SQLITE_SCHEMA(17, " The database schema changed"), 56 | SQLITE_TOOBIG(18, " String or BLOB exceeds size limit"), 57 | SQLITE_CONSTRAINT(19, " Abort due to constraint violation"), 58 | SQLITE_MISMATCH(20, " Data type mismatch"), 59 | SQLITE_MISUSE(21, " Library used incorrectly"), 60 | SQLITE_NOLFS(22, " Uses OS features not supported on host"), 61 | SQLITE_AUTH(23, " Authorization denied"), 62 | SQLITE_FORMAT(24, " Auxiliary database format error"), 63 | SQLITE_RANGE(25, " 2nd parameter to sqlite3_bind out of range"), 64 | SQLITE_NOTADB(26, " File opened that is not a database file"), 65 | SQLITE_ROW(100, " sqlite3_step() has another row ready"), 66 | SQLITE_DONE(101, " sqlite3_step() has finished executing"); 67 | 68 | public final int code; 69 | public final String message; 70 | 71 | /** 72 | * Constructor that applies error code and message. 73 | * @param code Error code. 74 | * @param message Message for the error. 75 | */ 76 | private SQLiteErrorCode(int code, String message) 77 | { 78 | this.code = code; 79 | this.message = message; 80 | } 81 | 82 | /** 83 | * @param errorCode Error code. 84 | * @return Error message. 85 | */ 86 | public static SQLiteErrorCode getErrorCode(int errorCode) 87 | { 88 | for (SQLiteErrorCode each : SQLiteErrorCode.values()) 89 | { 90 | if (errorCode == each.code) 91 | return each; 92 | } 93 | return UNKNOWN_ERROR; 94 | } 95 | 96 | /** 97 | * @see java.lang.Enum#toString() 98 | */ 99 | @Override 100 | public String toString() 101 | { 102 | return String.format("[%s] %s", this.name(), message); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/org/sqlite/SQLiteJDBCLoader.java: -------------------------------------------------------------------------------- 1 | /*-------------------------------------------------------------------------- 2 | * Copyright 2007 Taro L. Saito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *--------------------------------------------------------------------------*/ 16 | //-------------------------------------- 17 | // SQLite JDBC Project 18 | // 19 | // SQLite.java 20 | // Since: 2007/05/10 21 | // 22 | // $URL$ 23 | // $Author$ 24 | //-------------------------------------- 25 | package org.sqlite; 26 | 27 | import java.io.BufferedInputStream; 28 | import java.io.ByteArrayOutputStream; 29 | import java.io.File; 30 | import java.io.FileInputStream; 31 | import java.io.FileOutputStream; 32 | import java.io.IOException; 33 | import java.io.InputStream; 34 | import java.net.URL; 35 | import java.security.DigestInputStream; 36 | import java.security.MessageDigest; 37 | import java.security.NoSuchAlgorithmException; 38 | import java.util.Properties; 39 | 40 | import org.sqlite.util.OSInfo; 41 | 42 | /** 43 | * Set the system properties, org.sqlite.lib.path, org.sqlite.lib.name, 44 | * appropriately so that the SQLite JDBC driver can find *.dll, *.jnilib and 45 | * *.so files, according to the current OS (win, linux, mac). 46 | * 47 | * The library files are automatically extracted from this project's package 48 | * (JAR). 49 | * 50 | * usage: call {@link #initialize()} before using SQLite JDBC driver. 51 | * 52 | * @author leo 53 | * 54 | */ 55 | public class SQLiteJDBCLoader 56 | { 57 | 58 | private static boolean extracted = false; 59 | 60 | /** 61 | * Loads SQLite native JDBC library. 62 | * @return True if SQLite native library is successfully loaded; false otherwise. 63 | */ 64 | public static boolean initialize() throws Exception { 65 | loadSQLiteNativeLibrary(); 66 | return extracted; 67 | } 68 | 69 | /** 70 | * @return True if the SQLite JDBC driver is set to pure Java mode; false otherwise. 71 | * @deprecated Pure Java no longer supported 72 | */ 73 | static boolean getPureJavaFlag() { 74 | return Boolean.parseBoolean(System.getProperty("sqlite.purejava", "false")); 75 | } 76 | 77 | /** 78 | * Checks if the SQLite JDBC driver is set to pure Java mode. 79 | * @return True if the SQLite JDBC driver is set to pure Java mode; false otherwise. 80 | * @deprecated Pure Java nolonger supported 81 | */ 82 | public static boolean isPureJavaMode() { 83 | return false; 84 | } 85 | 86 | /** 87 | * Checks if the SQLite JDBC driver is set to native mode. 88 | * @return True if the SQLite JDBC driver is set to native Java mode; false otherwise. 89 | */ 90 | public static boolean isNativeMode() throws Exception { 91 | // load the driver 92 | initialize(); 93 | return extracted; 94 | } 95 | 96 | /** 97 | * Computes the MD5 value of the input stream. 98 | * @param input InputStream. 99 | * @return Encrypted string for the InputStream. 100 | * @throws IOException 101 | * @throws NoSuchAlgorithmException 102 | */ 103 | static String md5sum(InputStream input) throws IOException { 104 | BufferedInputStream in = new BufferedInputStream(input); 105 | 106 | try { 107 | MessageDigest digest = java.security.MessageDigest.getInstance("MD5"); 108 | DigestInputStream digestInputStream = new DigestInputStream(in, digest); 109 | for (; digestInputStream.read() >= 0;) { 110 | 111 | } 112 | ByteArrayOutputStream md5out = new ByteArrayOutputStream(); 113 | md5out.write(digest.digest()); 114 | return md5out.toString(); 115 | } 116 | catch (NoSuchAlgorithmException e) { 117 | throw new IllegalStateException("MD5 algorithm is not available: " + e); 118 | } 119 | finally { 120 | in.close(); 121 | } 122 | } 123 | 124 | /** 125 | * Extracts and loads the specified library file to the target folder 126 | * @param libFolderForCurrentOS Library path. 127 | * @param libraryFileName Library name. 128 | * @param targetFolder Target folder. 129 | * @return 130 | */ 131 | private static boolean extractAndLoadLibraryFile(String libFolderForCurrentOS, String libraryFileName, 132 | String targetFolder) { 133 | String nativeLibraryFilePath = libFolderForCurrentOS + "/" + libraryFileName; 134 | // Include architecture name in temporary filename in order to avoid conflicts 135 | // when multiple JVMs with different architectures running at the same time 136 | final String prefix = "sqlite-" + getVersion() + "-" + OSInfo.getArchName() + "-"; 137 | 138 | String extractedLibFileName = prefix + libraryFileName; 139 | File extractedLibFile = new File(targetFolder, extractedLibFileName); 140 | 141 | try { 142 | if (extractedLibFile.exists()) { 143 | // test md5sum value 144 | String md5sum1 = md5sum(SQLiteJDBCLoader.class.getResourceAsStream(nativeLibraryFilePath)); 145 | String md5sum2 = md5sum(new FileInputStream(extractedLibFile)); 146 | 147 | if (md5sum1.equals(md5sum2)) { 148 | return loadNativeLibrary(targetFolder, extractedLibFileName); 149 | } 150 | else { 151 | // remove old native library file 152 | boolean deletionSucceeded = extractedLibFile.delete(); 153 | if (!deletionSucceeded) { 154 | throw new IOException("failed to remove existing native library file: " 155 | + extractedLibFile.getAbsolutePath()); 156 | } 157 | } 158 | } 159 | 160 | // extract file into the current directory 161 | InputStream reader = SQLiteJDBCLoader.class.getResourceAsStream(nativeLibraryFilePath); 162 | FileOutputStream writer = new FileOutputStream(extractedLibFile); 163 | byte[] buffer = new byte[1024]; 164 | int bytesRead = 0; 165 | while ((bytesRead = reader.read(buffer)) != -1) { 166 | writer.write(buffer, 0, bytesRead); 167 | } 168 | 169 | writer.close(); 170 | reader.close(); 171 | 172 | if (!System.getProperty("os.name").contains("Windows")) { 173 | try { 174 | Runtime.getRuntime().exec(new String[] { "chmod", "755", extractedLibFile.getAbsolutePath() }) 175 | .waitFor(); 176 | } 177 | catch (Throwable e) {} 178 | } 179 | 180 | return loadNativeLibrary(targetFolder, extractedLibFileName); 181 | } 182 | catch (IOException e) { 183 | System.err.println(e.getMessage()); 184 | return false; 185 | } 186 | 187 | } 188 | 189 | /** 190 | * Loads native library using the given path and name of the library. 191 | * @param path Path of the native library. 192 | * @param name Name of the native library. 193 | * @return True for successfully loading; false otherwise. 194 | */ 195 | private static synchronized boolean loadNativeLibrary(String path, String name) { 196 | File libPath = new File(path, name); 197 | if (libPath.exists()) { 198 | 199 | try { 200 | System.load(new File(path, name).getAbsolutePath()); 201 | return true; 202 | } 203 | catch (UnsatisfiedLinkError e) { 204 | System.err.println(e); 205 | return false; 206 | } 207 | 208 | } 209 | else 210 | return false; 211 | } 212 | 213 | /** 214 | * Loads SQLite native library using given path and name of the library. 215 | * @exception 216 | */ 217 | private static void loadSQLiteNativeLibrary() throws Exception { 218 | if (extracted) 219 | return; 220 | 221 | // Try loading library from org.sqlite.lib.path library path */ 222 | String sqliteNativeLibraryPath = System.getProperty("org.sqlite.lib.path"); 223 | String sqliteNativeLibraryName = System.getProperty("org.sqlite.lib.name"); 224 | if (sqliteNativeLibraryName == null) { 225 | sqliteNativeLibraryName = System.mapLibraryName("sqlitejdbc"); 226 | if (sqliteNativeLibraryName != null && sqliteNativeLibraryName.endsWith("dylib")) { 227 | sqliteNativeLibraryName = sqliteNativeLibraryName.replace("dylib", "jnilib"); 228 | } 229 | } 230 | 231 | if (sqliteNativeLibraryPath != null) { 232 | if (loadNativeLibrary(sqliteNativeLibraryPath, sqliteNativeLibraryName)) { 233 | extracted = true; 234 | return; 235 | } 236 | } 237 | 238 | // Load the os-dependent library from the jar file 239 | sqliteNativeLibraryPath = "/org/sqlite/native/" + OSInfo.getNativeLibFolderPathForCurrentOS(); 240 | 241 | if (SQLiteJDBCLoader.class.getResource(sqliteNativeLibraryPath + "/" + sqliteNativeLibraryName) == null) { 242 | extracted = false; 243 | throw new Exception("Error loading native library: " + sqliteNativeLibraryPath + "/" + sqliteNativeLibraryName); 244 | } 245 | 246 | // temporary library folder 247 | String tempFolder = new File(System.getProperty("java.io.tmpdir")).getAbsolutePath(); 248 | // Try extracting the library from jar 249 | if (extractAndLoadLibraryFile(sqliteNativeLibraryPath, sqliteNativeLibraryName, tempFolder)) { 250 | extracted = true; 251 | return; 252 | } 253 | 254 | extracted = false; 255 | return; 256 | } 257 | 258 | @SuppressWarnings("unused") 259 | private static void getNativeLibraryFolderForTheCurrentOS() { 260 | String osName = OSInfo.getOSName(); 261 | String archName = OSInfo.getArchName(); 262 | } 263 | 264 | /** 265 | * @return The major version of the SQLite JDBC driver. 266 | */ 267 | public static int getMajorVersion() { 268 | String[] c = getVersion().split( "\\." ); 269 | if( c.length == 0 ) { 270 | return 0; 271 | } 272 | try { 273 | return Integer.parseInt( c[0] ); 274 | } catch( NumberFormatException ex ) { 275 | return 1; 276 | } 277 | } 278 | 279 | /** 280 | * @return The minor version of the SQLite JDBC driver. 281 | */ 282 | public static int getMinorVersion() { 283 | String[] c = getVersion().split("\\."); 284 | return (c.length > 1) ? Integer.parseInt(c[1]) : 0; 285 | } 286 | 287 | /** 288 | * @return The version of the SQLite JDBC driver. 289 | */ 290 | public static String getVersion() { 291 | 292 | URL versionFile = SQLiteJDBCLoader.class.getResource("/META-INF/maven/org.xerial/sqlite-jdbc4/pom.properties"); 293 | if (versionFile == null) 294 | versionFile = SQLiteJDBCLoader.class.getResource("/META-INF/maven/org.xerial/sqlite-jdbc4/VERSION"); 295 | 296 | String version = "unknown"; 297 | try { 298 | if (versionFile != null) { 299 | Properties versionData = new Properties(); 300 | versionData.load(versionFile.openStream()); 301 | version = versionData.getProperty("version", version); 302 | version = version.trim().replaceAll("[^0-9\\.]", ""); 303 | } 304 | } 305 | catch (IOException e) { 306 | System.err.println(e); 307 | } 308 | return version; 309 | } 310 | 311 | } 312 | -------------------------------------------------------------------------------- /src/main/java/org/sqlite/SQLiteOpenMode.java: -------------------------------------------------------------------------------- 1 | /*-------------------------------------------------------------------------- 2 | * Copyright 2009 Taro L. Saito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *--------------------------------------------------------------------------*/ 16 | //-------------------------------------- 17 | // sqlite-jdbc Project 18 | // 19 | // SQLiteOpenMode.java 20 | // Since: Dec 8, 2009 21 | // 22 | // $URL$ 23 | // $Author$ 24 | //-------------------------------------- 25 | package org.sqlite; 26 | 27 | /** 28 | * Database file open modes of SQLite. 29 | * 30 | * See also http://sqlite.org/c3ref/open.html 31 | * 32 | * @author leo 33 | * 34 | */ 35 | public enum SQLiteOpenMode { 36 | READONLY(0x00000001), /* Ok for int SQLITE3_open_v2() */ 37 | READWRITE(0x00000002), /* Ok for int SQLITE3_open_v2() */ 38 | CREATE(0x00000004), /* Ok for int SQLITE3_open_v2() */ 39 | DELETEONCLOSE(0x00000008), /* VFS only */ 40 | EXCLUSIVE(0x00000010), /* VFS only */ 41 | OPEN_URI(0x00000040), /* Ok for sqlite3_open_v2() */ 42 | OPEN_MEMORY(0x00000080), /* Ok for sqlite3_open_v2() */ 43 | MAIN_DB(0x00000100), /* VFS only */ 44 | TEMP_DB(0x00000200), /* VFS only */ 45 | TRANSIENT_DB(0x00000400), /* VFS only */ 46 | MAIN_JOURNAL(0x00000800), /* VFS only */ 47 | TEMP_JOURNAL(0x00001000), /* VFS only */ 48 | SUBJOURNAL(0x00002000), /* VFS only */ 49 | MASTER_JOURNAL(0x00004000), /* VFS only */ 50 | NOMUTEX(0x00008000), /* Ok for int SQLITE3_open_v2() */ 51 | FULLMUTEX(0x00010000), /* Ok for int SQLITE3_open_v2() */ 52 | SHAREDCACHE(0x00020000), /* Ok for int SQLITE3_open_v2() */ 53 | PRIVATECACHE(0x00040000) /* Ok for sqlite3_open_v2() */ 54 | ; 55 | 56 | public final int flag; 57 | 58 | private SQLiteOpenMode(int flag) { 59 | this.flag = flag; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/org/sqlite/core/Codes.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 David Crawshaw 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package org.sqlite.core; 17 | 18 | public interface Codes 19 | { 20 | /** Successful result */ 21 | public static final int SQLITE_OK = 0; 22 | 23 | /** SQL error or missing database */ 24 | public static final int SQLITE_ERROR = 1; 25 | 26 | /** An internal logic error in SQLite */ 27 | public static final int SQLITE_INTERNAL = 2; 28 | 29 | /** Access permission denied */ 30 | public static final int SQLITE_PERM = 3; 31 | 32 | /** Callback routine requested an abort */ 33 | public static final int SQLITE_ABORT = 4; 34 | 35 | /** The database file is locked */ 36 | public static final int SQLITE_BUSY = 5; 37 | 38 | /** A table in the database is locked */ 39 | public static final int SQLITE_LOCKED = 6; 40 | 41 | /** A malloc() failed */ 42 | public static final int SQLITE_NOMEM = 7; 43 | 44 | /** Attempt to write a readonly database */ 45 | public static final int SQLITE_READONLY = 8; 46 | 47 | /** Operation terminated by sqlite_interrupt() */ 48 | public static final int SQLITE_INTERRUPT = 9; 49 | 50 | /** Some kind of disk I/O error occurred */ 51 | public static final int SQLITE_IOERR = 10; 52 | 53 | /** The database disk image is malformed */ 54 | public static final int SQLITE_CORRUPT = 11; 55 | 56 | /** (Internal Only) Table or record not found */ 57 | public static final int SQLITE_NOTFOUND = 12; 58 | 59 | /** Insertion failed because database is full */ 60 | public static final int SQLITE_FULL = 13; 61 | 62 | /** Unable to open the database file */ 63 | public static final int SQLITE_CANTOPEN = 14; 64 | 65 | /** Database lock protocol error */ 66 | public static final int SQLITE_PROTOCOL = 15; 67 | 68 | /** (Internal Only) Database table is empty */ 69 | public static final int SQLITE_EMPTY = 16; 70 | 71 | /** The database schema changed */ 72 | public static final int SQLITE_SCHEMA = 17; 73 | 74 | /** Too much data for one row of a table */ 75 | public static final int SQLITE_TOOBIG = 18; 76 | 77 | /** Abort due to constraint violation */ 78 | public static final int SQLITE_CONSTRAINT = 19; 79 | 80 | /** Data type mismatch */ 81 | public static final int SQLITE_MISMATCH = 20; 82 | 83 | /** Library used incorrectly */ 84 | public static final int SQLITE_MISUSE = 21; 85 | 86 | /** Uses OS features not supported on host */ 87 | public static final int SQLITE_NOLFS = 22; 88 | 89 | /** Authorization denied */ 90 | public static final int SQLITE_AUTH = 23; 91 | 92 | /** sqlite_step() has another row ready */ 93 | public static final int SQLITE_ROW = 100; 94 | 95 | /** sqlite_step() has finished executing */ 96 | public static final int SQLITE_DONE = 101; 97 | 98 | 99 | // types returned by sqlite3_column_type() 100 | 101 | public static final int SQLITE_INTEGER = 1; 102 | public static final int SQLITE_FLOAT = 2; 103 | public static final int SQLITE_TEXT = 3; 104 | public static final int SQLITE_BLOB = 4; 105 | public static final int SQLITE_NULL = 5; 106 | } 107 | -------------------------------------------------------------------------------- /src/main/java/org/sqlite/core/CoreDatabaseMetaData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 David Crawshaw 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | package org.sqlite.core; 18 | 19 | import java.sql.PreparedStatement; 20 | import java.sql.ResultSet; 21 | import java.sql.SQLException; 22 | import java.sql.Statement; 23 | import java.util.regex.Matcher; 24 | import java.util.regex.Pattern; 25 | 26 | import org.sqlite.SQLiteConnection; 27 | 28 | public abstract class CoreDatabaseMetaData 29 | { 30 | protected SQLiteConnection conn; 31 | protected PreparedStatement 32 | getTables = null, getTableTypes = null, 33 | getTypeInfo = null, getCatalogs = null, 34 | getSchemas = null, getUDTs = null, 35 | getColumnsTblName = null, getSuperTypes = null, 36 | getSuperTables = null, getTablePrivileges = null, 37 | getIndexInfo = null, getProcedures = null, 38 | getProcedureColumns = null, getAttributes = null, 39 | getBestRowIdentifier = null, getVersionColumns = null, 40 | getColumnPrivileges = null; 41 | 42 | /** 43 | * Used to save generating a new statement every call. 44 | */ 45 | protected PreparedStatement getGeneratedKeys = null; 46 | 47 | /** 48 | * Reference count. 49 | */ 50 | public int refCount = 1; 51 | 52 | /** 53 | * Constructor that applies the Connection object. 54 | * @param conn Connection object. 55 | */ 56 | protected CoreDatabaseMetaData(SQLiteConnection conn) { 57 | this.conn = conn; 58 | } 59 | 60 | public abstract ResultSet getGeneratedKeys() throws SQLException; 61 | 62 | /** 63 | * @throws SQLException 64 | */ 65 | protected void checkOpen() throws SQLException { 66 | if (conn == null) { 67 | throw new SQLException("connection closed"); 68 | } 69 | } 70 | 71 | /** 72 | * @throws SQLException 73 | */ 74 | public synchronized void close() throws SQLException { 75 | if (conn == null || refCount > 0) { 76 | return; 77 | } 78 | 79 | try { 80 | if (getTables != null) { 81 | getTables.close(); 82 | } 83 | if (getTableTypes != null) { 84 | getTableTypes.close(); 85 | } 86 | if (getTypeInfo != null) { 87 | getTypeInfo.close(); 88 | } 89 | if (getCatalogs != null) { 90 | getCatalogs.close(); 91 | } 92 | if (getSchemas != null) { 93 | getSchemas.close(); 94 | } 95 | if (getUDTs != null) { 96 | getUDTs.close(); 97 | } 98 | if (getColumnsTblName != null) { 99 | getColumnsTblName.close(); 100 | } 101 | if (getSuperTypes != null) { 102 | getSuperTypes.close(); 103 | } 104 | if (getSuperTables != null) { 105 | getSuperTables.close(); 106 | } 107 | if (getTablePrivileges != null) { 108 | getTablePrivileges.close(); 109 | } 110 | if (getIndexInfo != null) { 111 | getIndexInfo.close(); 112 | } 113 | if (getProcedures != null) { 114 | getProcedures.close(); 115 | } 116 | if (getProcedureColumns != null) { 117 | getProcedureColumns.close(); 118 | } 119 | if (getAttributes != null) { 120 | getAttributes.close(); 121 | } 122 | if (getBestRowIdentifier != null) { 123 | getBestRowIdentifier.close(); 124 | } 125 | if (getVersionColumns != null) { 126 | getVersionColumns.close(); 127 | } 128 | if (getColumnPrivileges != null) { 129 | getColumnPrivileges.close(); 130 | } 131 | if (getGeneratedKeys != null) { 132 | getGeneratedKeys.close(); 133 | } 134 | 135 | getTables = null; 136 | getTableTypes = null; 137 | getTypeInfo = null; 138 | getCatalogs = null; 139 | getSchemas = null; 140 | getUDTs = null; 141 | getColumnsTblName = null; 142 | getSuperTypes = null; 143 | getSuperTables = null; 144 | getTablePrivileges = null; 145 | getIndexInfo = null; 146 | getProcedures = null; 147 | getProcedureColumns = null; 148 | getAttributes = null; 149 | getBestRowIdentifier = null; 150 | getVersionColumns = null; 151 | getColumnPrivileges = null; 152 | getGeneratedKeys = null; 153 | } 154 | finally { 155 | conn = null; 156 | } 157 | } 158 | 159 | /** 160 | * Adds SQL string quotes to the given string. 161 | * @param tableName The string to quote. 162 | * @return The quoted string. 163 | */ 164 | protected static String quote(String tableName) { 165 | if (tableName == null) { 166 | return "null"; 167 | } 168 | else { 169 | return String.format("'%s'", tableName); 170 | } 171 | } 172 | 173 | /** 174 | * Applies SQL escapes for special characters in a given string. 175 | * @param val The string to escape. 176 | * @return The SQL escaped string. 177 | */ 178 | protected String escape(final String val) { 179 | // TODO: this function is ugly, pass this work off to SQLite, then we 180 | // don't have to worry about Unicode 4, other characters needing 181 | // escaping, etc. 182 | int len = val.length(); 183 | StringBuilder buf = new StringBuilder(len); 184 | for (int i = 0; i < len; i++) { 185 | if (val.charAt(i) == '\'') { 186 | buf.append('\''); 187 | } 188 | buf.append(val.charAt(i)); 189 | } 190 | return buf.toString(); 191 | } 192 | 193 | // inner classes 194 | 195 | /** 196 | * Pattern used to extract column order for an unnamed primary key. 197 | */ 198 | protected final static Pattern PK_UNNAMED_PATTERN = 199 | Pattern.compile(".*\\sPRIMARY\\s+KEY\\s+\\((.*?,+.*?)\\).*", 200 | Pattern.CASE_INSENSITIVE | Pattern.DOTALL); 201 | 202 | /** 203 | * Pattern used to extract a named primary key. 204 | */ 205 | protected final static Pattern PK_NAMED_PATTERN = 206 | Pattern.compile(".*\\sCONSTRAINT\\s+(.*?)\\s+PRIMARY\\s+KEY\\s+\\((.*?)\\).*", 207 | Pattern.CASE_INSENSITIVE | Pattern.DOTALL); 208 | 209 | /** 210 | * Parses the sqlite_master table for a table's primary key 211 | */ 212 | public class PrimaryKeyFinder { 213 | /** The table name. */ 214 | String table; 215 | 216 | /** The primary key name. */ 217 | String pkName = null; 218 | 219 | /** The column(s) for the primary key. */ 220 | String pkColumns[] = null; 221 | 222 | /** 223 | * Constructor. 224 | * @param table The table for which to get find a primary key. 225 | * @throws SQLException 226 | */ 227 | public PrimaryKeyFinder(String table) throws SQLException { 228 | this.table = table; 229 | 230 | if (table == null || table.trim().length() == 0) { 231 | throw new SQLException("Invalid table name: '" + this.table + "'"); 232 | } 233 | 234 | Statement stat = null; 235 | ResultSet rs = null; 236 | 237 | try { 238 | stat = conn.createStatement(); 239 | // read create SQL script for table 240 | rs = stat.executeQuery("select sql from sqlite_master where" + 241 | " lower(name) = lower('" + escape(table) + "') and type = 'table'"); 242 | 243 | if (!rs.next()) 244 | throw new SQLException("Table not found: '" + table + "'"); 245 | 246 | Matcher matcher = PK_NAMED_PATTERN.matcher(rs.getString(1)); 247 | if (matcher.find()){ 248 | pkName = '\'' + escape(matcher.group(1).toLowerCase()) + '\''; 249 | pkColumns = matcher.group(2).split(","); 250 | } 251 | else { 252 | matcher = PK_UNNAMED_PATTERN.matcher(rs.getString(1)); 253 | if (matcher.find()){ 254 | pkColumns = matcher.group(1).split(","); 255 | } 256 | } 257 | 258 | if (pkColumns == null) { 259 | rs = stat.executeQuery("pragma table_info('" + escape(table) + "');"); 260 | while(rs.next()) { 261 | if (rs.getBoolean(6)) 262 | pkColumns = new String[]{rs.getString(2)}; 263 | } 264 | } 265 | 266 | if (pkColumns != null) 267 | for (int i = 0; i < pkColumns.length; i++) { 268 | pkColumns[i] = pkColumns[i].toLowerCase().trim(); 269 | } 270 | } 271 | finally { 272 | try { 273 | if (rs != null) rs.close(); 274 | } catch (Exception e) {} 275 | try { 276 | if (stat != null) stat.close(); 277 | } catch (Exception e) {} 278 | } 279 | } 280 | 281 | /** 282 | * @return The primary key name if any. 283 | */ 284 | public String getName() { 285 | return pkName; 286 | } 287 | 288 | /** 289 | * @return Array of primary key column(s) if any. 290 | */ 291 | public String[] getColumns() { 292 | return pkColumns; 293 | } 294 | } 295 | 296 | /** 297 | * @see java.lang.Object#finalize() 298 | */ 299 | protected void finalize() throws Throwable { 300 | close(); 301 | } 302 | } 303 | -------------------------------------------------------------------------------- /src/main/java/org/sqlite/core/CorePreparedStatement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 David Crawshaw 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | package org.sqlite.core; 18 | 19 | import java.sql.Date; 20 | import java.sql.SQLException; 21 | 22 | import org.sqlite.SQLiteConnection; 23 | import org.sqlite.jdbc4.JDBC4Statement; 24 | 25 | public abstract class CorePreparedStatement extends JDBC4Statement 26 | { 27 | protected int columnCount; 28 | protected int paramCount; 29 | 30 | /** 31 | * Constructs a prepared statement on a provided connection. 32 | * @param conn Connection on which to create the prepared statement. 33 | * @param sql The SQL script to prepare. 34 | * @throws SQLException 35 | */ 36 | protected CorePreparedStatement(SQLiteConnection conn, String sql) throws SQLException { 37 | super(conn); 38 | 39 | this.sql = sql; 40 | db.prepare(this); 41 | rs.colsMeta = db.column_names(pointer); 42 | columnCount = db.column_count(pointer); 43 | paramCount = db.bind_parameter_count(pointer); 44 | batch = null; 45 | batchPos = 0; 46 | } 47 | 48 | /** 49 | * @see org.sqlite.core.CoreStatement#finalize() 50 | */ 51 | @Override 52 | protected void finalize() throws SQLException { 53 | close(); 54 | } 55 | 56 | /** 57 | * Checks if values are bound to statement parameters. 58 | * @throws SQLException 59 | */ 60 | protected void checkParameters() throws SQLException { 61 | if (batch == null && paramCount > 0) 62 | throw new SQLException("Values not bound to statement"); 63 | } 64 | 65 | /** 66 | * @see org.sqlite.jdbc3.JDBC3Statement#executeBatch() 67 | */ 68 | @Override 69 | public int[] executeBatch() throws SQLException { 70 | if (batchPos == 0) { 71 | return new int[] {}; 72 | } 73 | 74 | checkParameters(); 75 | 76 | try { 77 | return db.executeBatch(pointer, batchPos / paramCount, batch); 78 | } 79 | finally { 80 | clearBatch(); 81 | } 82 | } 83 | 84 | /** 85 | * @see org.sqlite.jdbc3.JDBC3Statement#getUpdateCount() 86 | */ 87 | @Override 88 | public int getUpdateCount() throws SQLException { 89 | if (pointer == 0 || resultsWaiting || rs.isOpen()) { 90 | return -1; 91 | } 92 | 93 | return db.changes(); 94 | } 95 | 96 | // PARAMETER FUNCTIONS ////////////////////////////////////////// 97 | 98 | /** 99 | * Assigns the object value to the element at the specific position of array 100 | * batch. 101 | * @param pos 102 | * @param value 103 | * @throws SQLException 104 | */ 105 | protected void batch(int pos, Object value) throws SQLException { 106 | checkOpen(); 107 | if (batch == null) { 108 | batch = new Object[paramCount]; 109 | } 110 | batch[batchPos + pos - 1] = value; 111 | } 112 | 113 | 114 | /** 115 | * Store the date in the user's preferred format (text, int, or real) 116 | */ 117 | protected void setDateByMilliseconds(int pos, Long value) throws SQLException { 118 | switch(conn.dateClass) { 119 | case TEXT: 120 | batch(pos, conn.dateFormat.format(new Date(value))); 121 | break; 122 | 123 | case REAL: 124 | // long to Julian date 125 | batch(pos, new Double((value/86400000.0) + 2440587.5)); 126 | break; 127 | 128 | default: //INTEGER: 129 | batch(pos, new Long(value / conn.dateMultiplier)); 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/main/java/org/sqlite/core/CoreResultSet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 David Crawshaw 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package org.sqlite.core; 17 | 18 | import java.sql.SQLException; 19 | import java.sql.Statement; 20 | 21 | /** 22 | * Implements a JDBC ResultSet. 23 | */ 24 | public abstract class CoreResultSet implements Codes 25 | { 26 | protected final CoreStatement stmt; 27 | protected final DB db; 28 | 29 | public boolean open = false; // true means have results and can iterate them 30 | public int maxRows; // max. number of rows as set by a Statement 31 | public String[] cols = null; // if null, the RS is closed() 32 | public String[] colsMeta = null; // same as cols, but used by Meta interface 33 | protected boolean[][] meta = null; 34 | 35 | protected int limitRows; // 0 means no limit, must check against maxRows 36 | protected int row = 0; // number of current row, starts at 1 (0 is for before loading data) 37 | protected int lastCol; // last column accessed, for wasNull(). -1 if none 38 | 39 | public boolean closeStmt; 40 | 41 | /** 42 | * Default constructor for a given statement. 43 | * @param stmt The statement. 44 | * @param closeStmt TODO 45 | */ 46 | protected CoreResultSet(CoreStatement stmt) { 47 | this.stmt = stmt; 48 | this.db = stmt.db; 49 | } 50 | 51 | // INTERNAL FUNCTIONS /////////////////////////////////////////// 52 | 53 | /** 54 | * Checks the status of the result set. 55 | * @return True if has results and can iterate them; false otherwise. 56 | */ 57 | public boolean isOpen() { 58 | return open; 59 | } 60 | 61 | /** 62 | * @throws SQLException if ResultSet is not open. 63 | */ 64 | protected void checkOpen() throws SQLException { 65 | if (!open) { 66 | throw new SQLException("ResultSet closed"); 67 | } 68 | } 69 | 70 | /** 71 | * Takes col in [1,x] form, returns in [0,x-1] form 72 | * @param col 73 | * @return 74 | * @throws SQLException 75 | */ 76 | public int checkCol(int col) throws SQLException { 77 | if (colsMeta == null) { 78 | throw new IllegalStateException("SQLite JDBC: inconsistent internal state"); 79 | } 80 | if (col < 1 || col > colsMeta.length) { 81 | throw new SQLException("column " + col + " out of bounds [1," + colsMeta.length + "]"); 82 | } 83 | return --col; 84 | } 85 | 86 | /** 87 | * Takes col in [1,x] form, marks it as last accessed and returns [0,x-1] 88 | * @param col 89 | * @return 90 | * @throws SQLException 91 | */ 92 | protected int markCol(int col) throws SQLException { 93 | checkOpen(); 94 | checkCol(col); 95 | lastCol = col; 96 | return --col; 97 | } 98 | 99 | /** 100 | * @throws SQLException 101 | */ 102 | public void checkMeta() throws SQLException { 103 | checkCol(1); 104 | if (meta == null) { 105 | meta = db.column_metadata(stmt.pointer); 106 | } 107 | } 108 | 109 | public void close() throws SQLException { 110 | cols = null; 111 | colsMeta = null; 112 | meta = null; 113 | open = false; 114 | limitRows = 0; 115 | row = 0; 116 | lastCol = -1; 117 | 118 | if (stmt == null) { 119 | return; 120 | } 121 | 122 | if (stmt != null && stmt.pointer != 0) { 123 | db.reset(stmt.pointer); 124 | 125 | if (closeStmt) { 126 | closeStmt = false; // break recursive call 127 | ((Statement)stmt).close(); 128 | } 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/main/java/org/sqlite/core/CoreStatement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 David Crawshaw 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package org.sqlite.core; 17 | 18 | import java.sql.ResultSet; 19 | import java.sql.SQLException; 20 | 21 | import org.sqlite.SQLiteConnection; 22 | import org.sqlite.jdbc4.JDBC4ResultSet; 23 | 24 | public abstract class CoreStatement implements Codes 25 | { 26 | public final SQLiteConnection conn; 27 | protected final DB db; 28 | protected final CoreResultSet rs; 29 | 30 | protected CoreDatabaseMetaData metadata; 31 | 32 | public long pointer; 33 | protected String sql = null; 34 | 35 | protected int batchPos; 36 | protected Object[] batch = null; 37 | protected boolean resultsWaiting = false; 38 | 39 | protected CoreStatement(SQLiteConnection c) { 40 | conn = c; 41 | db = conn.db(); 42 | rs = new JDBC4ResultSet(this); 43 | } 44 | 45 | /** 46 | * @throws SQLException If the database is not opened. 47 | */ 48 | protected final void checkOpen() throws SQLException { 49 | if (pointer == 0) 50 | throw new SQLException("statement is not executing"); 51 | } 52 | 53 | /** 54 | * @return True if the database is opened; false otherwise. 55 | * @throws SQLException 56 | */ 57 | boolean isOpen() throws SQLException { 58 | return (pointer != 0); 59 | } 60 | 61 | /** 62 | * Calls sqlite3_step() and sets up results. Expects a clean stmt. 63 | * @return True if the ResultSet has at least one row; false otherwise. 64 | * @throws SQLException If the given SQL statement is null or no database is open. 65 | */ 66 | protected boolean exec() throws SQLException { 67 | if (sql == null) 68 | throw new SQLException("SQLiteJDBC internal error: sql==null"); 69 | if (rs.isOpen()) 70 | throw new SQLException("SQLite JDBC internal error: rs.isOpen() on exec."); 71 | 72 | boolean rc = false; 73 | try { 74 | rc = db.execute(this, null); 75 | } 76 | finally { 77 | resultsWaiting = rc; 78 | } 79 | 80 | return db.column_count(pointer) != 0; 81 | } 82 | 83 | /** 84 | * Executes SQL statement and throws SQLExceptions if the given SQL 85 | * statement is null or no database is open. 86 | * @param sql SQL statement. 87 | * @return True if the ResultSet has at least one row; false otherwise. 88 | * @throws SQLException If the given SQL statement is null or no database is open. 89 | */ 90 | protected boolean exec(String sql) throws SQLException { 91 | if (sql == null) 92 | throw new SQLException("SQLiteJDBC internal error: sql==null"); 93 | if (rs.isOpen()) 94 | throw new SQLException("SQLite JDBC internal error: rs.isOpen() on exec."); 95 | 96 | boolean rc = false; 97 | try { 98 | rc = db.execute(sql); 99 | } 100 | finally { 101 | resultsWaiting = rc; 102 | } 103 | 104 | return db.column_count(pointer) != 0; 105 | } 106 | 107 | protected void internalClose() throws SQLException { 108 | if (db.conn.isClosed()) 109 | throw DB.newSQLException(SQLITE_ERROR, "Connection is closed"); 110 | 111 | if (pointer == 0) 112 | return; 113 | 114 | rs.close(); 115 | batch = null; 116 | batchPos = 0; 117 | int resp = db.finalize(this); 118 | 119 | if (resp != SQLITE_OK && resp != SQLITE_MISUSE) 120 | db.throwex(); 121 | } 122 | 123 | public abstract ResultSet executeQuery(String sql, boolean closeStmt) throws SQLException; 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/org/sqlite/core/StringEscaper.java: -------------------------------------------------------------------------------- 1 | package org.sqlite.core; 2 | 3 | import java.sql.SQLException; 4 | 5 | 6 | /** 7 | * @author Philip DeCamp 8 | */ 9 | public class StringEscaper { 10 | 11 | public static String escape( String val ) { 12 | return val == null ? null : val.replace( ".", "''" ); 13 | } 14 | 15 | 16 | public static String format( Object object ) throws SQLException { 17 | if( object == null ) { 18 | return "null"; 19 | } 20 | 21 | if( object instanceof String ) { 22 | String str = (String)object; 23 | final int len = str.length(); 24 | StringBuilder s = new StringBuilder( len + 4 ); 25 | s.append( '\'' ); 26 | 27 | for( int i = 0; i < len; i++ ) { 28 | char c = str.charAt( i ); 29 | s.append( c ); 30 | if( c == '\'' ) { 31 | s.append( '\'' ); 32 | } 33 | } 34 | 35 | s.append( '\'' ); 36 | return s.toString(); 37 | } 38 | 39 | if( object instanceof Number || object instanceof Boolean ) { 40 | return object.toString(); 41 | } 42 | 43 | if( object instanceof byte[] ) { 44 | byte[] arr = (byte[])object; 45 | StringBuilder sb = new StringBuilder( 2 * arr.length + 3 ); 46 | sb.append( "x'" ); 47 | 48 | for( int i = 0; i < arr.length; i++ ) { 49 | sb.append( toHex( arr[i] ) >>> 4 ); 50 | sb.append( toHex( arr[i] ) & 0xF ); 51 | } 52 | 53 | sb.append( '\'' ); 54 | return sb.toString(); 55 | } 56 | 57 | throw new SQLException( "Unexpected value type: " + object.getClass() ); 58 | } 59 | 60 | 61 | private static char toHex( int nibble ) { 62 | return (char)( nibble < 10 ? '0' + nibble : 'A' + nibble - 10 ); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/org/sqlite/javax/SQLiteConnectionPoolDataSource.java: -------------------------------------------------------------------------------- 1 | /*-------------------------------------------------------------------------- 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | *--------------------------------------------------------------------------*/ 14 | package org.sqlite.javax; 15 | import java.sql.SQLException; 16 | import javax.sql.PooledConnection; 17 | 18 | import org.sqlite.SQLiteConfig; 19 | import org.sqlite.SQLiteDataSource; 20 | 21 | public class SQLiteConnectionPoolDataSource extends SQLiteDataSource implements javax.sql.ConnectionPoolDataSource { 22 | 23 | /** 24 | * Default constructor. 25 | */ 26 | public SQLiteConnectionPoolDataSource () { 27 | super(); 28 | } 29 | 30 | /** 31 | * Creates a data source based on the provided configuration. 32 | * @param config The configuration for the data source. 33 | */ 34 | public SQLiteConnectionPoolDataSource(SQLiteConfig config) { 35 | super(config); 36 | } 37 | 38 | /** 39 | * @see javax.sql.ConnectionPoolDataSource#getPooledConnection() 40 | */ 41 | public PooledConnection getPooledConnection() throws SQLException { 42 | return getPooledConnection(null, null); 43 | } 44 | 45 | /** 46 | * @see javax.sql.ConnectionPoolDataSource#getPooledConnection(java.lang.String, java.lang.String) 47 | */ 48 | public PooledConnection getPooledConnection(String user, String password) throws SQLException { 49 | return new SQLitePooledConnection(getConnection(user, password)); 50 | } 51 | } -------------------------------------------------------------------------------- /src/main/java/org/sqlite/javax/SQLitePooledConnection.java: -------------------------------------------------------------------------------- 1 | /*-------------------------------------------------------------------------- 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | *--------------------------------------------------------------------------*/ 14 | package org.sqlite.javax; 15 | 16 | import javax.sql.ConnectionEvent; 17 | import javax.sql.ConnectionEventListener; 18 | import javax.sql.PooledConnection; 19 | import org.sqlite.jdbc4.JDBC4PooledConnection; 20 | 21 | import java.lang.reflect.InvocationHandler; 22 | import java.lang.reflect.InvocationTargetException; 23 | import java.lang.reflect.Method; 24 | import java.lang.reflect.Proxy; 25 | import java.sql.Connection; 26 | import java.sql.SQLException; 27 | import java.util.ArrayList; 28 | import java.util.List; 29 | 30 | public class SQLitePooledConnection extends JDBC4PooledConnection implements PooledConnection { 31 | 32 | protected Connection physicalConn; 33 | protected volatile Connection handleConn; 34 | 35 | protected List listeners = new ArrayList(); 36 | 37 | /** 38 | * Constructor. 39 | * @param physicalConn The physical Connection. 40 | */ 41 | protected SQLitePooledConnection(Connection physicalConn) { 42 | this.physicalConn = physicalConn; 43 | } 44 | 45 | /** 46 | * @see javax.sql.PooledConnection#close() 47 | */ 48 | public void close() throws SQLException { 49 | if (handleConn != null) { 50 | listeners.clear(); 51 | handleConn.close(); 52 | } 53 | 54 | if (physicalConn != null) { 55 | try { 56 | physicalConn.close(); 57 | } finally { 58 | physicalConn = null; 59 | } 60 | } 61 | } 62 | 63 | /** 64 | * @see javax.sql.PooledConnection#getConnection() 65 | */ 66 | public Connection getConnection() throws SQLException { 67 | if (handleConn != null) 68 | handleConn.close(); 69 | 70 | handleConn = (Connection)Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{Connection.class}, 71 | new InvocationHandler() { 72 | boolean isClosed; 73 | 74 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 75 | try { 76 | String name = method.getName(); 77 | if ("close".equals(name)) { 78 | ConnectionEvent event = new ConnectionEvent(SQLitePooledConnection.this); 79 | 80 | for (int i = listeners.size() - 1; i >= 0; i--) { 81 | listeners.get(i).connectionClosed(event); 82 | } 83 | 84 | if (!physicalConn.getAutoCommit()) { 85 | physicalConn.rollback(); 86 | } 87 | physicalConn.setAutoCommit(true); 88 | isClosed = true; 89 | 90 | return null; // don't close physical connection 91 | } 92 | else if ("isClosed".equals(name)) { 93 | if (!isClosed) 94 | isClosed = ((Boolean)method.invoke(physicalConn, args)).booleanValue(); 95 | 96 | return isClosed; 97 | } 98 | 99 | if (isClosed) { 100 | throw new SQLException ("Connection is closed"); 101 | } 102 | 103 | return method.invoke(physicalConn, args); 104 | } 105 | catch (SQLException e){ 106 | if ("database connection closed".equals(e.getMessage())) { 107 | ConnectionEvent event = new ConnectionEvent(SQLitePooledConnection.this, e); 108 | 109 | for (int i = listeners.size() - 1; i >= 0; i--) { 110 | listeners.get(i).connectionErrorOccurred(event); 111 | } 112 | } 113 | 114 | throw e; 115 | } 116 | catch (InvocationTargetException ex) { 117 | throw ex.getCause(); 118 | } 119 | } 120 | }); 121 | 122 | return handleConn; 123 | } 124 | 125 | /** 126 | * @see javax.sql.PooledConnection#addConnectionEventListener(javax.sql.ConnectionEventListener) 127 | */ 128 | public void addConnectionEventListener(ConnectionEventListener listener) { 129 | listeners.add(listener); 130 | } 131 | 132 | /** 133 | * @see javax.sql.PooledConnection#removeConnectionEventListener(javax.sql.ConnectionEventListener) 134 | */ 135 | public void removeConnectionEventListener(ConnectionEventListener listener) { 136 | listeners.remove(listener); 137 | } 138 | } -------------------------------------------------------------------------------- /src/main/java/org/sqlite/jdbc3/JDBC3Connection.java: -------------------------------------------------------------------------------- 1 | package org.sqlite.jdbc3; 2 | 3 | import java.sql.CallableStatement; 4 | import java.sql.DatabaseMetaData; 5 | import java.sql.PreparedStatement; 6 | import java.sql.ResultSet; 7 | import java.sql.SQLException; 8 | import java.sql.SQLWarning; 9 | import java.sql.Savepoint; 10 | import java.sql.Statement; 11 | import java.sql.Struct; 12 | import java.util.Map; 13 | import java.util.Properties; 14 | 15 | import org.sqlite.SQLiteOpenMode; 16 | import org.sqlite.core.CoreConnection; 17 | 18 | public abstract class JDBC3Connection extends CoreConnection { 19 | 20 | protected JDBC3Connection(String url, String fileName, Properties prop) throws SQLException { 21 | super(url, fileName, prop); 22 | } 23 | 24 | /** 25 | * @see java.sql.Connection#getCatalog() 26 | */ 27 | public String getCatalog() throws SQLException { 28 | checkOpen(); 29 | return null; 30 | } 31 | 32 | /** 33 | * @see java.sql.Connection#setCatalog(java.lang.String) 34 | */ 35 | public void setCatalog(String catalog) throws SQLException { 36 | checkOpen(); 37 | } 38 | 39 | /** 40 | * @see java.sql.Connection#getHoldability() 41 | */ 42 | public int getHoldability() throws SQLException { 43 | checkOpen(); 44 | return ResultSet.CLOSE_CURSORS_AT_COMMIT; 45 | } 46 | 47 | /** 48 | * @see java.sql.Connection#setHoldability(int) 49 | */ 50 | public void setHoldability(int h) throws SQLException { 51 | checkOpen(); 52 | if (h != ResultSet.CLOSE_CURSORS_AT_COMMIT) 53 | throw new SQLException("SQLite only supports CLOSE_CURSORS_AT_COMMIT"); 54 | } 55 | 56 | /** 57 | * @see java.sql.Connection#getTransactionIsolation() 58 | */ 59 | public int getTransactionIsolation() { 60 | return transactionIsolation; 61 | } 62 | 63 | /** 64 | * @see java.sql.Connection#setTransactionIsolation(int) 65 | */ 66 | public void setTransactionIsolation(int level) throws SQLException { 67 | checkOpen(); 68 | 69 | switch (level) { 70 | case java.sql.Connection.TRANSACTION_SERIALIZABLE: 71 | db.exec("PRAGMA read_uncommitted = false;"); 72 | break; 73 | case java.sql.Connection.TRANSACTION_READ_UNCOMMITTED: 74 | db.exec("PRAGMA read_uncommitted = true;"); 75 | break; 76 | default: 77 | throw new SQLException("SQLite supports only TRANSACTION_SERIALIZABLE and TRANSACTION_READ_UNCOMMITTED."); 78 | } 79 | transactionIsolation = level; 80 | } 81 | /** 82 | * @see java.sql.Connection#getTypeMap() 83 | */ 84 | public Map> getTypeMap() throws SQLException { 85 | throw new SQLException("not yet implemented"); 86 | } 87 | 88 | /** 89 | * @see java.sql.Connection#setTypeMap(java.util.Map) 90 | */ 91 | @SuppressWarnings("rawtypes") 92 | public void setTypeMap(Map map) throws SQLException { 93 | throw new SQLException("not yet implemented"); 94 | } 95 | 96 | /** 97 | * @see java.sql.Connection#isReadOnly() 98 | */ 99 | public boolean isReadOnly() throws SQLException { 100 | return (openModeFlags & SQLiteOpenMode.READONLY.flag) != 0; 101 | } 102 | 103 | /** 104 | * @see java.sql.Connection#setReadOnly(boolean) 105 | */ 106 | public void setReadOnly(boolean ro) throws SQLException { 107 | // trying to change read-only flag 108 | if (ro != isReadOnly()) { 109 | throw new SQLException( 110 | "Cannot change read-only flag after establishing a connection." + 111 | " Use SQLiteConfig#setReadOnly and SQLiteConfig.createConnection()."); 112 | } 113 | } 114 | 115 | public abstract DatabaseMetaData getMetaData() throws SQLException; 116 | 117 | /** 118 | * @see java.sql.Connection#nativeSQL(java.lang.String) 119 | */ 120 | public String nativeSQL(String sql) { 121 | return sql; 122 | } 123 | 124 | /** 125 | * @see java.sql.Connection#clearWarnings() 126 | */ 127 | public void clearWarnings() throws SQLException {} 128 | 129 | /** 130 | * @see java.sql.Connection#getWarnings() 131 | */ 132 | public SQLWarning getWarnings() throws SQLException { 133 | return null; 134 | } 135 | 136 | /** 137 | * @see java.sql.Connection#getAutoCommit() 138 | */ 139 | public boolean getAutoCommit() throws SQLException { 140 | checkOpen(); 141 | return autoCommit; 142 | } 143 | 144 | /** 145 | * @see java.sql.Connection#setAutoCommit(boolean) 146 | */ 147 | public void setAutoCommit(boolean ac) throws SQLException { 148 | checkOpen(); 149 | if (autoCommit == ac) 150 | return; 151 | autoCommit = ac; 152 | db.exec(autoCommit ? "commit;" : beginCommandMap.get(transactionMode)); 153 | } 154 | 155 | /** 156 | * @see java.sql.Connection#commit() 157 | */ 158 | public void commit() throws SQLException { 159 | checkOpen(); 160 | if (autoCommit) 161 | throw new SQLException("database in auto-commit mode"); 162 | db.exec("commit;"); 163 | db.exec(beginCommandMap.get(transactionMode)); 164 | } 165 | 166 | /** 167 | * @see java.sql.Connection#rollback() 168 | */ 169 | public void rollback() throws SQLException { 170 | checkOpen(); 171 | if (autoCommit) 172 | throw new SQLException("database in auto-commit mode"); 173 | db.exec("rollback;"); 174 | db.exec(beginCommandMap.get(transactionMode)); 175 | } 176 | 177 | /** 178 | * @see java.sql.Connection#createStatement() 179 | */ 180 | public Statement createStatement() throws SQLException { 181 | return createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, 182 | ResultSet.CLOSE_CURSORS_AT_COMMIT); 183 | } 184 | 185 | /** 186 | * @see java.sql.Connection#createStatement(int, int) 187 | */ 188 | public Statement createStatement(int rsType, int rsConcurr) throws SQLException { 189 | return createStatement(rsType, rsConcurr, ResultSet.CLOSE_CURSORS_AT_COMMIT); 190 | } 191 | 192 | /** 193 | * @see java.sql.Connection#createStatement(int, int, int) 194 | */ 195 | public abstract Statement createStatement(int rst, int rsc, int rsh) throws SQLException; 196 | 197 | /** 198 | * @see java.sql.Connection#prepareCall(java.lang.String) 199 | */ 200 | public CallableStatement prepareCall(String sql) throws SQLException { 201 | return prepareCall(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, 202 | ResultSet.CLOSE_CURSORS_AT_COMMIT); 203 | } 204 | 205 | /** 206 | * @see java.sql.Connection#prepareCall(java.lang.String, int, int) 207 | */ 208 | public CallableStatement prepareCall(String sql, int rst, int rsc) throws SQLException { 209 | return prepareCall(sql, rst, rsc, ResultSet.CLOSE_CURSORS_AT_COMMIT); 210 | } 211 | 212 | /** 213 | * @see java.sql.Connection#prepareCall(java.lang.String, int, int, int) 214 | */ 215 | public CallableStatement prepareCall(String sql, int rst, int rsc, int rsh) throws SQLException { 216 | throw new SQLException("SQLite does not support Stored Procedures"); 217 | } 218 | 219 | /** 220 | * @see java.sql.Connection#prepareStatement(java.lang.String) 221 | */ 222 | public PreparedStatement prepareStatement(String sql) throws SQLException { 223 | return prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); 224 | } 225 | 226 | /** 227 | * @see java.sql.Connection#prepareStatement(java.lang.String, int) 228 | */ 229 | public PreparedStatement prepareStatement(String sql, int autoC) throws SQLException { 230 | return prepareStatement(sql); 231 | } 232 | 233 | /** 234 | * @see java.sql.Connection#prepareStatement(java.lang.String, int[]) 235 | */ 236 | public PreparedStatement prepareStatement(String sql, int[] colInds) throws SQLException { 237 | return prepareStatement(sql); 238 | } 239 | 240 | /** 241 | * @see java.sql.Connection#prepareStatement(java.lang.String, java.lang.String[]) 242 | */ 243 | public PreparedStatement prepareStatement(String sql, String[] colNames) throws SQLException { 244 | return prepareStatement(sql); 245 | } 246 | 247 | /** 248 | * @see java.sql.Connection#prepareStatement(java.lang.String, int, int) 249 | */ 250 | public PreparedStatement prepareStatement(String sql, int rst, int rsc) throws SQLException { 251 | return prepareStatement(sql, rst, rsc, ResultSet.CLOSE_CURSORS_AT_COMMIT); 252 | } 253 | 254 | /** 255 | * @see java.sql.Connection#prepareStatement(java.lang.String, int, int, int) 256 | */ 257 | public abstract PreparedStatement prepareStatement(String sql, int rst, int rsc, int rsh) throws SQLException; 258 | 259 | // UNUSED FUNCTIONS ///////////////////////////////////////////// 260 | 261 | /** 262 | * @see java.sql.Connection#setSavepoint() 263 | */ 264 | public Savepoint setSavepoint() throws SQLException { 265 | throw new SQLException("unsupported by SQLite: savepoints"); 266 | } 267 | 268 | /** 269 | * @see java.sql.Connection#setSavepoint(java.lang.String) 270 | */ 271 | public Savepoint setSavepoint(String name) throws SQLException { 272 | throw new SQLException("unsupported by SQLite: savepoints"); 273 | } 274 | 275 | /** 276 | * @see java.sql.Connection#releaseSavepoint(java.sql.Savepoint) 277 | */ 278 | public void releaseSavepoint(Savepoint savepoint) throws SQLException { 279 | throw new SQLException("unsupported by SQLite: savepoints"); 280 | } 281 | 282 | /** 283 | * @see java.sql.Connection#rollback(java.sql.Savepoint) 284 | */ 285 | public void rollback(Savepoint savepoint) throws SQLException { 286 | throw new SQLException("unsupported by SQLite: savepoints"); 287 | } 288 | 289 | public Struct createStruct(String t, Object[] attr) throws SQLException { 290 | throw new SQLException("unsupported by SQLite"); 291 | } 292 | } 293 | -------------------------------------------------------------------------------- /src/main/java/org/sqlite/jdbc4/JDBC4Connection.java: -------------------------------------------------------------------------------- 1 | package org.sqlite.jdbc4; 2 | 3 | import java.sql.Array; 4 | import java.sql.Blob; 5 | import java.sql.Clob; 6 | import java.sql.Connection; 7 | import java.sql.DatabaseMetaData; 8 | import java.sql.NClob; 9 | import java.sql.PreparedStatement; 10 | import java.sql.SQLClientInfoException; 11 | import java.sql.SQLException; 12 | import java.sql.SQLXML; 13 | import java.sql.Statement; 14 | import java.util.Properties; 15 | 16 | import org.sqlite.SQLiteConnection; 17 | import org.sqlite.jdbc3.JDBC3Connection; 18 | 19 | public abstract class JDBC4Connection extends JDBC3Connection implements Connection { 20 | 21 | public JDBC4Connection(String url, String fileName, Properties prop) throws SQLException 22 | { 23 | super(url, fileName, prop); 24 | } 25 | 26 | public DatabaseMetaData getMetaData() throws SQLException { 27 | checkOpen(); 28 | 29 | if (meta == null) { 30 | meta = new JDBC4DatabaseMetaData((SQLiteConnection)this); 31 | } 32 | 33 | return (DatabaseMetaData)meta; 34 | } 35 | 36 | public Statement createStatement(int rst, int rsc, int rsh) throws SQLException { 37 | checkOpen(); 38 | checkCursor(rst, rsc, rsh); 39 | 40 | return new JDBC4Statement((SQLiteConnection)this); 41 | } 42 | 43 | public PreparedStatement prepareStatement(String sql, int rst, int rsc, int rsh) throws SQLException { 44 | checkOpen(); 45 | checkCursor(rst, rsc, rsh); 46 | 47 | return new JDBC4PreparedStatement((SQLiteConnection)this, sql); 48 | } 49 | 50 | //JDBC 4 51 | /** 52 | * @see java.sql.Connection#isClosed() 53 | */ 54 | public boolean isClosed() throws SQLException { 55 | return db == null; 56 | } 57 | 58 | public T unwrap(Class iface) throws SQLException { 59 | // TODO Auto-generated method stub 60 | return null; 61 | } 62 | 63 | public boolean isWrapperFor(Class iface) throws SQLException { 64 | // TODO Auto-generated method stub 65 | return false; 66 | } 67 | 68 | public Clob createClob() throws SQLException { 69 | // TODO Auto-generated method stub 70 | return null; 71 | } 72 | 73 | public Blob createBlob() throws SQLException { 74 | // TODO Auto-generated method stub 75 | return null; 76 | } 77 | 78 | public NClob createNClob() throws SQLException { 79 | // TODO Auto-generated method stub 80 | return null; 81 | } 82 | 83 | public SQLXML createSQLXML() throws SQLException { 84 | // TODO Auto-generated method stub 85 | return null; 86 | } 87 | 88 | public boolean isValid(int timeout) throws SQLException { 89 | // TODO Auto-generated method stub 90 | return false; 91 | } 92 | 93 | public void setClientInfo(String name, String value) 94 | throws SQLClientInfoException { 95 | // TODO Auto-generated method stub 96 | 97 | } 98 | 99 | public void setClientInfo(Properties properties) 100 | throws SQLClientInfoException { 101 | // TODO Auto-generated method stub 102 | 103 | } 104 | 105 | public String getClientInfo(String name) throws SQLException { 106 | // TODO Auto-generated method stub 107 | return null; 108 | } 109 | 110 | public Properties getClientInfo() throws SQLException { 111 | // TODO Auto-generated method stub 112 | return null; 113 | } 114 | 115 | public Array createArrayOf(String typeName, Object[] elements) 116 | throws SQLException { 117 | // TODO Auto-generated method stub 118 | return null; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/org/sqlite/jdbc4/JDBC4DatabaseMetaData.java: -------------------------------------------------------------------------------- 1 | package org.sqlite.jdbc4; 2 | 3 | import java.sql.DatabaseMetaData; 4 | import java.sql.ResultSet; 5 | import java.sql.RowIdLifetime; 6 | import java.sql.SQLException; 7 | 8 | import org.sqlite.SQLiteConnection; 9 | import org.sqlite.jdbc3.JDBC3DatabaseMetaData; 10 | 11 | public class JDBC4DatabaseMetaData extends JDBC3DatabaseMetaData implements DatabaseMetaData 12 | { 13 | public JDBC4DatabaseMetaData(SQLiteConnection conn) { 14 | super(conn); 15 | } 16 | 17 | // JDBC 4 18 | public T unwrap(Class iface) throws SQLException { 19 | // TODO Auto-generated method stub 20 | return null; 21 | } 22 | 23 | public boolean isWrapperFor(Class iface) throws SQLException { 24 | // TODO Auto-generated method stub 25 | return false; 26 | } 27 | 28 | public RowIdLifetime getRowIdLifetime() throws SQLException { 29 | // TODO Auto-generated method stub 30 | return null; 31 | } 32 | 33 | public ResultSet getSchemas(String catalog, String schemaPattern) 34 | throws SQLException { 35 | // TODO Auto-generated method stub 36 | return null; 37 | } 38 | 39 | public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException { 40 | // TODO Auto-generated method stub 41 | return false; 42 | } 43 | 44 | public boolean autoCommitFailureClosesAllResultSets() throws SQLException { 45 | // TODO Auto-generated method stub 46 | return false; 47 | } 48 | 49 | public ResultSet getClientInfoProperties() throws SQLException { 50 | // TODO Auto-generated method stub 51 | return null; 52 | } 53 | 54 | public ResultSet getFunctions(String catalog, String schemaPattern, 55 | String functionNamePattern) throws SQLException { 56 | // TODO Auto-generated method stub 57 | return null; 58 | } 59 | 60 | @Override 61 | public ResultSet getPseudoColumns( String catalog, 62 | String schemaPattern, 63 | String tableNamePattern, 64 | String columnNamePattern ) throws SQLException 65 | { 66 | //TODO: Implement 67 | return null; 68 | } 69 | 70 | @Override 71 | public boolean generatedKeyAlwaysReturned() throws SQLException { 72 | //TODO: Implement 73 | return false; 74 | } 75 | 76 | @Override 77 | public long getMaxLogicalLobSize() throws SQLException { 78 | //TODO: Implement 79 | return 0; 80 | } 81 | 82 | @Override 83 | public boolean supportsRefCursors() throws SQLException { 84 | //TODO: Implement 85 | return false; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/org/sqlite/jdbc4/JDBC4PooledConnection.java: -------------------------------------------------------------------------------- 1 | package org.sqlite.jdbc4; 2 | 3 | import javax.sql.PooledConnection; 4 | import javax.sql.StatementEventListener; 5 | 6 | public abstract class JDBC4PooledConnection implements PooledConnection { 7 | 8 | public void addStatementEventListener(StatementEventListener listener) { 9 | // TODO impl 10 | } 11 | 12 | public void removeStatementEventListener(StatementEventListener listener) { 13 | // TODO impl 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/org/sqlite/jdbc4/JDBC4PreparedStatement.java: -------------------------------------------------------------------------------- 1 | package org.sqlite.jdbc4; 2 | 3 | import java.io.InputStream; 4 | import java.io.Reader; 5 | import java.sql.NClob; 6 | import java.sql.ParameterMetaData; 7 | import java.sql.PreparedStatement; 8 | import java.sql.RowId; 9 | import java.sql.SQLException; 10 | import java.sql.SQLXML; 11 | 12 | import org.sqlite.SQLiteConnection; 13 | import org.sqlite.jdbc3.JDBC3PreparedStatement; 14 | 15 | public class JDBC4PreparedStatement extends JDBC3PreparedStatement implements PreparedStatement, ParameterMetaData { 16 | 17 | public JDBC4PreparedStatement(SQLiteConnection conn, String sql) throws SQLException { 18 | super(conn, sql); 19 | } 20 | 21 | // JDBC 4 22 | public void setRowId(int parameterIndex, RowId x) throws SQLException { 23 | // TODO Auto-generated method stub 24 | 25 | } 26 | 27 | public void setNString(int parameterIndex, String value) 28 | throws SQLException { 29 | // TODO Auto-generated method stub 30 | 31 | } 32 | 33 | public void setNCharacterStream(int parameterIndex, Reader value, 34 | long length) throws SQLException { 35 | // TODO Auto-generated method stub 36 | 37 | } 38 | 39 | public void setNClob(int parameterIndex, NClob value) throws SQLException { 40 | // TODO Auto-generated method stub 41 | 42 | } 43 | 44 | public void setClob(int parameterIndex, Reader reader, long length) 45 | throws SQLException { 46 | // TODO Auto-generated method stub 47 | 48 | } 49 | 50 | public void setBlob(int parameterIndex, InputStream inputStream, long length) 51 | throws SQLException { 52 | // TODO Auto-generated method stub 53 | 54 | } 55 | 56 | public void setNClob(int parameterIndex, Reader reader, long length) 57 | throws SQLException { 58 | // TODO Auto-generated method stub 59 | 60 | } 61 | 62 | public void setSQLXML(int parameterIndex, SQLXML xmlObject) 63 | throws SQLException { 64 | // TODO Auto-generated method stub 65 | 66 | } 67 | 68 | public void setAsciiStream(int parameterIndex, InputStream x, long length) 69 | throws SQLException { 70 | // TODO Auto-generated method stub 71 | 72 | } 73 | 74 | public void setBinaryStream(int parameterIndex, InputStream x, long length) 75 | throws SQLException { 76 | // TODO Auto-generated method stub 77 | 78 | } 79 | 80 | public void setCharacterStream(int parameterIndex, Reader reader, 81 | long length) throws SQLException { 82 | // TODO Auto-generated method stub 83 | 84 | } 85 | 86 | public void setAsciiStream(int parameterIndex, InputStream x) 87 | throws SQLException { 88 | // TODO Auto-generated method stub 89 | 90 | } 91 | 92 | public void setBinaryStream(int parameterIndex, InputStream x) 93 | throws SQLException { 94 | // TODO Auto-generated method stub 95 | 96 | } 97 | 98 | public void setCharacterStream(int parameterIndex, Reader reader) 99 | throws SQLException { 100 | // TODO Auto-generated method stub 101 | 102 | } 103 | 104 | public void setNCharacterStream(int parameterIndex, Reader value) 105 | throws SQLException { 106 | // TODO Auto-generated method stub 107 | 108 | } 109 | 110 | public void setClob(int parameterIndex, Reader reader) throws SQLException { 111 | // TODO Auto-generated method stub 112 | 113 | } 114 | 115 | public void setBlob(int parameterIndex, InputStream inputStream) 116 | throws SQLException { 117 | // TODO Auto-generated method stub 118 | 119 | } 120 | 121 | public void setNClob(int parameterIndex, Reader reader) throws SQLException { 122 | // TODO Auto-generated method stub 123 | 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/main/java/org/sqlite/jdbc4/JDBC4Statement.java: -------------------------------------------------------------------------------- 1 | package org.sqlite.jdbc4; 2 | 3 | import java.sql.*; 4 | 5 | import org.sqlite.SQLiteConnection; 6 | import org.sqlite.jdbc3.JDBC3Statement; 7 | 8 | public class JDBC4Statement extends JDBC3Statement implements Statement { 9 | public JDBC4Statement(SQLiteConnection conn) { 10 | super(conn); 11 | } 12 | 13 | // JDBC 4 14 | public T unwrap(Class iface) throws SQLException { 15 | // TODO Auto-generated method stub 16 | return null; 17 | } 18 | 19 | public boolean isWrapperFor(Class iface) throws SQLException { 20 | // TODO Auto-generated method stub 21 | return false; 22 | } 23 | 24 | public boolean isClosed() throws SQLException { 25 | // TODO Auto-generated method stub 26 | return false; 27 | } 28 | 29 | public void setPoolable(boolean poolable) throws SQLException { 30 | // TODO Auto-generated method stub 31 | 32 | } 33 | 34 | public boolean isPoolable() throws SQLException { 35 | // TODO Auto-generated method stub 36 | return false; 37 | } 38 | 39 | @Override 40 | public void closeOnCompletion() throws SQLException { 41 | // TODO: Implement 42 | } 43 | 44 | @Override 45 | public boolean isCloseOnCompletion() throws SQLException { 46 | // TODO: Implement 47 | return false; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/org/sqlite/util/OSInfo.java: -------------------------------------------------------------------------------- 1 | /*-------------------------------------------------------------------------- 2 | * Copyright 2008 Taro L. Saito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *--------------------------------------------------------------------------*/ 16 | //-------------------------------------- 17 | // sqlite-jdbc Project 18 | // 19 | // OSInfo.java 20 | // Since: May 20, 2008 21 | // 22 | // $URL$ 23 | // $Author$ 24 | //-------------------------------------- 25 | package org.sqlite.util; 26 | 27 | /** 28 | * Provides OS name and architecture name. 29 | * 30 | * @author leo 31 | * 32 | */ 33 | public class OSInfo 34 | { 35 | public static void main(String[] args) { 36 | if (args.length >= 1) { 37 | if ("--os".equals(args[0])) { 38 | System.out.print(getOSName()); 39 | return; 40 | } 41 | else if ("--arch".equals(args[0])) { 42 | System.out.print(getArchName()); 43 | return; 44 | } 45 | } 46 | 47 | System.out.print(getNativeLibFolderPathForCurrentOS()); 48 | } 49 | 50 | /** 51 | * @return Native library fold path for the current operation system in the format 52 | * of OS_name/OS_architecture_name 53 | */ 54 | public static String getNativeLibFolderPathForCurrentOS() { 55 | return getOSName() + "/" + getArchName(); 56 | } 57 | 58 | /** 59 | * @return Operating system name: "Windows", "Mac", or "Linux". 60 | */ 61 | public static String getOSName() { 62 | return translateOSNameToFolderName(System.getProperty("os.name")); 63 | } 64 | 65 | /** 66 | * @return Operation system architecture name. 67 | */ 68 | public static String getArchName() { 69 | return translateArchNameToFolderName(System.getProperty("os.arch")); 70 | } 71 | 72 | /** 73 | * Extracts operating system name from given string. 74 | * @param osName The given string that contains operating system name. 75 | * @return Operating system name: "Windows", "Mac", or "Linux". 76 | */ 77 | public static String translateOSNameToFolderName(String osName) { 78 | if (osName.contains("Windows")) { 79 | return "Windows"; 80 | } 81 | else if (osName.contains("Mac")) { 82 | return "Mac"; 83 | } 84 | else if (osName.contains("Linux")) { 85 | return "Linux"; 86 | } 87 | else { 88 | return osName.replaceAll("\\W", ""); 89 | } 90 | } 91 | 92 | /** 93 | * @param archName 94 | * @return Operation system architecture name. 95 | */ 96 | public static String translateArchNameToFolderName(String archName) { 97 | return archName.replaceAll("\\W", ""); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/org/sqlite/util/ResourceFinder.java: -------------------------------------------------------------------------------- 1 | /*-------------------------------------------------------------------------- 2 | * Copyright 2009 Taro L. Saito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *--------------------------------------------------------------------------*/ 16 | //-------------------------------------- 17 | // sqlite-jdbc Project 18 | // 19 | // ResourceFinder.java 20 | // Since: Apr 28, 2009 21 | // 22 | // $URL$ 23 | // $Author$ 24 | //-------------------------------------- 25 | package org.sqlite.util; 26 | 27 | import java.net.URL; 28 | 29 | /** 30 | * Resource address finder for files inside the jar file 31 | * 32 | * @author leo 33 | * 34 | */ 35 | public class ResourceFinder 36 | { 37 | /** 38 | * Gets the {@link URL} of the file resource 39 | * 40 | * @param referenceClass 41 | * the base class for finding resources files. This method will 42 | * search the package containing the given referenceClass. 43 | * @param resourceFileName 44 | * the resource file name relative to the package of the 45 | * referenceClass 46 | * @return the URL of the file resource 47 | */ 48 | public static URL find(Class< ? > referenceClass, String resourceFileName) 49 | { 50 | return find(referenceClass.getClassLoader(), referenceClass.getPackage(), resourceFileName); 51 | } 52 | 53 | /** 54 | * Finds the {@link URL} of the resource 55 | * 56 | * @param basePackage 57 | * the base package to find the resource 58 | * @param resourceFileName 59 | * the resource file name relative to the package folder 60 | * @return the URL of the specified resource 61 | */ 62 | public static URL find(ClassLoader classLoader, Package basePackage, String resourceFileName) 63 | { 64 | return find(classLoader, basePackage.getName(), resourceFileName); 65 | } 66 | 67 | /** 68 | * Finds the {@link URL} of the resource 69 | * 70 | * @param packageName 71 | * the base package name to find the resource 72 | * @param resourceFileName 73 | * the resource file name relative to the package folder 74 | * @return the URL of the specified resource 75 | */ 76 | public static URL find(ClassLoader classLoader, String packageName, String resourceFileName) 77 | { 78 | String packagePath = packagePath(packageName); 79 | String resourcePath = packagePath + resourceFileName; 80 | if (!resourcePath.startsWith("/")) 81 | resourcePath = "/" + resourcePath; 82 | 83 | return classLoader.getResource(resourcePath); 84 | } 85 | 86 | @SuppressWarnings("unused") 87 | private static String packagePath(Class< ? > referenceClass) 88 | { 89 | return packagePath(referenceClass.getPackage()); 90 | } 91 | 92 | /** 93 | * @param basePackage Package object 94 | * @return Package path String in the unix-like format. 95 | */ 96 | private static String packagePath(Package basePackage) 97 | { 98 | return packagePath(basePackage.getName()); 99 | } 100 | 101 | /** 102 | * @param packageName Package name string 103 | * @return Package path String in the unix-like format. 104 | */ 105 | private static String packagePath(String packageName) 106 | { 107 | String packageAsPath = packageName.replaceAll("\\.", "/"); 108 | return packageAsPath.endsWith("/") ? packageAsPath : packageAsPath + "/"; 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /src/main/resources/java.sql.Driver: -------------------------------------------------------------------------------- 1 | org.sqlite.JDBC -------------------------------------------------------------------------------- /src/main/resources/org/sqlite/SQLite.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decamp/sqlcipher-jdbc/3ce4defeafa9d468b0b0a91b62d7ac98a5456ed8/src/main/resources/org/sqlite/SQLite.class -------------------------------------------------------------------------------- /src/main/resources/org/sqlite/native/Mac/x86_64/libsqlitejdbc.jnilib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decamp/sqlcipher-jdbc/3ce4defeafa9d468b0b0a91b62d7ac98a5456ed8/src/main/resources/org/sqlite/native/Mac/x86_64/libsqlitejdbc.jnilib -------------------------------------------------------------------------------- /src/main/target/sample.db1121577371722804844: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decamp/sqlcipher-jdbc/3ce4defeafa9d468b0b0a91b62d7ac98a5456ed8/src/main/target/sample.db1121577371722804844 -------------------------------------------------------------------------------- /src/main/target/sample.db3781345977843727311: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decamp/sqlcipher-jdbc/3ce4defeafa9d468b0b0a91b62d7ac98a5456ed8/src/main/target/sample.db3781345977843727311 -------------------------------------------------------------------------------- /src/main/target/sample.db5118308387616140847: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decamp/sqlcipher-jdbc/3ce4defeafa9d468b0b0a91b62d7ac98a5456ed8/src/main/target/sample.db5118308387616140847 -------------------------------------------------------------------------------- /src/main/target/sample.db5146130081809857960: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decamp/sqlcipher-jdbc/3ce4defeafa9d468b0b0a91b62d7ac98a5456ed8/src/main/target/sample.db5146130081809857960 -------------------------------------------------------------------------------- /src/main/target/testdb.jar7561007154787325801: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decamp/sqlcipher-jdbc/3ce4defeafa9d468b0b0a91b62d7ac98a5456ed8/src/main/target/testdb.jar7561007154787325801 -------------------------------------------------------------------------------- /src/main/target/testdb.jar7707595110025748705: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decamp/sqlcipher-jdbc/3ce4defeafa9d468b0b0a91b62d7ac98a5456ed8/src/main/target/testdb.jar7707595110025748705 -------------------------------------------------------------------------------- /src/test/java/org/sqlite/AllTests.java: -------------------------------------------------------------------------------- 1 | package org.sqlite; 2 | 3 | import org.junit.runners.Suite; 4 | import org.junit.runner.RunWith; 5 | 6 | @RunWith(Suite.class) 7 | @Suite.SuiteClasses({ 8 | BackupTest.class, 9 | ConnectionTest.class, 10 | DBMetaDataTest.class, 11 | ExtendedCommandTest.class, 12 | ExtensionTest.class, 13 | FetchSizeTest.class, 14 | InsertQueryTest.class, 15 | JDBCTest.class, 16 | OSInfoTest.class, 17 | PrepStmtTest.class, 18 | QueryTest.class, 19 | ReadUncommittedTest.class, 20 | RSMetaDataTest.class, 21 | SQLiteDataSourceTest.class, 22 | SQLiteConnectionPoolDataSourceTest.class, 23 | SQLiteJDBCLoaderTest.class, 24 | StatementTest.class, 25 | TransactionTest.class, 26 | UDFTest.class 27 | }) 28 | public class AllTests { 29 | // runs all Tests 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/org/sqlite/BackupTest.java: -------------------------------------------------------------------------------- 1 | //-------------------------------------- 2 | // sqlite-jdbc Project 3 | // 4 | // BackupTest.java 5 | // Since: Feb 18, 2009 6 | // 7 | // $URL$ 8 | // $Author$ 9 | //-------------------------------------- 10 | package org.sqlite; 11 | 12 | import static org.junit.Assert.*; 13 | 14 | import java.io.File; 15 | import java.io.IOException; 16 | import java.sql.Connection; 17 | import java.sql.DriverManager; 18 | import java.sql.ResultSet; 19 | import java.sql.SQLException; 20 | import java.sql.Statement; 21 | 22 | import org.junit.BeforeClass; 23 | import org.junit.Test; 24 | 25 | public class BackupTest 26 | { 27 | 28 | @BeforeClass 29 | public static void forName() throws Exception { 30 | Class.forName("org.sqlite.JDBC"); 31 | } 32 | 33 | @Test 34 | public void backupAndRestore() throws SQLException, IOException { 35 | // create a memory database 36 | File tmpFile = File.createTempFile("backup-test", ".sqlite"); 37 | tmpFile.deleteOnExit(); 38 | 39 | // memory DB to file 40 | Connection conn = DriverManager.getConnection("jdbc:sqlite:"); 41 | Statement stmt = conn.createStatement(); 42 | stmt.executeUpdate("create table sample(id, name)"); 43 | stmt.executeUpdate("insert into sample values(1, \"leo\")"); 44 | stmt.executeUpdate("insert into sample values(2, \"yui\")"); 45 | 46 | stmt.executeUpdate("backup to " + tmpFile.getAbsolutePath()); 47 | stmt.close(); 48 | 49 | // open another memory database 50 | Connection conn2 = DriverManager.getConnection("jdbc:sqlite:"); 51 | Statement stmt2 = conn2.createStatement(); 52 | stmt2.execute("restore from " + tmpFile.getAbsolutePath()); 53 | ResultSet rs = stmt2.executeQuery("select * from sample"); 54 | int count = 0; 55 | while (rs.next()) { 56 | count++; 57 | } 58 | 59 | assertEquals(2, count); 60 | rs.close(); 61 | 62 | } 63 | 64 | @Test 65 | public void memoryToDisk() throws Exception { 66 | 67 | if (!SQLiteJDBCLoader.isNativeMode()) 68 | return; // skip this test in pure-java mode 69 | 70 | Connection conn = DriverManager.getConnection("jdbc:sqlite:"); 71 | Statement stmt = conn.createStatement(); 72 | stmt.executeUpdate("create table sample(id integer primary key autoincrement, name)"); 73 | for (int i = 0; i < 10000; i++) 74 | stmt.executeUpdate("insert into sample(name) values(\"leo\")"); 75 | 76 | File tmpFile = File.createTempFile("backup-test2", ".sqlite"); 77 | tmpFile.deleteOnExit(); 78 | //System.err.println("backup start"); 79 | stmt.executeUpdate("backup to " + tmpFile.getAbsolutePath()); 80 | stmt.close(); 81 | //System.err.println("backup done."); 82 | 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/test/java/org/sqlite/ConnectionTest.java: -------------------------------------------------------------------------------- 1 | package org.sqlite; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import java.io.File; 6 | import java.io.FileOutputStream; 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | import java.sql.Connection; 10 | import java.sql.DriverManager; 11 | import java.sql.PreparedStatement; 12 | import java.sql.ResultSet; 13 | import java.sql.ResultSetMetaData; 14 | import java.sql.SQLException; 15 | import java.sql.Statement; 16 | 17 | import org.junit.BeforeClass; 18 | import org.junit.Test; 19 | import org.sqlite.SQLiteConfig.SynchronousMode; 20 | 21 | /** 22 | * These tests check whether access to files is woring correctly and some 23 | * Connection.close() cases. 24 | */ 25 | public class ConnectionTest 26 | { 27 | @BeforeClass 28 | public static void forName() throws Exception { 29 | Class.forName("org.sqlite.JDBC"); 30 | } 31 | 32 | @Test 33 | public void executeUpdateOnClosedDB() throws SQLException { 34 | Connection conn = DriverManager.getConnection("jdbc:sqlite:"); 35 | Statement stat = conn.createStatement(); 36 | conn.close(); 37 | 38 | try { 39 | stat.executeUpdate("create table A(id, name)"); 40 | } 41 | catch (SQLException e) { 42 | return; // successfully detect the operation on the closed DB 43 | } 44 | fail("should not reach here"); 45 | } 46 | 47 | @Test 48 | public void readOnly() throws SQLException { 49 | 50 | // set read only mode 51 | SQLiteConfig config = new SQLiteConfig(); 52 | config.setReadOnly(true); 53 | 54 | Connection conn = DriverManager.getConnection("jdbc:sqlite:", config.toProperties()); 55 | Statement stat = conn.createStatement(); 56 | try { 57 | assertTrue(conn.isReadOnly()); 58 | // these updates must be forbidden in read-only mode 59 | stat.executeUpdate("create table A(id, name)"); 60 | stat.executeUpdate("insert into A values(1, 'leo')"); 61 | 62 | fail("read only flag is not properly set"); 63 | } 64 | catch (SQLException e) { 65 | // success 66 | } 67 | finally { 68 | stat.close(); 69 | conn.close(); 70 | } 71 | 72 | config.setReadOnly(true); // should be a no-op 73 | 74 | try{ 75 | conn.setReadOnly(false); 76 | fail("should not change read only flag after opening connection"); 77 | } 78 | catch (SQLException e) { 79 | assert(e.getMessage().contains("Cannot change read-only flag after establishing a connection.")); 80 | } 81 | finally { 82 | conn.close(); 83 | } 84 | } 85 | 86 | @Test 87 | public void foreignKeys() throws SQLException { 88 | SQLiteConfig config = new SQLiteConfig(); 89 | config.enforceForeignKeys(true); 90 | Connection conn = DriverManager.getConnection("jdbc:sqlite:", config.toProperties()); 91 | Statement stat = conn.createStatement(); 92 | 93 | try { 94 | stat.executeUpdate("create table track(id integer primary key, name, aid, foreign key (aid) references artist(id))"); 95 | stat.executeUpdate("create table artist(id integer primary key, name)"); 96 | 97 | stat.executeUpdate("insert into artist values(10, 'leo')"); 98 | stat.executeUpdate("insert into track values(1, 'first track', 10)"); // OK 99 | 100 | try { 101 | stat.executeUpdate("insert into track values(2, 'second track', 3)"); // invalid reference 102 | } 103 | catch (SQLException e) { 104 | return; // successfully detect violation of foreign key constraints 105 | } 106 | fail("foreign key constraint must be enforced"); 107 | } 108 | finally { 109 | stat.close(); 110 | conn.close(); 111 | } 112 | 113 | } 114 | 115 | @Test 116 | public void canWrite() throws SQLException { 117 | SQLiteConfig config = new SQLiteConfig(); 118 | config.enforceForeignKeys(true); 119 | Connection conn = DriverManager.getConnection("jdbc:sqlite:", config.toProperties()); 120 | Statement stat = conn.createStatement(); 121 | 122 | try { 123 | assertFalse(conn.isReadOnly()); 124 | } 125 | finally { 126 | stat.close(); 127 | conn.close(); 128 | } 129 | 130 | } 131 | 132 | @Test 133 | public void synchronous() throws SQLException { 134 | SQLiteConfig config = new SQLiteConfig(); 135 | config.setSynchronous(SynchronousMode.OFF); 136 | Connection conn = DriverManager.getConnection("jdbc:sqlite:", config.toProperties()); 137 | Statement stat = conn.createStatement(); 138 | 139 | try { 140 | ResultSet rs = stat.executeQuery("pragma synchronous"); 141 | if (rs.next()) { 142 | ResultSetMetaData rm = rs.getMetaData(); 143 | int i = rm.getColumnCount(); 144 | int synchronous = rs.getInt(1); 145 | assertEquals(0, synchronous); 146 | } 147 | 148 | } 149 | finally { 150 | stat.close(); 151 | conn.close(); 152 | } 153 | 154 | } 155 | 156 | @Test 157 | public void openMemory() throws SQLException { 158 | Connection conn = DriverManager.getConnection("jdbc:sqlite:"); 159 | conn.close(); 160 | } 161 | 162 | @Test 163 | public void isClosed() throws SQLException { 164 | Connection conn = DriverManager.getConnection("jdbc:sqlite:"); 165 | conn.close(); 166 | assertTrue(conn.isClosed()); 167 | } 168 | 169 | @Test(expected = SQLException.class) 170 | public void closeTest() throws SQLException { 171 | Connection conn = DriverManager.getConnection("jdbc:sqlite:"); 172 | PreparedStatement prep = conn.prepareStatement("select null;"); 173 | ResultSet rs = prep.executeQuery(); 174 | conn.close(); 175 | prep.clearParameters(); 176 | } 177 | 178 | @Test(expected = SQLException.class) 179 | public void openInvalidLocation() throws SQLException { 180 | Connection conn = DriverManager.getConnection("jdbc:sqlite:/"); 181 | conn.close(); 182 | } 183 | 184 | @Test 185 | public void openResource() throws Exception { 186 | File testDB = copyToTemp("sample.db"); 187 | assertTrue(testDB.exists()); 188 | Connection conn = DriverManager 189 | .getConnection(String.format("jdbc:sqlite::resource:%s", testDB.toURI().toURL())); 190 | Statement stat = conn.createStatement(); 191 | ResultSet rs = stat.executeQuery("select * from coordinate"); 192 | assertTrue(rs.next()); 193 | rs.close(); 194 | stat.close(); 195 | conn.close(); 196 | 197 | } 198 | 199 | @Test 200 | public void openJARResource() throws Exception { 201 | File testJAR = copyToTemp("testdb.jar"); 202 | assertTrue(testJAR.exists()); 203 | 204 | Connection conn = DriverManager.getConnection(String.format("jdbc:sqlite::resource:jar:%s!/sample.db", testJAR 205 | .toURI().toURL())); 206 | Statement stat = conn.createStatement(); 207 | ResultSet rs = stat.executeQuery("select * from coordinate"); 208 | assertTrue(rs.next()); 209 | rs.close(); 210 | stat.close(); 211 | conn.close(); 212 | } 213 | 214 | @Test 215 | public void openFile() throws Exception { 216 | 217 | File testDB = copyToTemp("sample.db"); 218 | 219 | assertTrue(testDB.exists()); 220 | Connection conn = DriverManager.getConnection(String.format("jdbc:sqlite:%s", testDB)); 221 | conn.close(); 222 | } 223 | 224 | public static File copyToTemp(String fileName) throws IOException { 225 | InputStream in = ConnectionTest.class.getResourceAsStream(fileName); 226 | File dir = new File("target"); 227 | if (!dir.exists()) 228 | dir.mkdirs(); 229 | 230 | File tmp = File.createTempFile(fileName, "", new File("target")); 231 | tmp.deleteOnExit(); 232 | FileOutputStream out = new FileOutputStream(tmp); 233 | 234 | byte[] buf = new byte[8192]; 235 | for (int readBytes = 0; (readBytes = in.read(buf)) != -1;) { 236 | out.write(buf, 0, readBytes); 237 | } 238 | out.flush(); 239 | out.close(); 240 | in.close(); 241 | 242 | return tmp; 243 | } 244 | 245 | @Test 246 | public void URIFilenames() throws SQLException { 247 | Connection conn1 = DriverManager.getConnection("jdbc:sqlite:file:memdb1?mode=memory&cache=shared"); 248 | Statement stmt1 = conn1.createStatement(); 249 | stmt1.executeUpdate("create table tbl (col int)"); 250 | stmt1.executeUpdate("insert into tbl values(100)"); 251 | stmt1.close(); 252 | 253 | Connection conn2 = DriverManager.getConnection("jdbc:sqlite:file:memdb1?mode=memory&cache=shared"); 254 | Statement stmt2 = conn2.createStatement(); 255 | ResultSet rs = stmt2.executeQuery("select * from tbl"); 256 | assertTrue(rs.next()); 257 | assertEquals(100, rs.getInt(1)); 258 | stmt2.close(); 259 | 260 | Connection conn3 = DriverManager.getConnection("jdbc:sqlite:file::memory:?cache=shared"); 261 | Statement stmt3 = conn3.createStatement(); 262 | stmt3.executeUpdate("attach 'file:memdb1?mode=memory&cache=shared' as memdb1"); 263 | rs = stmt3.executeQuery("select * from memdb1.tbl"); 264 | assertTrue(rs.next()); 265 | assertEquals(100, rs.getInt(1)); 266 | stmt3.executeUpdate("create table tbl2(col int)"); 267 | stmt3.executeUpdate("insert into tbl2 values(200)"); 268 | stmt3.close(); 269 | 270 | Connection conn4 = DriverManager.getConnection("jdbc:sqlite:file::memory:?cache=shared"); 271 | Statement stmt4 = conn4.createStatement(); 272 | rs = stmt4.executeQuery("select * from tbl2"); 273 | assertTrue(rs.next()); 274 | assertEquals(200, rs.getInt(1)); 275 | rs.close(); 276 | stmt4.close(); 277 | conn4.close(); 278 | } 279 | } 280 | -------------------------------------------------------------------------------- /src/test/java/org/sqlite/EncryptedTest.java: -------------------------------------------------------------------------------- 1 | package org.sqlite; 2 | 3 | import org.junit.BeforeClass; 4 | import org.junit.Test; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.sql.*; 9 | import java.util.Properties; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | 14 | /** 15 | * @author Philip DeCamp 16 | */ 17 | public class EncryptedTest { 18 | 19 | @BeforeClass 20 | public static void forName() throws Exception { 21 | Class.forName("org.sqlite.JDBC"); 22 | } 23 | 24 | @Test 25 | public void createEncrypted() throws SQLException, IOException { 26 | File tmp = File.createTempFile( "sqlitetest", ".db" ); 27 | tmp.deleteOnExit(); 28 | String url = "jdbc:sqlite:" + tmp.getAbsolutePath(); 29 | 30 | Properties props = new Properties(); 31 | final String password = "salty'\"dog"; 32 | props.put( "key", password ); 33 | Connection conn = DriverManager.getConnection( url, props ); 34 | conn.setAutoCommit( false ); 35 | 36 | Statement st = conn.createStatement(); 37 | st.executeUpdate( "create table ants (col int)" ); 38 | st.executeUpdate( "insert into ants values( 300 )" ); 39 | st.executeUpdate( "insert into ants values( 400 )" ); 40 | st.close(); 41 | conn.commit(); 42 | conn.close(); 43 | 44 | // Try reading without key. 45 | props.remove( "key" ); 46 | conn = DriverManager.getConnection( url, props ); 47 | 48 | try { 49 | st = conn.createStatement(); 50 | ResultSet rs = st.executeQuery( "select count(*) from ants" ); 51 | fail( "Database not encrypted." ); 52 | } catch( SQLException ignore ) {} 53 | 54 | conn.close(); 55 | props.put( "key", password ); 56 | conn = DriverManager.getConnection( url, props ); 57 | 58 | st = conn.createStatement(); 59 | ResultSet rs = st.executeQuery( "select count(*) from ants" ); 60 | assertTrue( rs.next() ); 61 | assertEquals( 2, rs.getInt( 1 ) ); 62 | conn.close(); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/test/java/org/sqlite/ExtendedCommandTest.java: -------------------------------------------------------------------------------- 1 | //-------------------------------------- 2 | // sqlite-jdbc Project 3 | // 4 | // ExtendedCommandTest.java 5 | // Since: Mar 12, 2010 6 | // 7 | // $URL$ 8 | // $Author$ 9 | //-------------------------------------- 10 | package org.sqlite; 11 | 12 | import static org.junit.Assert.*; 13 | 14 | import java.sql.SQLException; 15 | 16 | import org.junit.After; 17 | import org.junit.Before; 18 | import org.junit.Test; 19 | import org.sqlite.ExtendedCommand.BackupCommand; 20 | import org.sqlite.ExtendedCommand.RestoreCommand; 21 | import org.sqlite.ExtendedCommand.SQLExtension; 22 | 23 | public class ExtendedCommandTest 24 | { 25 | 26 | @Before 27 | public void setUp() throws Exception {} 28 | 29 | @After 30 | public void tearDown() throws Exception {} 31 | 32 | public static BackupCommand parseBackupCommand(String sql) throws SQLException { 33 | SQLExtension e = ExtendedCommand.parse(sql); 34 | assertTrue(BackupCommand.class.isInstance(e)); 35 | return BackupCommand.class.cast(e); 36 | } 37 | 38 | public static RestoreCommand parseRestoreCommand(String sql) throws SQLException { 39 | SQLExtension e = ExtendedCommand.parse(sql); 40 | assertTrue(RestoreCommand.class.isInstance(e)); 41 | return RestoreCommand.class.cast(e); 42 | } 43 | 44 | @Test 45 | public void parseBackupCmd() throws SQLException { 46 | BackupCommand b = parseBackupCommand("backup mydb to somewhere/backupfolder/mydb.sqlite"); 47 | assertEquals("mydb", b.srcDB); 48 | assertEquals("somewhere/backupfolder/mydb.sqlite", b.destFile); 49 | 50 | b = parseBackupCommand("backup main to \"tmp folder with space\""); 51 | assertEquals("main", b.srcDB); 52 | assertEquals("tmp folder with space", b.destFile); 53 | 54 | b = parseBackupCommand("backup main to 'tmp folder with space'"); 55 | assertEquals("main", b.srcDB); 56 | assertEquals("tmp folder with space", b.destFile); 57 | 58 | b = parseBackupCommand("backup to target/sample.db"); 59 | assertEquals("main", b.srcDB); 60 | assertEquals("target/sample.db", b.destFile); 61 | } 62 | 63 | @Test 64 | public void parseRestoreCmd() throws SQLException { 65 | RestoreCommand b = parseRestoreCommand("restore mydb from somewhere/backupfolder/mydb.sqlite"); 66 | assertEquals("mydb", b.targetDB); 67 | assertEquals("somewhere/backupfolder/mydb.sqlite", b.srcFile); 68 | 69 | b = parseRestoreCommand("restore main from \"tmp folder with space\""); 70 | assertEquals("main", b.targetDB); 71 | assertEquals("tmp folder with space", b.srcFile); 72 | 73 | b = parseRestoreCommand("restore main from 'tmp folder with space'"); 74 | assertEquals("main", b.targetDB); 75 | assertEquals("tmp folder with space", b.srcFile); 76 | 77 | b = parseRestoreCommand("restore from target/sample.db"); 78 | assertEquals("main", b.targetDB); 79 | assertEquals("target/sample.db", b.srcFile); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/test/java/org/sqlite/ExtensionTest.java: -------------------------------------------------------------------------------- 1 | package org.sqlite; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import java.sql.Connection; 6 | import java.sql.DriverManager; 7 | import java.sql.ResultSet; 8 | import java.sql.Statement; 9 | 10 | import org.junit.*; 11 | 12 | 13 | public class ExtensionTest 14 | { 15 | 16 | @BeforeClass 17 | public static void forName() throws Exception { 18 | Class.forName("org.sqlite.JDBC"); 19 | } 20 | 21 | Connection conn; 22 | Statement stat; 23 | 24 | @Before 25 | public void setUp() throws Exception { 26 | conn = DriverManager.getConnection("jdbc:sqlite:"); 27 | stat = conn.createStatement(); 28 | } 29 | 30 | @After 31 | public void tearDown() throws Exception { 32 | if (stat != null) 33 | stat.close(); 34 | if (conn != null) 35 | conn.close(); 36 | 37 | } 38 | 39 | @Test 40 | public void extFTS3() throws Exception { 41 | stat.execute("create virtual table recipe using fts3(name, ingredients)"); 42 | stat.execute("insert into recipe (name, ingredients) values('broccoli stew', 'broccoli peppers cheese tomatoes')"); 43 | stat.execute("insert into recipe (name, ingredients) values('pumpkin stew', 'pumpkin onions garlic celery')"); 44 | 45 | ResultSet rs = stat.executeQuery("select rowid, name, ingredients from recipe where ingredients match 'onions'"); 46 | assertTrue(rs.next()); 47 | assertEquals("pumpkin stew", rs.getString(2)); 48 | 49 | } 50 | 51 | @Test 52 | @Ignore // Currently not compiling with extensions functions. 53 | public void extFunctions() throws Exception { 54 | { 55 | ResultSet rs = stat.executeQuery("select cos(radians(45))"); 56 | assertTrue(rs.next()); 57 | assertEquals(0.707106781186548, rs.getDouble(1), 0.000000000000001); 58 | rs.close(); 59 | } 60 | 61 | { 62 | ResultSet rs = stat.executeQuery("select reverse(\"ACGT\")"); 63 | assertTrue(rs.next()); 64 | assertEquals("TGCA", rs.getString(1)); 65 | rs.close(); 66 | } 67 | 68 | } 69 | 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/test/java/org/sqlite/FetchSizeTest.java: -------------------------------------------------------------------------------- 1 | package org.sqlite; 2 | 3 | import static junit.framework.Assert.*; 4 | 5 | import java.sql.Connection; 6 | import java.sql.DriverManager; 7 | import java.sql.PreparedStatement; 8 | import java.sql.ResultSet; 9 | import java.sql.SQLException; 10 | 11 | import org.junit.After; 12 | import org.junit.Before; 13 | import org.junit.BeforeClass; 14 | import org.junit.Test; 15 | 16 | /** 17 | * Created by IntelliJ IDEA. User: david_donn Date: 19/01/2010 Time: 11:50:24 AM 18 | * To change this template use File | Settings | File Templates. 19 | */ 20 | public class FetchSizeTest 21 | { 22 | 23 | private Connection conn; 24 | 25 | @BeforeClass 26 | public static void forName() throws Exception { 27 | Class.forName("org.sqlite.JDBC"); 28 | } 29 | 30 | @Before 31 | public void connect() throws Exception { 32 | conn = DriverManager.getConnection("jdbc:sqlite:"); 33 | } 34 | 35 | @After 36 | public void close() throws SQLException { 37 | conn.close(); 38 | } 39 | 40 | @Test 41 | public void testFetchSize() throws SQLException { 42 | assertEquals(conn.prepareStatement("create table s1 (c1)").executeUpdate(), 0); 43 | PreparedStatement insertPrep = conn.prepareStatement("insert into s1 values (?)"); 44 | insertPrep.setInt(1, 1); 45 | assertEquals(insertPrep.executeUpdate(), 1); 46 | insertPrep.setInt(1, 2); 47 | assertEquals(insertPrep.executeUpdate(), 1); 48 | insertPrep.setInt(1, 3); 49 | assertEquals(insertPrep.executeUpdate(), 1); 50 | insertPrep.setInt(1, 4); 51 | assertEquals(insertPrep.executeUpdate(), 1); 52 | insertPrep.setInt(1, 5); 53 | assertEquals(insertPrep.executeUpdate(), 1); 54 | insertPrep.close(); 55 | 56 | PreparedStatement selectPrep = conn.prepareStatement("select c1 from s1"); 57 | ResultSet rs = selectPrep.executeQuery(); 58 | rs.setFetchSize(2); 59 | assertTrue(rs.next()); 60 | assertTrue(rs.next()); 61 | assertTrue(rs.next()); 62 | assertTrue(rs.next()); 63 | assertTrue(rs.next()); 64 | assertFalse(rs.next()); 65 | } 66 | 67 | } -------------------------------------------------------------------------------- /src/test/java/org/sqlite/InsertQueryTest.java: -------------------------------------------------------------------------------- 1 | //-------------------------------------- 2 | // sqlite-jdbc Project 3 | // 4 | // InsertQueryTest.java 5 | // Since: Apr 7, 2009 6 | // 7 | // $URL$ 8 | // $Author$ 9 | //-------------------------------------- 10 | package org.sqlite; 11 | 12 | import java.io.File; 13 | import java.sql.Connection; 14 | import java.sql.DriverManager; 15 | import java.sql.PreparedStatement; 16 | import java.sql.ResultSet; 17 | import java.sql.SQLException; 18 | import java.sql.Statement; 19 | 20 | import org.junit.After; 21 | import org.junit.Before; 22 | import org.junit.BeforeClass; 23 | import org.junit.Test; 24 | 25 | public class InsertQueryTest 26 | { 27 | @BeforeClass 28 | public static void forName() throws Exception 29 | { 30 | Class.forName("org.sqlite.JDBC"); 31 | } 32 | 33 | String dbName; 34 | 35 | @Before 36 | public void setUp() throws Exception 37 | { 38 | File tmpFile = File.createTempFile("tmp-sqlite", ".db"); 39 | tmpFile.deleteOnExit(); 40 | dbName = tmpFile.getAbsolutePath(); 41 | } 42 | 43 | @After 44 | public void tearDown() throws Exception 45 | { 46 | 47 | } 48 | 49 | interface ConnectionFactory 50 | { 51 | Connection getConnection() throws SQLException; 52 | 53 | void dispose() throws SQLException; 54 | } 55 | 56 | class IndependentConnectionFactory implements ConnectionFactory 57 | { 58 | public Connection getConnection() throws SQLException 59 | { 60 | return DriverManager.getConnection("jdbc:sqlite:" + dbName); 61 | } 62 | 63 | public void dispose() throws SQLException 64 | { 65 | 66 | } 67 | 68 | } 69 | 70 | class SharedConnectionFactory implements ConnectionFactory 71 | { 72 | private Connection conn = null; 73 | 74 | public Connection getConnection() throws SQLException 75 | { 76 | if (conn == null) 77 | conn = DriverManager.getConnection("jdbc:sqlite:" + dbName); 78 | return conn; 79 | } 80 | 81 | public void dispose() throws SQLException 82 | { 83 | if (conn != null) 84 | conn.close(); 85 | } 86 | } 87 | 88 | static class BD 89 | { 90 | String fullId; 91 | String type; 92 | 93 | public BD(String fullId, String type) 94 | { 95 | this.fullId = fullId; 96 | this.type = type; 97 | } 98 | 99 | public String getFullId() 100 | { 101 | return fullId; 102 | } 103 | 104 | public void setFullId(String fullId) 105 | { 106 | this.fullId = fullId; 107 | } 108 | 109 | public String getType() 110 | { 111 | return type; 112 | } 113 | 114 | public void setType(String type) 115 | { 116 | this.type = type; 117 | } 118 | 119 | public static byte[] serializeBD(BD item) 120 | { 121 | return new byte[0]; 122 | } 123 | 124 | } 125 | 126 | @Test 127 | public void insertLockTestUsingSharedConnection() throws Exception 128 | { 129 | insertAndQuery(new SharedConnectionFactory()); 130 | } 131 | 132 | @Test 133 | public void insertLockTestUsingIndependentConnection() throws Exception 134 | { 135 | insertAndQuery(new IndependentConnectionFactory()); 136 | } 137 | 138 | void insertAndQuery(ConnectionFactory factory) throws SQLException 139 | { 140 | try 141 | { 142 | Statement st = factory.getConnection().createStatement(); 143 | st 144 | .executeUpdate("CREATE TABLE IF NOT EXISTS data (fid VARCHAR(255) PRIMARY KEY, type VARCHAR(64), data BLOB);"); 145 | st 146 | .executeUpdate("CREATE TABLE IF NOT EXISTS ResourcesTags (bd_fid VARCHAR(255), name VARCHAR(64), version INTEGER);"); 147 | st.close(); 148 | 149 | factory.getConnection().setAutoCommit(false); 150 | 151 | // Object Serialization 152 | PreparedStatement statAddBD = factory.getConnection().prepareStatement( 153 | "INSERT OR REPLACE INTO data values (?, ?, ?)"); 154 | PreparedStatement statDelRT = factory.getConnection().prepareStatement( 155 | "DELETE FROM ResourcesTags WHERE bd_fid = ?"); 156 | PreparedStatement statAddRT = factory.getConnection().prepareStatement( 157 | "INSERT INTO ResourcesTags values (?, ?, ?)"); 158 | 159 | for (int i = 0; i < 10; i++) 160 | { 161 | BD item = new BD(Integer.toHexString(i), Integer.toString(i)); 162 | 163 | // SQLite database insertion 164 | statAddBD.setString(1, item.getFullId()); 165 | statAddBD.setString(2, item.getType()); 166 | statAddBD.setBytes(3, BD.serializeBD(item)); 167 | statAddBD.execute(); 168 | 169 | // Then, its resources tags 170 | statDelRT.setString(1, item.getFullId()); 171 | statDelRT.execute(); 172 | 173 | statAddRT.setString(1, item.getFullId()); 174 | 175 | for (int j = 0; j < 2; j++) 176 | { 177 | statAddRT.setString(2, "1"); 178 | statAddRT.setLong(3, 1L); 179 | statAddRT.execute(); 180 | } 181 | } 182 | 183 | factory.getConnection().setAutoCommit(true); 184 | 185 | statAddBD.close(); 186 | statDelRT.close(); 187 | statAddRT.close(); 188 | 189 | // 190 | PreparedStatement stat; 191 | Long result = 0L; 192 | String query = "SELECT COUNT(fid) FROM data"; 193 | 194 | stat = factory.getConnection().prepareStatement(query); 195 | ResultSet rs = stat.executeQuery(); 196 | 197 | rs.next(); 198 | result = rs.getLong(1); 199 | //System.out.println("count = " + result); 200 | 201 | rs.close(); 202 | stat.close(); 203 | } 204 | finally 205 | { 206 | factory.dispose(); 207 | } 208 | 209 | } 210 | 211 | @Test(expected = SQLException.class) 212 | public void reproduceDatabaseLocked() throws SQLException 213 | { 214 | Connection conn = DriverManager.getConnection("jdbc:sqlite:" + dbName); 215 | Connection conn2 = DriverManager.getConnection("jdbc:sqlite:" + dbName); 216 | Statement stat = conn.createStatement(); 217 | Statement stat2 = conn2.createStatement(); 218 | 219 | conn.setAutoCommit(false); 220 | 221 | stat.executeUpdate("drop table if exists sample"); 222 | stat.executeUpdate("create table sample(id, name)"); 223 | stat.executeUpdate("insert into sample values(1, 'leo')"); 224 | 225 | ResultSet rs = stat2.executeQuery("select count(*) from sample"); 226 | rs.next(); 227 | 228 | conn.commit(); // causes "database is locked" (SQLITE_BUSY) 229 | 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /src/test/java/org/sqlite/JDBCTest.java: -------------------------------------------------------------------------------- 1 | //-------------------------------------- 2 | // sqlite-jdbc Project 3 | // 4 | // JDBCTest.java 5 | // Since: Apr 8, 2009 6 | // 7 | // $URL$ 8 | // $Author$ 9 | //-------------------------------------- 10 | package org.sqlite; 11 | 12 | import java.sql.Connection; 13 | import java.sql.DriverManager; 14 | import java.sql.Statement; 15 | import java.util.Properties; 16 | 17 | import org.junit.BeforeClass; 18 | import org.junit.Test; 19 | 20 | public class JDBCTest 21 | { 22 | @BeforeClass 23 | public static void forName() throws Exception { 24 | Class.forName("org.sqlite.JDBC"); 25 | } 26 | 27 | @Test 28 | public void enableLoadExtensionTest() throws Exception { 29 | Properties prop = new Properties(); 30 | prop.setProperty("enable_load_extension", "true"); 31 | 32 | Connection conn = null; 33 | try { 34 | conn = DriverManager.getConnection("jdbc:sqlite:", prop); 35 | Statement stat = conn.createStatement(); 36 | 37 | // How to build shared lib in Windows 38 | // # mingw32-gcc -fPIC -c extension-function.c 39 | // # mingw32-gcc -shared -Wl -o extension-function.dll extension-function.o 40 | 41 | // stat.executeQuery("select load_extension('extension-function.dll')"); 42 | // 43 | // ResultSet rs = stat.executeQuery("select sqrt(4)"); 44 | // System.out.println(rs.getDouble(1)); 45 | 46 | } 47 | finally { 48 | if (conn != null) 49 | conn.close(); 50 | } 51 | } 52 | 53 | @Test 54 | public void majorVersion() throws Exception { 55 | int major = DriverManager.getDriver("jdbc:sqlite:").getMajorVersion(); 56 | int minor = DriverManager.getDriver("jdbc:sqlite:").getMinorVersion(); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/test/java/org/sqlite/OSInfoTest.java: -------------------------------------------------------------------------------- 1 | //-------------------------------------- 2 | // sqlite-jdbc Project 3 | // 4 | // OSInfoTest.java 5 | // Since: May 20, 2008 6 | // 7 | // $URL$ 8 | // $Author$ 9 | //-------------------------------------- 10 | package org.sqlite; 11 | 12 | import static org.junit.Assert.*; 13 | 14 | import java.io.ByteArrayOutputStream; 15 | import java.io.PrintStream; 16 | 17 | import org.junit.Test; 18 | import org.sqlite.util.OSInfo; 19 | 20 | public class OSInfoTest 21 | { 22 | @Test 23 | public void osName() { 24 | assertEquals("Windows", OSInfo.translateOSNameToFolderName("Windows XP")); 25 | assertEquals("Windows", OSInfo.translateOSNameToFolderName("Windows 2000")); 26 | assertEquals("Windows", OSInfo.translateOSNameToFolderName("Windows Vista")); 27 | assertEquals("Windows", OSInfo.translateOSNameToFolderName("Windows 98")); 28 | assertEquals("Windows", OSInfo.translateOSNameToFolderName("Windows 95")); 29 | 30 | assertEquals("Mac", OSInfo.translateOSNameToFolderName("Mac OS")); 31 | assertEquals("Mac", OSInfo.translateOSNameToFolderName("Mac OS X")); 32 | 33 | assertEquals("AIX", OSInfo.translateOSNameToFolderName("AIX")); 34 | 35 | assertEquals("Linux", OSInfo.translateOSNameToFolderName("Linux")); 36 | assertEquals("OS2", OSInfo.translateOSNameToFolderName("OS2")); 37 | 38 | assertEquals("HPUX", OSInfo.translateOSNameToFolderName("HP UX")); 39 | } 40 | 41 | @Test 42 | public void archName() { 43 | assertEquals("i386", OSInfo.translateArchNameToFolderName("i386")); 44 | assertEquals("x86", OSInfo.translateArchNameToFolderName("x86")); 45 | assertEquals("ppc", OSInfo.translateArchNameToFolderName("ppc")); 46 | assertEquals("amd64", OSInfo.translateArchNameToFolderName("amd64")); 47 | } 48 | 49 | @Test 50 | public void folderPath() { 51 | String[] component = OSInfo.getNativeLibFolderPathForCurrentOS().split("/"); 52 | assertEquals(2, component.length); 53 | assertEquals(OSInfo.getOSName(), component[0]); 54 | assertEquals(OSInfo.getArchName(), component[1]); 55 | } 56 | 57 | @Test 58 | public void testMainForOSName() throws Exception { 59 | 60 | // preserve the current System.out 61 | PrintStream out = System.out; 62 | try { 63 | // switch STDOUT 64 | ByteArrayOutputStream buf = new ByteArrayOutputStream(); 65 | PrintStream tmpOut = new PrintStream(buf); 66 | System.setOut(tmpOut); 67 | OSInfo.main(new String[] { "--os" }); 68 | assertEquals(OSInfo.getOSName(), buf.toString()); 69 | } 70 | finally { 71 | // reset STDOUT 72 | System.setOut(out); 73 | } 74 | 75 | } 76 | 77 | @Test 78 | public void testMainForArchName() throws Exception { 79 | 80 | // preserver the current System.out 81 | PrintStream out = System.out; 82 | try { 83 | // switch STDOUT 84 | ByteArrayOutputStream buf = new ByteArrayOutputStream(); 85 | PrintStream tmpOut = new PrintStream(buf); 86 | System.setOut(tmpOut); 87 | OSInfo.main(new String[] { "--arch" }); 88 | assertEquals(OSInfo.getArchName(), buf.toString()); 89 | } 90 | finally { 91 | // reset STDOUT 92 | System.setOut(out); 93 | } 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/test/java/org/sqlite/QueryTest.java: -------------------------------------------------------------------------------- 1 | //-------------------------------------- 2 | // sqlite-jdbc Project 3 | // 4 | // QueryTest.java 5 | // Since: Apr 8, 2009 6 | // 7 | // $URL$ 8 | // $Author$ 9 | //-------------------------------------- 10 | package org.sqlite; 11 | 12 | import static org.junit.Assert.*; 13 | 14 | import java.sql.Connection; 15 | import java.sql.DriverManager; 16 | import java.sql.PreparedStatement; 17 | import java.sql.ResultSet; 18 | import java.sql.SQLException; 19 | import java.sql.Statement; 20 | import java.text.SimpleDateFormat; 21 | import java.util.Date; 22 | 23 | import org.junit.BeforeClass; 24 | import org.junit.Test; 25 | 26 | public class QueryTest 27 | { 28 | @BeforeClass 29 | public static void forName() throws Exception { 30 | Class.forName("org.sqlite.JDBC"); 31 | } 32 | 33 | public Connection getConnection() throws SQLException { 34 | return DriverManager.getConnection("jdbc:sqlite::memory:"); 35 | } 36 | 37 | @Test 38 | public void createTable() throws Exception { 39 | Connection conn = getConnection(); 40 | Statement stmt = conn.createStatement(); 41 | stmt.execute("CREATE TABLE IF NOT EXISTS sample " + "(id INTEGER PRIMARY KEY, descr VARCHAR(40))"); 42 | stmt.close(); 43 | 44 | stmt = conn.createStatement(); 45 | try { 46 | ResultSet rs = stmt.executeQuery("SELECT * FROM sample"); 47 | rs.next(); 48 | } 49 | catch (SQLException e) { 50 | e.printStackTrace(); 51 | } 52 | 53 | conn.close(); 54 | 55 | } 56 | 57 | @Test 58 | public void setFloatTest() throws Exception { 59 | float f = 3.141597f; 60 | Connection conn = getConnection(); 61 | 62 | conn.createStatement().execute("create table sample (data NOAFFINITY)"); 63 | PreparedStatement prep = conn.prepareStatement("insert into sample values(?)"); 64 | prep.setFloat(1, f); 65 | prep.executeUpdate(); 66 | 67 | PreparedStatement stmt = conn.prepareStatement("select * from sample where data > ?"); 68 | stmt.setObject(1, 3.0f); 69 | ResultSet rs = stmt.executeQuery(); 70 | assertTrue(rs.next()); 71 | float f2 = rs.getFloat(1); 72 | assertEquals(f, f2, 0.0000001); 73 | 74 | } 75 | 76 | @Test 77 | public void dateTimeTest() throws Exception { 78 | Connection conn = getConnection(); 79 | 80 | conn.createStatement().execute("create table sample (start_time datetime)"); 81 | 82 | Date now = new Date(); 83 | String date = new SimpleDateFormat(SQLiteConfig.DEFAULT_DATE_STRING_FORMAT).format(now); 84 | 85 | conn.createStatement().execute("insert into sample values(" + now.getTime() + ")"); 86 | conn.createStatement().execute("insert into sample values('" + date + "')"); 87 | 88 | ResultSet rs = conn.createStatement().executeQuery("select * from sample"); 89 | assertTrue(rs.next()); 90 | assertEquals(now, rs.getDate(1)); 91 | assertTrue(rs.next()); 92 | assertEquals(now, rs.getDate(1)); 93 | 94 | PreparedStatement stmt = conn.prepareStatement("insert into sample values(?)"); 95 | stmt.setDate(1, new java.sql.Date(now.getTime())); 96 | } 97 | 98 | @Test 99 | public void viewTest() throws Exception { 100 | Connection conn = getConnection(); 101 | Statement st1 = conn.createStatement(); 102 | // drop table if it already exists 103 | 104 | String tableName = "sample"; 105 | st1.execute("DROP TABLE IF EXISTS " + tableName); 106 | st1.close(); 107 | Statement st2 = conn.createStatement(); 108 | st2.execute("DROP VIEW IF EXISTS " + tableName); 109 | st2.close(); 110 | 111 | } 112 | 113 | @Test 114 | public void timeoutTest() throws Exception { 115 | Connection conn = getConnection(); 116 | Statement st1 = conn.createStatement(); 117 | 118 | st1.setQueryTimeout(1); 119 | 120 | st1.close(); 121 | } 122 | 123 | @Test 124 | public void concatTest() { 125 | 126 | Connection conn = null; 127 | try { 128 | // create a database connection 129 | conn = getConnection(); 130 | Statement statement = conn.createStatement(); 131 | statement.setQueryTimeout(30); // set timeout to 30 sec. 132 | 133 | statement.executeUpdate("drop table if exists person"); 134 | statement.executeUpdate("create table person (id integer, name string, shortname string)"); 135 | statement.executeUpdate("insert into person values(1, 'leo','L')"); 136 | statement.executeUpdate("insert into person values(2, 'yui','Y')"); 137 | statement.executeUpdate("insert into person values(3, 'abc', null)"); 138 | 139 | statement.executeUpdate("drop table if exists message"); 140 | statement.executeUpdate("create table message (id integer, subject string)"); 141 | statement.executeUpdate("insert into message values(1, 'Hello')"); 142 | statement.executeUpdate("insert into message values(2, 'World')"); 143 | 144 | statement.executeUpdate("drop table if exists mxp"); 145 | statement.executeUpdate("create table mxp (pid integer, mid integer, type string)"); 146 | statement.executeUpdate("insert into mxp values(1,1, 'F')"); 147 | statement.executeUpdate("insert into mxp values(2,1,'T')"); 148 | statement.executeUpdate("insert into mxp values(1,2, 'F')"); 149 | statement.executeUpdate("insert into mxp values(2,2,'T')"); 150 | statement.executeUpdate("insert into mxp values(3,2,'T')"); 151 | 152 | ResultSet rs = statement 153 | .executeQuery("select group_concat(ifnull(shortname, name)) from mxp, person where mxp.mid=2 and mxp.pid=person.id and mxp.type='T'"); 154 | while (rs.next()) { 155 | // read the result set 156 | assertEquals("Y,abc", rs.getString(1)); 157 | } 158 | rs = statement 159 | .executeQuery("select group_concat(ifnull(shortname, name)) from mxp, person where mxp.mid=1 and mxp.pid=person.id and mxp.type='T'"); 160 | while (rs.next()) { 161 | // read the result set 162 | assertEquals("Y", rs.getString(1)); 163 | } 164 | 165 | PreparedStatement ps = conn 166 | .prepareStatement("select group_concat(ifnull(shortname, name)) from mxp, person where mxp.mid=? and mxp.pid=person.id and mxp.type='T'"); 167 | ps.clearParameters(); 168 | ps.setInt(1, new Integer(2)); 169 | rs = ps.executeQuery(); 170 | while (rs.next()) { 171 | // read the result set 172 | assertEquals("Y,abc", rs.getString(1)); 173 | } 174 | ps.clearParameters(); 175 | ps.setInt(1, new Integer(2)); 176 | rs = ps.executeQuery(); 177 | while (rs.next()) { 178 | // read the result set 179 | assertEquals("Y,abc", rs.getString(1)); 180 | } 181 | 182 | } 183 | catch (SQLException e) { 184 | // if the error message is "out of memory", 185 | // it probably means no database file is found 186 | System.err.println(e.getMessage()); 187 | } 188 | finally { 189 | try { 190 | if (conn != null) 191 | conn.close(); 192 | } 193 | catch (SQLException e) { 194 | // connection close failed. 195 | System.err.println(e); 196 | } 197 | } 198 | 199 | } 200 | 201 | } 202 | -------------------------------------------------------------------------------- /src/test/java/org/sqlite/RSMetaDataTest.java: -------------------------------------------------------------------------------- 1 | package org.sqlite; 2 | 3 | import static org.junit.Assert.*; 4 | import static org.junit.Assert.assertEquals; 5 | import static org.junit.Assert.assertFalse; 6 | import static org.junit.Assert.assertTrue; 7 | 8 | import java.sql.Connection; 9 | import java.sql.DriverManager; 10 | import java.sql.ResultSetMetaData; 11 | import java.sql.SQLException; 12 | import java.sql.Statement; 13 | import java.sql.Types; 14 | 15 | import org.junit.After; 16 | import org.junit.Before; 17 | import org.junit.BeforeClass; 18 | import org.junit.Test; 19 | 20 | public class RSMetaDataTest 21 | { 22 | private Connection conn; 23 | private Statement stat; 24 | private ResultSetMetaData meta; 25 | 26 | @BeforeClass 27 | public static void forName() throws Exception 28 | { 29 | Class.forName("org.sqlite.JDBC"); 30 | } 31 | 32 | @Before 33 | public void connect() throws Exception 34 | { 35 | conn = DriverManager.getConnection("jdbc:sqlite:"); 36 | stat = conn.createStatement(); 37 | stat.executeUpdate("create table People (pid integer primary key autoincrement, " 38 | + " firstname string(255), surname string(25,5), dob date);"); 39 | stat.executeUpdate("insert into people values (null, 'Mohandas', 'Gandhi', " + " '1869-10-02');"); 40 | meta = stat.executeQuery("select pid, firstname, surname from people;").getMetaData(); 41 | } 42 | 43 | @After 44 | public void close() throws SQLException 45 | { 46 | stat.executeUpdate("drop table people;"); 47 | stat.close(); 48 | conn.close(); 49 | } 50 | 51 | @Test 52 | public void catalogName() throws SQLException 53 | { 54 | assertEquals(meta.getCatalogName(1), "People"); 55 | } 56 | 57 | @Test 58 | public void columns() throws SQLException 59 | { 60 | assertEquals(meta.getColumnCount(), 3); 61 | assertEquals(meta.getColumnName(1), "pid"); 62 | assertEquals(meta.getColumnName(2), "firstname"); 63 | assertEquals(meta.getColumnName(3), "surname"); 64 | assertEquals(meta.getColumnType(1), Types.INTEGER); 65 | assertEquals(meta.getColumnType(2), Types.VARCHAR); 66 | assertEquals(meta.getColumnType(3), Types.VARCHAR); 67 | assertTrue(meta.isAutoIncrement(1)); 68 | assertFalse(meta.isAutoIncrement(2)); 69 | assertFalse(meta.isAutoIncrement(3)); 70 | assertEquals(meta.isNullable(1), ResultSetMetaData.columnNoNulls); 71 | assertEquals(meta.isNullable(2), ResultSetMetaData.columnNullable); 72 | assertEquals(meta.isNullable(3), ResultSetMetaData.columnNullable); 73 | } 74 | 75 | @Test 76 | public void columnTypes() throws SQLException 77 | { 78 | stat.executeUpdate( 79 | "create table tbl (col1 INT, col2 INTEGER, col3 TINYINT, " + 80 | "col4 SMALLINT, col5 MEDIUMINT, col6 BIGINT, col7 UNSIGNED BIG INT, " + 81 | "col8 INT2, col9 INT8, col10 CHARACTER(20), col11 VARCHAR(255), " + 82 | "col12 VARYING CHARACTER(255), col13 NCHAR(55), " + 83 | "col14 NATIVE CHARACTER(70), col15 NVARCHAR(100), col16 TEXT, " + 84 | "col17 CLOB, col18 BLOB, col19 REAL, col20 DOUBLE, " + 85 | "col21 DOUBLE PRECISION, col22 FLOAT, col23 NUMERIC, " + 86 | "col24 DECIMAL(10,5), col25 BOOLEAN, col26 DATE, col27 DATETIME)" 87 | ); 88 | // insert empty data into table otherwise getColumnType returns null 89 | stat.executeUpdate( 90 | "insert into tbl values (1, 2, 3, 4, 5, 6, 7, 8, 9," + 91 | "'c', 'varchar', 'varying', 'n', 'n','nvarchar', 'text', 'clob'," + 92 | "null, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 0, 12345, 123456)"); 93 | meta = stat.executeQuery( 94 | "select col1, col2, col3, col4, col5, col6, col7, col8, col9, " + 95 | "col10, col11, col12, col13, col14, col15, col16, col17, col18, " + 96 | "col19, col20, col21, col22, col23, col24, col25, col26, col27, " + 97 | "cast(col1 as boolean) from tbl" 98 | ).getMetaData(); 99 | 100 | assertEquals(Types.INTEGER, meta.getColumnType(1)); 101 | assertEquals(Types.INTEGER, meta.getColumnType(2)); 102 | assertEquals(Types.TINYINT, meta.getColumnType(3)); 103 | assertEquals(Types.SMALLINT, meta.getColumnType(4)); 104 | assertEquals(Types.INTEGER, meta.getColumnType(5)); 105 | assertEquals(Types.BIGINT, meta.getColumnType(6)); 106 | assertEquals(Types.BIGINT, meta.getColumnType(7)); 107 | assertEquals(Types.SMALLINT, meta.getColumnType(8)); 108 | assertEquals(Types.BIGINT, meta.getColumnType(9)); 109 | 110 | assertEquals(Types.CHAR, meta.getColumnType(10)); 111 | assertEquals(Types.VARCHAR, meta.getColumnType(11)); 112 | assertEquals(Types.VARCHAR, meta.getColumnType(12)); 113 | assertEquals(Types.CHAR, meta.getColumnType(13)); 114 | assertEquals(Types.CHAR, meta.getColumnType(14)); 115 | assertEquals(Types.VARCHAR, meta.getColumnType(15)); 116 | assertEquals(Types.VARCHAR, meta.getColumnType(16)); 117 | assertEquals(Types.CLOB, meta.getColumnType(17)); 118 | 119 | assertEquals(Types.BLOB, meta.getColumnType(18)); 120 | 121 | assertEquals(Types.REAL, meta.getColumnType(19)); 122 | assertEquals(Types.DOUBLE, meta.getColumnType(20)); 123 | assertEquals(Types.DOUBLE, meta.getColumnType(21)); 124 | assertEquals(Types.FLOAT, meta.getColumnType(22)); 125 | assertEquals(Types.NUMERIC, meta.getColumnType(23)); 126 | assertEquals(Types.DECIMAL, meta.getColumnType(24)); 127 | assertEquals(Types.BOOLEAN, meta.getColumnType(25)); 128 | 129 | assertEquals(Types.DATE, meta.getColumnType(26)); 130 | assertEquals(Types.DATE, meta.getColumnType(27)); 131 | 132 | assertEquals(Types.BOOLEAN, meta.getColumnType(28)); 133 | 134 | assertEquals(10, meta.getPrecision(24)); 135 | assertEquals(5, meta.getScale(24)); 136 | } 137 | 138 | @Test 139 | public void differentRS() throws SQLException 140 | { 141 | meta = stat.executeQuery("select * from people;").getMetaData(); 142 | assertEquals(meta.getColumnCount(), 4); 143 | assertEquals(meta.getColumnName(1), "pid"); 144 | assertEquals(meta.getColumnName(2), "firstname"); 145 | assertEquals(meta.getColumnName(3), "surname"); 146 | assertEquals(meta.getColumnName(4), "dob"); 147 | } 148 | 149 | @Test 150 | public void nullable() throws SQLException 151 | { 152 | meta = stat.executeQuery("select null;").getMetaData(); 153 | assertEquals(meta.isNullable(1), ResultSetMetaData.columnNullable); 154 | } 155 | 156 | @Test(expected = SQLException.class) 157 | public void badCatalogIndex() throws SQLException 158 | { 159 | meta.getCatalogName(4); 160 | } 161 | 162 | @Test(expected = SQLException.class) 163 | public void badColumnIndex() throws SQLException 164 | { 165 | meta.getColumnName(4); 166 | } 167 | 168 | @Test 169 | public void scale() throws SQLException 170 | { 171 | assertEquals(0, meta.getScale(2)); 172 | assertEquals(5, meta.getScale(3)); 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /src/test/java/org/sqlite/ReadUncommittedTest.java: -------------------------------------------------------------------------------- 1 | //-------------------------------------- 2 | // sqlite-jdbc Project 3 | // 4 | // ReadCommitedTest.java 5 | // Since: Jan 19, 2009 6 | // 7 | // $URL$ 8 | // $Author$ 9 | //-------------------------------------- 10 | package org.sqlite; 11 | 12 | import java.sql.Connection; 13 | import java.sql.DriverManager; 14 | import java.sql.SQLException; 15 | import java.sql.Statement; 16 | import java.util.Properties; 17 | 18 | import org.junit.After; 19 | import org.junit.Before; 20 | import org.junit.BeforeClass; 21 | import org.junit.Test; 22 | 23 | public class ReadUncommittedTest 24 | { 25 | private Connection conn; 26 | private Statement stat; 27 | 28 | @BeforeClass 29 | public static void forName() throws Exception 30 | { 31 | Class.forName("org.sqlite.JDBC"); 32 | } 33 | 34 | @Before 35 | public void connect() throws Exception 36 | { 37 | Properties prop = new Properties(); 38 | prop.setProperty("shared_cache", "true"); 39 | conn = DriverManager.getConnection("jdbc:sqlite:", prop); 40 | stat = conn.createStatement(); 41 | stat.executeUpdate("create table test (id integer primary key, fn, sn);"); 42 | stat.executeUpdate("create view testView as select * from test;"); 43 | } 44 | 45 | @After 46 | public void close() throws SQLException 47 | { 48 | stat.close(); 49 | conn.close(); 50 | } 51 | 52 | @Test 53 | public void setReadUncommitted() throws SQLException 54 | { 55 | conn.setTransactionIsolation(SQLiteConnection.TRANSACTION_READ_UNCOMMITTED); 56 | } 57 | 58 | @Test 59 | public void setSerializable() throws SQLException 60 | { 61 | conn.setTransactionIsolation(SQLiteConnection.TRANSACTION_SERIALIZABLE); 62 | } 63 | 64 | @Test(expected = SQLException.class) 65 | public void setUnsupportedIsolationLevel() throws SQLException 66 | { 67 | conn.setTransactionIsolation(SQLiteConnection.TRANSACTION_REPEATABLE_READ); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/test/java/org/sqlite/SQLiteConfigTest.java: -------------------------------------------------------------------------------- 1 | package org.sqlite; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import java.sql.SQLException; 6 | import java.util.Properties; 7 | 8 | import org.junit.Test; 9 | 10 | public class SQLiteConfigTest { 11 | 12 | @Test 13 | public void toProperites() throws SQLException 14 | { 15 | SQLiteConfig config = new SQLiteConfig(); 16 | 17 | config.setReadOnly(true); 18 | config.setDateStringFormat("yyyy/mm/dd"); 19 | config.setDatePrecision("seconds"); 20 | config.setDateClass("real"); 21 | 22 | Properties properties = config.toProperties(); 23 | 24 | assertEquals("yyyy/mm/dd", 25 | properties.getProperty(SQLiteConfig.Pragma.DATE_STRING_FORMAT.getPragmaName())); 26 | assertEquals(SQLiteConfig.DatePrecision.SECONDS.name(), 27 | properties.getProperty(SQLiteConfig.Pragma.DATE_PRECISION.getPragmaName())); 28 | assertEquals(SQLiteConfig.DateClass.REAL.name(), 29 | properties.getProperty(SQLiteConfig.Pragma.DATE_CLASS.getPragmaName())); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/org/sqlite/SQLiteConnectionPoolDataSourceTest.java: -------------------------------------------------------------------------------- 1 | /*-------------------------------------------------------------------------- 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | *--------------------------------------------------------------------------*/ 14 | package org.sqlite; 15 | 16 | import static org.junit.Assert.*; 17 | 18 | import java.sql.Connection; 19 | import java.sql.SQLException; 20 | 21 | import javax.sql.ConnectionPoolDataSource; 22 | import javax.sql.PooledConnection; 23 | 24 | import org.junit.Test; 25 | import org.sqlite.javax.SQLiteConnectionPoolDataSource; 26 | 27 | public class SQLiteConnectionPoolDataSourceTest { 28 | 29 | @Test 30 | public void connectionTest () throws SQLException { 31 | ConnectionPoolDataSource ds = new SQLiteConnectionPoolDataSource(); 32 | 33 | PooledConnection pooledConn = ds.getPooledConnection(); 34 | 35 | Connection handle = pooledConn.getConnection(); 36 | assertFalse(handle.isClosed()); 37 | assertTrue(handle.createStatement().execute("select 1")); 38 | 39 | Connection handle2 = pooledConn.getConnection(); 40 | assertTrue(handle.isClosed()); 41 | try { 42 | handle.createStatement().execute("select 1"); 43 | fail(); 44 | } 45 | catch (SQLException e) { 46 | assertEquals("Connection is closed", e.getMessage()); 47 | } 48 | 49 | assertTrue(handle2.createStatement().execute("select 1")); 50 | handle2.close(); 51 | 52 | handle = pooledConn.getConnection(); 53 | assertTrue(handle.createStatement().execute("select 1")); 54 | 55 | pooledConn.close(); 56 | assertTrue(handle.isClosed()); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/test/java/org/sqlite/SQLiteDataSourceTest.java: -------------------------------------------------------------------------------- 1 | //-------------------------------------- 2 | // sqlite-jdbc Project 3 | // 4 | // SQLiteDataSourceTest.java 5 | // Since: Mar 11, 2010 6 | // 7 | // $URL$ 8 | // $Author$ 9 | //-------------------------------------- 10 | package org.sqlite; 11 | 12 | import static org.junit.Assert.*; 13 | 14 | import java.sql.Connection; 15 | import java.sql.ResultSet; 16 | import java.sql.Statement; 17 | 18 | import org.junit.After; 19 | import org.junit.Before; 20 | import org.junit.Test; 21 | 22 | public class SQLiteDataSourceTest 23 | { 24 | 25 | @Before 26 | public void setUp() throws Exception {} 27 | 28 | @After 29 | public void tearDown() throws Exception {} 30 | 31 | @Test 32 | public void enumParam() throws Exception { 33 | 34 | SQLiteDataSource ds = new SQLiteDataSource(); 35 | Connection conn = ds.getConnection(); 36 | Statement stat = conn.createStatement(); 37 | try { 38 | 39 | stat.executeUpdate("create table A (id integer, name)"); 40 | stat.executeUpdate("insert into A values(1, 'leo')"); 41 | ResultSet rs = stat.executeQuery("select * from A"); 42 | int count = 0; 43 | while (rs.next()) { 44 | count++; 45 | int id = rs.getInt(1); 46 | String name = rs.getString(2); 47 | assertEquals(1, id); 48 | assertEquals("leo", name); 49 | } 50 | assertEquals(1, count); 51 | 52 | } 53 | finally { 54 | stat.close(); 55 | conn.close(); 56 | } 57 | 58 | } 59 | 60 | @Test 61 | public void encoding() throws Exception { 62 | 63 | String[] configArray = new String[] { 64 | "UTF8", "UTF-8", "UTF_8", 65 | "UTF16", "UTF-16", "UTF_16", 66 | "UTF_16LE", "UTF-16LE", "UTF16_LITTLE_ENDIAN", 67 | "UTF_16BE", "UTF-16BE","UTF16_BIG_ENDIAN" }; 68 | String[] encodingArray = new String[] { 69 | "UTF-8", "UTF-16le", "UTF-16le", "UTF-16be" }; 70 | 71 | for (int i = 0; i < configArray.length; i++) { 72 | SQLiteDataSource ds = new SQLiteDataSource(); 73 | ds.setEncoding(configArray[i]); 74 | 75 | Connection conn = ds.getConnection(); 76 | Statement stat = conn.createStatement(); 77 | try { 78 | 79 | ResultSet rs = stat.executeQuery("pragma encoding"); 80 | assertEquals(encodingArray[i / 3], rs.getString(1)); 81 | } finally { 82 | stat.close(); 83 | conn.close(); 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/test/java/org/sqlite/SQLiteJDBCLoaderTest.java: -------------------------------------------------------------------------------- 1 | /*-------------------------------------------------------------------------- 2 | * Copyright 2007 Taro L. Saito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *--------------------------------------------------------------------------*/ 16 | //-------------------------------------- 17 | // sqlite-jdbc Project 18 | // 19 | // SQLiteJDBCLoaderTest.java 20 | // Since: Oct 15, 2007 21 | // 22 | // $URL$ 23 | // $Author$ 24 | //-------------------------------------- 25 | package org.sqlite; 26 | 27 | import static org.junit.Assert.assertEquals; 28 | import static org.junit.Assert.assertTrue; 29 | import static org.junit.Assert.fail; 30 | 31 | import java.sql.Connection; 32 | import java.sql.DriverManager; 33 | import java.sql.ResultSet; 34 | import java.sql.SQLException; 35 | import java.sql.Statement; 36 | 37 | import org.junit.After; 38 | import org.junit.Before; 39 | import org.junit.Test; 40 | 41 | public class SQLiteJDBCLoaderTest 42 | { 43 | 44 | private Connection connection = null; 45 | 46 | @Before 47 | public void setUp() throws Exception 48 | { 49 | connection = null; 50 | Class.forName("org.sqlite.JDBC"); 51 | // create a database connection 52 | connection = DriverManager.getConnection("jdbc:sqlite::memory:"); 53 | } 54 | 55 | @After 56 | public void tearDown() throws Exception 57 | { 58 | if (connection != null) 59 | connection.close(); 60 | } 61 | 62 | @Test 63 | public void query() throws ClassNotFoundException 64 | { 65 | try 66 | { 67 | Statement statement = connection.createStatement(); 68 | statement.setQueryTimeout(30); // set timeout to 30 sec. 69 | 70 | statement.executeUpdate("create table person ( id integer, name string)"); 71 | statement.executeUpdate("insert into person values(1, 'leo')"); 72 | statement.executeUpdate("insert into person values(2, 'yui')"); 73 | 74 | ResultSet rs = statement.executeQuery("select * from person order by id"); 75 | while (rs.next()) 76 | { 77 | // read the result set 78 | rs.getInt(1); 79 | rs.getString(2); 80 | } 81 | } 82 | catch (SQLException e) 83 | { 84 | // if e.getMessage() is "out of memory", it probably means no 85 | // database file is found 86 | fail(e.getMessage()); 87 | } 88 | } 89 | 90 | @Test 91 | public void function() throws SQLException 92 | { 93 | Function.create(connection, "total", new Function() { 94 | @Override 95 | protected void xFunc() throws SQLException 96 | { 97 | int sum = 0; 98 | for (int i = 0; i < args(); i++) 99 | sum += value_int(i); 100 | result(sum); 101 | } 102 | }); 103 | 104 | ResultSet rs = connection.createStatement().executeQuery("select total(1, 2, 3, 4, 5)"); 105 | assertTrue(rs.next()); 106 | assertEquals(rs.getInt(1), 1 + 2 + 3 + 4 + 5); 107 | } 108 | 109 | @Test 110 | public void version() 111 | { 112 | // System.out.println(SQLiteJDBCLoader.getVersion()); 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /src/test/java/org/sqlite/sample.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decamp/sqlcipher-jdbc/3ce4defeafa9d468b0b0a91b62d7ac98a5456ed8/src/test/java/org/sqlite/sample.db -------------------------------------------------------------------------------- /src/test/java/org/sqlite/testdb.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decamp/sqlcipher-jdbc/3ce4defeafa9d468b0b0a91b62d7ac98a5456ed8/src/test/java/org/sqlite/testdb.jar --------------------------------------------------------------------------------