├── .gitattributes ├── .github └── workflows │ ├── glorp-integration-tests.yml │ ├── shellcheck.yml │ └── unit-tests.yml ├── .project ├── .smalltalkci ├── .GLORP.ston └── .unit.ston ├── LICENSE ├── README.md ├── bin └── windows │ ├── 32bit │ ├── sqlite3.def │ └── sqlite3.dll │ └── 64bit │ ├── sqlite3.def │ └── sqlite3.dll ├── doc ├── getting_started.md ├── history.md ├── migration.md └── starting_glorp.md ├── scripts ├── install-SQLite3.sh └── setupSQLite3AsDatabaseDriver.st └── src ├── .properties ├── BaselineOfSQLite3 ├── BaselineOfSQLite3.class.st └── package.st ├── SQLite3-Core-Benchmarks ├── ManifestSQLite3CoreBenchmarks.class.st ├── SQLite3Benchmark.class.st └── package.st ├── SQLite3-Core-Tests ├── ManifestSQLite3CoreTests.class.st ├── SQLite3BaseConnectionTest.class.st ├── SQLite3ColumnTest.class.st ├── SQLite3ConnectionTest.class.st ├── SQLite3DatabaseTest.class.st ├── SQLite3RowTest.class.st ├── SQLite3TableBasedTest.class.st ├── SQLite3TableTest.class.st ├── SQLite3TableWithSpacesTest.class.st └── package.st ├── SQLite3-Core ├── FFIExternalReference.extension.st ├── FFIExternalResourceManager.extension.st ├── SQLite3Abort.class.st ├── SQLite3AbortRollback.class.st ├── SQLite3AbstractError.class.st ├── SQLite3AuthorizationDenied.class.st ├── SQLite3Backup.class.st ├── SQLite3BackupExternalReference.class.st ├── SQLite3BaseConnection.class.st ├── SQLite3Busy.class.st ├── SQLite3BusyRecovery.class.st ├── SQLite3BusySnapshot.class.st ├── SQLite3CantOpen.class.st ├── SQLite3CantOpenConvertPath.class.st ├── SQLite3CantOpenFullPath.class.st ├── SQLite3CantOpenIsDir.class.st ├── SQLite3CantOpenNoTempDir.class.st ├── SQLite3Column.class.st ├── SQLite3Connection.class.st ├── SQLite3Constants.class.st ├── SQLite3ConstraintViolation.class.st ├── SQLite3ConstraintViolationCheck.class.st ├── SQLite3ConstraintViolationCommitHook.class.st ├── SQLite3ConstraintViolationForeignKey.class.st ├── SQLite3ConstraintViolationFunction.class.st ├── SQLite3ConstraintViolationNotNull.class.st ├── SQLite3ConstraintViolationPrimaryKey.class.st ├── SQLite3ConstraintViolationRowID.class.st ├── SQLite3ConstraintViolationTrigger.class.st ├── SQLite3ConstraintViolationUnique.class.st ├── SQLite3ConstraintViolationVirtualTable.class.st ├── SQLite3Corrupt.class.st ├── SQLite3CorruptVirtualTable.class.st ├── SQLite3Cursor.class.st ├── SQLite3Database.class.st ├── SQLite3DatabaseExternalObject.class.st ├── SQLite3DoneResult.class.st ├── SQLite3Empty.class.st ├── SQLite3Error.class.st ├── SQLite3Format.class.st ├── SQLite3Full.class.st ├── SQLite3IOError.class.st ├── SQLite3IOErrorAccess.class.st ├── SQLite3IOErrorBlocked.class.st ├── SQLite3IOErrorCheckReservedLock.class.st ├── SQLite3IOErrorClose.class.st ├── SQLite3IOErrorConvertPath.class.st ├── SQLite3IOErrorDelete.class.st ├── SQLite3IOErrorDeleteNoEntry.class.st ├── SQLite3IOErrorDirClose.class.st ├── SQLite3IOErrorDirFSync.class.st ├── SQLite3IOErrorFStat.class.st ├── SQLite3IOErrorFSync.class.st ├── SQLite3IOErrorGetTempPath.class.st ├── SQLite3IOErrorLock.class.st ├── SQLite3IOErrorMemoryMap.class.st ├── SQLite3IOErrorNoMemory.class.st ├── SQLite3IOErrorRead.class.st ├── SQLite3IOErrorReadLock.class.st ├── SQLite3IOErrorSeek.class.st ├── SQLite3IOErrorSharedMemoryError.class.st ├── SQLite3IOErrorSharedMemoryLock.class.st ├── SQLite3IOErrorSharedMemoryMap.class.st ├── SQLite3IOErrorSharedMemoryOpen.class.st ├── SQLite3IOErrorSharedMemorySize.class.st ├── SQLite3IOErrorShortRead.class.st ├── SQLite3IOErrorTruncate.class.st ├── SQLite3IOErrorUnlock.class.st ├── SQLite3IOErrorWrite.class.st ├── SQLite3Internal.class.st ├── SQLite3Interrupt.class.st ├── SQLite3Library.class.st ├── SQLite3Locked.class.st ├── SQLite3LockedSharedCache.class.st ├── SQLite3LogNotice.class.st ├── SQLite3LogNoticeRecoverRollback.class.st ├── SQLite3LogNoticeRecoverWriteAheadLogging.class.st ├── SQLite3LogWarning.class.st ├── SQLite3LogWarningAutoIndex.class.st ├── SQLite3Mismatch.class.st ├── SQLite3Misuse.class.st ├── SQLite3NativeError.class.st ├── SQLite3NoLargeFileSupport.class.st ├── SQLite3NoMemory.class.st ├── SQLite3NotADatabase.class.st ├── SQLite3NotFound.class.st ├── SQLite3NotOpen.class.st ├── SQLite3OKResult.class.st ├── SQLite3OutOfRange.class.st ├── SQLite3Permission.class.st ├── SQLite3PreparedStatement.class.st ├── SQLite3Protocol.class.st ├── SQLite3ReadOnly.class.st ├── SQLite3ReadOnlyCantLock.class.st ├── SQLite3ReadOnlyDBMoved.class.st ├── SQLite3ReadOnlyRecovery.class.st ├── SQLite3ReadOnlyRollback.class.st ├── SQLite3Result.class.st ├── SQLite3Row.class.st ├── SQLite3RowResult.class.st ├── SQLite3SchemaChanged.class.st ├── SQLite3StatementExternalObject.class.st ├── SQLite3Table.class.st ├── SQLite3TooBig.class.st └── package.st ├── SQLite3-Glorp-Tests ├── GlorpBlobTest.extension.st └── package.st ├── SQLite3-Glorp ├── SQLite3BaseConnection.extension.st ├── SQLite3Cursor.extension.st ├── SQLite3Driver.class.st └── package.st ├── SQLite3-Inspector-Extensions ├── AbstractFileReference.extension.st ├── SQLite3Database.extension.st ├── SQLite3Row.extension.st ├── SQLite3Table.extension.st └── package.st ├── SQLite3-Pharo10 ├── Random.extension.st └── package.st ├── SQLite3-Pharo8 ├── SQLite3Library.extension.st └── package.st └── SQLite3-Pharo9 ├── SQLite3Library.extension.st └── package.st /.gitattributes: -------------------------------------------------------------------------------- 1 | *.st linguist-language=Smalltalk 2 | -------------------------------------------------------------------------------- /.github/workflows/glorp-integration-tests.yml: -------------------------------------------------------------------------------- 1 | name: GLORP Integration Tests 2 | 3 | on: [push,pull_request,workflow_dispatch] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | strategy: 9 | fail-fast: false 10 | matrix: 11 | smalltalk: [ Pharo64-9.0, Pharo64-10, Pharo64-11, Pharo64-12 ] 12 | name: ${{ matrix.smalltalk }} 13 | steps: 14 | - uses: actions/checkout@v3 15 | - name: Install SQLite3 16 | run: ./scripts/install-SQLite3.sh 17 | - name: Set up Smalltalk CI 18 | uses: hpi-swa/setup-smalltalkCI@v1 19 | with: 20 | smalltalk-image: ${{ matrix.smalltalk }} 21 | - name: Load Image and Run Integration Tests 22 | run: smalltalkci -s ${{ matrix.smalltalk }} .smalltalkci/.GLORP.ston 23 | timeout-minutes: 15 24 | env: 25 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 26 | - name: Upload coverage to Codecov 27 | uses: codecov/codecov-action@v3 28 | with: 29 | name: GLORP-Integration-Tests-${{matrix.smalltalk}} 30 | token: ${{ secrets.CODECOV_TOKEN }} 31 | -------------------------------------------------------------------------------- /.github/workflows/shellcheck.yml: -------------------------------------------------------------------------------- 1 | name: Shellcheck 2 | 3 | on: [push,pull_request,workflow_dispatch] 4 | 5 | jobs: 6 | shellcheck: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v3 10 | - name: Run Shellcheck 11 | uses: reviewdog/action-shellcheck@v1 12 | with: 13 | github_token: ${{ secrets.GITHUB_TOKEN }} 14 | -------------------------------------------------------------------------------- /.github/workflows/unit-tests.yml: -------------------------------------------------------------------------------- 1 | name: Unit Tests 2 | 3 | on: [push,pull_request,workflow_dispatch] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | strategy: 9 | matrix: 10 | smalltalk: [ Pharo64-9.0, Pharo64-10, Pharo64-11, Pharo64-12 ] 11 | name: ${{ matrix.smalltalk }} 12 | steps: 13 | - uses: actions/checkout@v3 14 | - name: Install SQLite3 15 | run: ./scripts/install-SQLite3.sh 16 | - name: Set up Smalltalk CI 17 | uses: hpi-swa/setup-smalltalkCI@v1 18 | with: 19 | smalltalk-image: ${{ matrix.smalltalk }} 20 | - name: Load Image and Run Tests 21 | run: smalltalkci -s ${{ matrix.smalltalk }} .smalltalkci/.unit.ston 22 | env: 23 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 24 | timeout-minutes: 15 25 | - name: Upload coverage to Codecov 26 | uses: codecov/codecov-action@v3 27 | with: 28 | name: Unit-Tests-${{matrix.smalltalk}} 29 | token: ${{ secrets.CODECOV_TOKEN }} 30 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | { 2 | 'srcDirectory' : 'src' 3 | } -------------------------------------------------------------------------------- /.smalltalkci/.GLORP.ston: -------------------------------------------------------------------------------- 1 | SmalltalkCISpec { 2 | #loading : [ 3 | SCIMetacelloLoadSpec { 4 | #baseline : 'SQLite3', 5 | #directory : '../src', 6 | #load : [ 'CI' ], 7 | #platforms : [ #pharo ] 8 | } 9 | ], 10 | #postLoading : [ 11 | '../scripts/setupSQLite3AsDatabaseDriver.st' 12 | ], 13 | #testing : { 14 | #packages : [ 'Glorp-Integration-Tests' ], 15 | #coverage : { 16 | #packages : [ 'SQLite3-*' ], 17 | #format: #lcov 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.smalltalkci/.unit.ston: -------------------------------------------------------------------------------- 1 | SmalltalkCISpec { 2 | #loading : [ 3 | SCIMetacelloLoadSpec { 4 | #baseline : 'SQLite3', 5 | #directory : '../src', 6 | #load : [ 'Tests' ], 7 | #platforms : [ #pharo ] 8 | } 9 | ], 10 | #testing : { 11 | #coverage : { 12 | #packages : [ 'SQLite3-Core*' ], 13 | #format: #lcov 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2008-2022 Pharo RBMS Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pharo-SQLite3 2 | [![Pharo](https://img.shields.io/static/v1?style=for-the-badge&message=Pharo&color=3297d4&logo=Harbor&logoColor=FFFFFF&label=)](https://www.pharo.org) 3 | [![SQLite3](https://img.shields.io/static/v1?style=for-the-badge&message=SQLite3&color=044a64&logo=SQLite&logoColor=FFFFFF&label=)](https://www.sqlite.org) 4 | 5 | [![Unit Tests](https://github.com/pharo-rdbms/Pharo-SQLite3/actions/workflows/unit-tests.yml/badge.svg)](https://github.com/pharo-rdbms/Pharo-SQLite3/actions/workflows/unit-tests.yml) 6 | [![GLORP Integration Tests](https://github.com/pharo-rdbms/Pharo-SQLite3/actions/workflows/glorp-integration-tests.yml/badge.svg)](https://github.com/pharo-rdbms/Pharo-SQLite3/actions/workflows/glorp-integration-tests.yml) 7 | [![Coverage Status](https://codecov.io/github/pharo-rdbms/Pharo-SQLite3/coverage.svg?branch=master)](https://codecov.io/gh/pharo-rdbms/Pharo-SQLite3/branch/master) 8 | 9 | [![License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) 10 | [![Pharo 9](https://img.shields.io/badge/Pharo-9.0-%23aac9ff.svg)](https://pharo.org/download) 11 | [![Pharo 10](https://img.shields.io/badge/Pharo-10-%23aac9ff.svg)](https://pharo.org/download) 12 | [![Pharo 11](https://img.shields.io/badge/Pharo-11-%23aac9ff.svg)](https://pharo.org/download) 13 | [![Pharo 12](https://img.shields.io/badge/Pharo-12-%23aac9ff.svg)](https://pharo.org/download) 14 | 15 | 16 | Standalone [SQLite3](https://www.sqlite.org) database binding for 17 | [Pharo](http://www.pharo.org) - community owned 18 | 19 | - [Quick Start](#quick-start) 20 | - [Installation](#installation) 21 | - [Getting started](#getting-started) 22 | - [Project Infos](#project-infos) 23 | - [History](#history) 24 | - [Roadmap](#roadmap) 25 | - [Contributors](#contributors) 26 | - [License](#license) 27 | - [Migration](#migration) 28 | 29 | ## Quick Start 30 | 31 | ### Installation 32 | 33 | ```Smalltalk 34 | Metacello new 35 | repository: 'github://pharo-rdbms/Pharo-SQLite3/src'; 36 | baseline: 'SQLite3'; 37 | load 38 | ``` 39 | 40 | a binary of SQlite for Windows is included in the **bin** folder 41 | 42 | ### Getting started 43 | 44 | See the [getting started](doc/getting_started.md) document. 45 | 46 | If you want to use [glorp](https://github.com/pharo-rdbms/glorp) see the [starting glorp](doc/starting_glorp.md) document. 47 | 48 | ## Project Infos 49 | 50 | ## History 51 | 52 | The project goes back to a binding to SQLite database for Squeak later ported to 53 | Pharo and maintained over time to include new SQLite3 features. 54 | 55 | The full history is described in the [history details](doc/history.md). 56 | 57 | ## Roadmap 58 | 59 | - Implement support for 60 | [SQLcipher](https://github.com/sqlcipher/sqlcipher). This was available 61 | in NBSQLite, the SQLite binding using Pharo 4's NativeBoost FFI. 62 | 63 | - Implement driver for [Voyage](https://github.com/pharo-nosql/voyage). 64 | 65 | ## Contributors 66 | 67 | Contributors in order of appearance: 68 | 69 | - Avi Bryant 70 | - Fred Mannby 71 | - [Torsten Bergmann](https://github.com/astares) 72 | - Andreas Raab 73 | - [Pierce Ng](https://github.com/PierceNg) 74 | - [Esteban Lorenzano](https://github.com/estebanlm) 75 | - [Guillermo Polito](https://github.com/guillep) 76 | - [Esteban Maringolo](https://github.com/emaringolo) 77 | - [Julien Deplangue](https://github.com/juliendelplanque) 78 | - [Todd Blanchard](https://github.com/tblanchard) 79 | - [Renaud de Villemeur](https://github.com/rvillemeur) 80 | - [Bernardo Ezequiel Contreras](https://github.com/vonbecmann) 81 | - [Gabriel Omar Cotelli](https://github.com/gcotelli) 82 | - [Konrad Hinsen](https://github.com/khinsen) 83 | - [GitHub contributors](https://github.com/pharo-rdbms/Pharo-SQLite3/graphs/contributors) 84 | 85 | ## LICENSE 86 | 87 | [MIT License](LICENSE) 88 | 89 | ## Migration 90 | 91 | If you want to migrate your code from an older SQLite binding then check the 92 | [Migration Guide](doc/migration.md). 93 | -------------------------------------------------------------------------------- /bin/windows/32bit/sqlite3.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | sqlite3_aggregate_context 3 | sqlite3_aggregate_count 4 | sqlite3_auto_extension 5 | sqlite3_autovacuum_pages 6 | sqlite3_backup_finish 7 | sqlite3_backup_init 8 | sqlite3_backup_pagecount 9 | sqlite3_backup_remaining 10 | sqlite3_backup_step 11 | sqlite3_bind_blob 12 | sqlite3_bind_blob64 13 | sqlite3_bind_double 14 | sqlite3_bind_int 15 | sqlite3_bind_int64 16 | sqlite3_bind_null 17 | sqlite3_bind_parameter_count 18 | sqlite3_bind_parameter_index 19 | sqlite3_bind_parameter_name 20 | sqlite3_bind_pointer 21 | sqlite3_bind_text 22 | sqlite3_bind_text16 23 | sqlite3_bind_text64 24 | sqlite3_bind_value 25 | sqlite3_bind_zeroblob 26 | sqlite3_bind_zeroblob64 27 | sqlite3_blob_bytes 28 | sqlite3_blob_close 29 | sqlite3_blob_open 30 | sqlite3_blob_read 31 | sqlite3_blob_reopen 32 | sqlite3_blob_write 33 | sqlite3_busy_handler 34 | sqlite3_busy_timeout 35 | sqlite3_cancel_auto_extension 36 | sqlite3changegroup_add 37 | sqlite3changegroup_add_strm 38 | sqlite3changegroup_delete 39 | sqlite3changegroup_new 40 | sqlite3changegroup_output 41 | sqlite3changegroup_output_strm 42 | sqlite3_changes 43 | sqlite3_changes64 44 | sqlite3changeset_apply 45 | sqlite3changeset_apply_strm 46 | sqlite3changeset_apply_v2 47 | sqlite3changeset_apply_v2_strm 48 | sqlite3changeset_concat 49 | sqlite3changeset_concat_strm 50 | sqlite3changeset_conflict 51 | sqlite3changeset_finalize 52 | sqlite3changeset_fk_conflicts 53 | sqlite3changeset_invert 54 | sqlite3changeset_invert_strm 55 | sqlite3changeset_new 56 | sqlite3changeset_next 57 | sqlite3changeset_old 58 | sqlite3changeset_op 59 | sqlite3changeset_pk 60 | sqlite3changeset_start 61 | sqlite3changeset_start_strm 62 | sqlite3changeset_start_v2 63 | sqlite3changeset_start_v2_strm 64 | sqlite3_clear_bindings 65 | sqlite3_close 66 | sqlite3_close_v2 67 | sqlite3_collation_needed 68 | sqlite3_collation_needed16 69 | sqlite3_column_blob 70 | sqlite3_column_bytes 71 | sqlite3_column_bytes16 72 | sqlite3_column_count 73 | sqlite3_column_database_name 74 | sqlite3_column_database_name16 75 | sqlite3_column_decltype 76 | sqlite3_column_decltype16 77 | sqlite3_column_double 78 | sqlite3_column_int 79 | sqlite3_column_int64 80 | sqlite3_column_name 81 | sqlite3_column_name16 82 | sqlite3_column_origin_name 83 | sqlite3_column_origin_name16 84 | sqlite3_column_table_name 85 | sqlite3_column_table_name16 86 | sqlite3_column_text 87 | sqlite3_column_text16 88 | sqlite3_column_type 89 | sqlite3_column_value 90 | sqlite3_commit_hook 91 | sqlite3_compileoption_get 92 | sqlite3_compileoption_used 93 | sqlite3_complete 94 | sqlite3_complete16 95 | sqlite3_config 96 | sqlite3_context_db_handle 97 | sqlite3_create_collation 98 | sqlite3_create_collation16 99 | sqlite3_create_collation_v2 100 | sqlite3_create_filename 101 | sqlite3_create_function 102 | sqlite3_create_function16 103 | sqlite3_create_function_v2 104 | sqlite3_create_module 105 | sqlite3_create_module_v2 106 | sqlite3_create_window_function 107 | sqlite3_database_file_object 108 | sqlite3_data_count 109 | sqlite3_db_cacheflush 110 | sqlite3_db_config 111 | sqlite3_db_filename 112 | sqlite3_db_handle 113 | sqlite3_db_mutex 114 | sqlite3_db_name 115 | sqlite3_db_readonly 116 | sqlite3_db_release_memory 117 | sqlite3_db_status 118 | sqlite3_declare_vtab 119 | sqlite3_deserialize 120 | sqlite3_drop_modules 121 | sqlite3_enable_load_extension 122 | sqlite3_enable_shared_cache 123 | sqlite3_errcode 124 | sqlite3_errmsg 125 | sqlite3_errmsg16 126 | sqlite3_error_offset 127 | sqlite3_errstr 128 | sqlite3_exec 129 | sqlite3_expanded_sql 130 | sqlite3_expired 131 | sqlite3_extended_errcode 132 | sqlite3_extended_result_codes 133 | sqlite3_file_control 134 | sqlite3_filename_database 135 | sqlite3_filename_journal 136 | sqlite3_filename_wal 137 | sqlite3_finalize 138 | sqlite3_free 139 | sqlite3_free_filename 140 | sqlite3_free_table 141 | sqlite3_get_autocommit 142 | sqlite3_get_auxdata 143 | sqlite3_get_table 144 | sqlite3_global_recover 145 | sqlite3_hard_heap_limit64 146 | sqlite3_initialize 147 | sqlite3_interrupt 148 | sqlite3_is_interrupted 149 | sqlite3_keyword_check 150 | sqlite3_keyword_count 151 | sqlite3_keyword_name 152 | sqlite3_last_insert_rowid 153 | sqlite3_libversion 154 | sqlite3_libversion_number 155 | sqlite3_limit 156 | sqlite3_load_extension 157 | sqlite3_log 158 | sqlite3_malloc 159 | sqlite3_malloc64 160 | sqlite3_memory_alarm 161 | sqlite3_memory_highwater 162 | sqlite3_memory_used 163 | sqlite3_mprintf 164 | sqlite3_msize 165 | sqlite3_mutex_alloc 166 | sqlite3_mutex_enter 167 | sqlite3_mutex_free 168 | sqlite3_mutex_leave 169 | sqlite3_mutex_try 170 | sqlite3_next_stmt 171 | sqlite3_open 172 | sqlite3_open16 173 | sqlite3_open_v2 174 | sqlite3_os_end 175 | sqlite3_os_init 176 | sqlite3_overload_function 177 | sqlite3_prepare 178 | sqlite3_prepare16 179 | sqlite3_prepare16_v2 180 | sqlite3_prepare16_v3 181 | sqlite3_prepare_v2 182 | sqlite3_prepare_v3 183 | sqlite3_preupdate_blobwrite 184 | sqlite3_preupdate_count 185 | sqlite3_preupdate_depth 186 | sqlite3_preupdate_hook 187 | sqlite3_preupdate_new 188 | sqlite3_preupdate_old 189 | sqlite3_profile 190 | sqlite3_progress_handler 191 | sqlite3_randomness 192 | sqlite3_realloc 193 | sqlite3_realloc64 194 | sqlite3rebaser_configure 195 | sqlite3rebaser_create 196 | sqlite3rebaser_delete 197 | sqlite3rebaser_rebase 198 | sqlite3rebaser_rebase_strm 199 | sqlite3_release_memory 200 | sqlite3_reset 201 | sqlite3_reset_auto_extension 202 | sqlite3_result_blob 203 | sqlite3_result_blob64 204 | sqlite3_result_double 205 | sqlite3_result_error 206 | sqlite3_result_error16 207 | sqlite3_result_error_code 208 | sqlite3_result_error_nomem 209 | sqlite3_result_error_toobig 210 | sqlite3_result_int 211 | sqlite3_result_int64 212 | sqlite3_result_null 213 | sqlite3_result_pointer 214 | sqlite3_result_subtype 215 | sqlite3_result_text 216 | sqlite3_result_text16 217 | sqlite3_result_text16be 218 | sqlite3_result_text16le 219 | sqlite3_result_text64 220 | sqlite3_result_value 221 | sqlite3_result_zeroblob 222 | sqlite3_result_zeroblob64 223 | sqlite3_rollback_hook 224 | sqlite3_rtree_geometry_callback 225 | sqlite3_rtree_query_callback 226 | sqlite3_serialize 227 | sqlite3session_attach 228 | sqlite3session_changeset 229 | sqlite3session_changeset_size 230 | sqlite3session_changeset_strm 231 | sqlite3session_config 232 | sqlite3session_create 233 | sqlite3session_delete 234 | sqlite3session_diff 235 | sqlite3session_enable 236 | sqlite3session_indirect 237 | sqlite3session_isempty 238 | sqlite3session_memory_used 239 | sqlite3session_object_config 240 | sqlite3session_patchset 241 | sqlite3session_patchset_strm 242 | sqlite3session_table_filter 243 | sqlite3_set_authorizer 244 | sqlite3_set_auxdata 245 | sqlite3_set_last_insert_rowid 246 | sqlite3_shutdown 247 | sqlite3_sleep 248 | sqlite3_snprintf 249 | sqlite3_soft_heap_limit 250 | sqlite3_soft_heap_limit64 251 | sqlite3_sourceid 252 | sqlite3_sql 253 | sqlite3_status 254 | sqlite3_status64 255 | sqlite3_step 256 | sqlite3_stmt_busy 257 | sqlite3_stmt_explain 258 | sqlite3_stmt_isexplain 259 | sqlite3_stmt_readonly 260 | sqlite3_stmt_status 261 | sqlite3_str_append 262 | sqlite3_str_appendall 263 | sqlite3_str_appendchar 264 | sqlite3_str_appendf 265 | sqlite3_str_errcode 266 | sqlite3_str_finish 267 | sqlite3_strglob 268 | sqlite3_stricmp 269 | sqlite3_str_length 270 | sqlite3_strlike 271 | sqlite3_str_new 272 | sqlite3_strnicmp 273 | sqlite3_str_reset 274 | sqlite3_str_value 275 | sqlite3_str_vappendf 276 | sqlite3_system_errno 277 | sqlite3_table_column_metadata 278 | sqlite3_test_control 279 | sqlite3_thread_cleanup 280 | sqlite3_threadsafe 281 | sqlite3_total_changes 282 | sqlite3_total_changes64 283 | sqlite3_trace 284 | sqlite3_trace_v2 285 | sqlite3_transfer_bindings 286 | sqlite3_txn_state 287 | sqlite3_update_hook 288 | sqlite3_uri_boolean 289 | sqlite3_uri_int64 290 | sqlite3_uri_key 291 | sqlite3_uri_parameter 292 | sqlite3_user_data 293 | sqlite3_value_blob 294 | sqlite3_value_bytes 295 | sqlite3_value_bytes16 296 | sqlite3_value_double 297 | sqlite3_value_dup 298 | sqlite3_value_encoding 299 | sqlite3_value_free 300 | sqlite3_value_frombind 301 | sqlite3_value_int 302 | sqlite3_value_int64 303 | sqlite3_value_nochange 304 | sqlite3_value_numeric_type 305 | sqlite3_value_pointer 306 | sqlite3_value_subtype 307 | sqlite3_value_text 308 | sqlite3_value_text16 309 | sqlite3_value_text16be 310 | sqlite3_value_text16le 311 | sqlite3_value_type 312 | sqlite3_vfs_find 313 | sqlite3_vfs_register 314 | sqlite3_vfs_unregister 315 | sqlite3_vmprintf 316 | sqlite3_vsnprintf 317 | sqlite3_vtab_collation 318 | sqlite3_vtab_config 319 | sqlite3_vtab_distinct 320 | sqlite3_vtab_in 321 | sqlite3_vtab_in_first 322 | sqlite3_vtab_in_next 323 | sqlite3_vtab_nochange 324 | sqlite3_vtab_on_conflict 325 | sqlite3_vtab_rhs_value 326 | sqlite3_wal_autocheckpoint 327 | sqlite3_wal_checkpoint 328 | sqlite3_wal_checkpoint_v2 329 | sqlite3_wal_hook 330 | sqlite3_win32_is_nt 331 | sqlite3_win32_mbcs_to_utf8 332 | sqlite3_win32_mbcs_to_utf8_v2 333 | sqlite3_win32_set_directory 334 | sqlite3_win32_set_directory16 335 | sqlite3_win32_set_directory8 336 | sqlite3_win32_sleep 337 | sqlite3_win32_unicode_to_utf8 338 | sqlite3_win32_utf8_to_mbcs 339 | sqlite3_win32_utf8_to_mbcs_v2 340 | sqlite3_win32_utf8_to_unicode 341 | sqlite3_win32_write_debug 342 | -------------------------------------------------------------------------------- /bin/windows/32bit/sqlite3.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-rdbms/Pharo-SQLite3/a5e1363f06a5ee050d65d817725ea0c6d879e648/bin/windows/32bit/sqlite3.dll -------------------------------------------------------------------------------- /bin/windows/64bit/sqlite3.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | sqlite3_aggregate_context 3 | sqlite3_aggregate_count 4 | sqlite3_auto_extension 5 | sqlite3_autovacuum_pages 6 | sqlite3_backup_finish 7 | sqlite3_backup_init 8 | sqlite3_backup_pagecount 9 | sqlite3_backup_remaining 10 | sqlite3_backup_step 11 | sqlite3_bind_blob 12 | sqlite3_bind_blob64 13 | sqlite3_bind_double 14 | sqlite3_bind_int 15 | sqlite3_bind_int64 16 | sqlite3_bind_null 17 | sqlite3_bind_parameter_count 18 | sqlite3_bind_parameter_index 19 | sqlite3_bind_parameter_name 20 | sqlite3_bind_pointer 21 | sqlite3_bind_text 22 | sqlite3_bind_text16 23 | sqlite3_bind_text64 24 | sqlite3_bind_value 25 | sqlite3_bind_zeroblob 26 | sqlite3_bind_zeroblob64 27 | sqlite3_blob_bytes 28 | sqlite3_blob_close 29 | sqlite3_blob_open 30 | sqlite3_blob_read 31 | sqlite3_blob_reopen 32 | sqlite3_blob_write 33 | sqlite3_busy_handler 34 | sqlite3_busy_timeout 35 | sqlite3_cancel_auto_extension 36 | sqlite3_changes 37 | sqlite3_changes64 38 | sqlite3_clear_bindings 39 | sqlite3_close 40 | sqlite3_close_v2 41 | sqlite3_collation_needed 42 | sqlite3_collation_needed16 43 | sqlite3_column_blob 44 | sqlite3_column_bytes 45 | sqlite3_column_bytes16 46 | sqlite3_column_count 47 | sqlite3_column_database_name 48 | sqlite3_column_database_name16 49 | sqlite3_column_decltype 50 | sqlite3_column_decltype16 51 | sqlite3_column_double 52 | sqlite3_column_int 53 | sqlite3_column_int64 54 | sqlite3_column_name 55 | sqlite3_column_name16 56 | sqlite3_column_origin_name 57 | sqlite3_column_origin_name16 58 | sqlite3_column_table_name 59 | sqlite3_column_table_name16 60 | sqlite3_column_text 61 | sqlite3_column_text16 62 | sqlite3_column_type 63 | sqlite3_column_value 64 | sqlite3_commit_hook 65 | sqlite3_compileoption_get 66 | sqlite3_compileoption_used 67 | sqlite3_complete 68 | sqlite3_complete16 69 | sqlite3_config 70 | sqlite3_context_db_handle 71 | sqlite3_create_collation 72 | sqlite3_create_collation_v2 73 | sqlite3_create_collation16 74 | sqlite3_create_filename 75 | sqlite3_create_function 76 | sqlite3_create_function_v2 77 | sqlite3_create_function16 78 | sqlite3_create_module 79 | sqlite3_create_module_v2 80 | sqlite3_create_window_function 81 | sqlite3_data_count 82 | sqlite3_data_directory 83 | sqlite3_database_file_object 84 | sqlite3_db_cacheflush 85 | sqlite3_db_config 86 | sqlite3_db_filename 87 | sqlite3_db_handle 88 | sqlite3_db_mutex 89 | sqlite3_db_name 90 | sqlite3_db_readonly 91 | sqlite3_db_release_memory 92 | sqlite3_db_status 93 | sqlite3_declare_vtab 94 | sqlite3_deserialize 95 | sqlite3_drop_modules 96 | sqlite3_enable_load_extension 97 | sqlite3_enable_shared_cache 98 | sqlite3_errcode 99 | sqlite3_errmsg 100 | sqlite3_errmsg16 101 | sqlite3_error_offset 102 | sqlite3_errstr 103 | sqlite3_exec 104 | sqlite3_expanded_sql 105 | sqlite3_expired 106 | sqlite3_extended_errcode 107 | sqlite3_extended_result_codes 108 | sqlite3_file_control 109 | sqlite3_filename_database 110 | sqlite3_filename_journal 111 | sqlite3_filename_wal 112 | sqlite3_finalize 113 | sqlite3_free 114 | sqlite3_free_filename 115 | sqlite3_free_table 116 | sqlite3_get_autocommit 117 | sqlite3_get_auxdata 118 | sqlite3_get_table 119 | sqlite3_global_recover 120 | sqlite3_hard_heap_limit64 121 | sqlite3_initialize 122 | sqlite3_interrupt 123 | sqlite3_is_interrupted 124 | sqlite3_keyword_check 125 | sqlite3_keyword_count 126 | sqlite3_keyword_name 127 | sqlite3_last_insert_rowid 128 | sqlite3_libversion 129 | sqlite3_libversion_number 130 | sqlite3_limit 131 | sqlite3_load_extension 132 | sqlite3_log 133 | sqlite3_malloc 134 | sqlite3_malloc64 135 | sqlite3_memory_alarm 136 | sqlite3_memory_highwater 137 | sqlite3_memory_used 138 | sqlite3_mprintf 139 | sqlite3_msize 140 | sqlite3_mutex_alloc 141 | sqlite3_mutex_enter 142 | sqlite3_mutex_free 143 | sqlite3_mutex_leave 144 | sqlite3_mutex_try 145 | sqlite3_next_stmt 146 | sqlite3_open 147 | sqlite3_open_v2 148 | sqlite3_open16 149 | sqlite3_os_end 150 | sqlite3_os_init 151 | sqlite3_overload_function 152 | sqlite3_prepare 153 | sqlite3_prepare_v2 154 | sqlite3_prepare_v3 155 | sqlite3_prepare16 156 | sqlite3_prepare16_v2 157 | sqlite3_prepare16_v3 158 | sqlite3_preupdate_blobwrite 159 | sqlite3_preupdate_count 160 | sqlite3_preupdate_depth 161 | sqlite3_preupdate_hook 162 | sqlite3_preupdate_new 163 | sqlite3_preupdate_old 164 | sqlite3_profile 165 | sqlite3_progress_handler 166 | sqlite3_randomness 167 | sqlite3_realloc 168 | sqlite3_realloc64 169 | sqlite3_release_memory 170 | sqlite3_reset 171 | sqlite3_reset_auto_extension 172 | sqlite3_result_blob 173 | sqlite3_result_blob64 174 | sqlite3_result_double 175 | sqlite3_result_error 176 | sqlite3_result_error_code 177 | sqlite3_result_error_nomem 178 | sqlite3_result_error_toobig 179 | sqlite3_result_error16 180 | sqlite3_result_int 181 | sqlite3_result_int64 182 | sqlite3_result_null 183 | sqlite3_result_pointer 184 | sqlite3_result_subtype 185 | sqlite3_result_text 186 | sqlite3_result_text16 187 | sqlite3_result_text16be 188 | sqlite3_result_text16le 189 | sqlite3_result_text64 190 | sqlite3_result_value 191 | sqlite3_result_zeroblob 192 | sqlite3_result_zeroblob64 193 | sqlite3_rollback_hook 194 | sqlite3_rtree_geometry_callback 195 | sqlite3_rtree_query_callback 196 | sqlite3_serialize 197 | sqlite3_set_authorizer 198 | sqlite3_set_auxdata 199 | sqlite3_set_last_insert_rowid 200 | sqlite3_shutdown 201 | sqlite3_sleep 202 | sqlite3_snprintf 203 | sqlite3_soft_heap_limit 204 | sqlite3_soft_heap_limit64 205 | sqlite3_sourceid 206 | sqlite3_sql 207 | sqlite3_status 208 | sqlite3_status64 209 | sqlite3_step 210 | sqlite3_stmt_busy 211 | sqlite3_stmt_explain 212 | sqlite3_stmt_isexplain 213 | sqlite3_stmt_readonly 214 | sqlite3_stmt_status 215 | sqlite3_str_append 216 | sqlite3_str_appendall 217 | sqlite3_str_appendchar 218 | sqlite3_str_appendf 219 | sqlite3_str_errcode 220 | sqlite3_str_finish 221 | sqlite3_str_length 222 | sqlite3_str_new 223 | sqlite3_str_reset 224 | sqlite3_str_value 225 | sqlite3_str_vappendf 226 | sqlite3_strglob 227 | sqlite3_stricmp 228 | sqlite3_strlike 229 | sqlite3_strnicmp 230 | sqlite3_system_errno 231 | sqlite3_table_column_metadata 232 | sqlite3_temp_directory 233 | sqlite3_test_control 234 | sqlite3_thread_cleanup 235 | sqlite3_threadsafe 236 | sqlite3_total_changes 237 | sqlite3_total_changes64 238 | sqlite3_trace 239 | sqlite3_trace_v2 240 | sqlite3_transfer_bindings 241 | sqlite3_txn_state 242 | sqlite3_update_hook 243 | sqlite3_uri_boolean 244 | sqlite3_uri_int64 245 | sqlite3_uri_key 246 | sqlite3_uri_parameter 247 | sqlite3_user_data 248 | sqlite3_value_blob 249 | sqlite3_value_bytes 250 | sqlite3_value_bytes16 251 | sqlite3_value_double 252 | sqlite3_value_dup 253 | sqlite3_value_encoding 254 | sqlite3_value_free 255 | sqlite3_value_frombind 256 | sqlite3_value_int 257 | sqlite3_value_int64 258 | sqlite3_value_nochange 259 | sqlite3_value_numeric_type 260 | sqlite3_value_pointer 261 | sqlite3_value_subtype 262 | sqlite3_value_text 263 | sqlite3_value_text16 264 | sqlite3_value_text16be 265 | sqlite3_value_text16le 266 | sqlite3_value_type 267 | sqlite3_version 268 | sqlite3_vfs_find 269 | sqlite3_vfs_register 270 | sqlite3_vfs_unregister 271 | sqlite3_vmprintf 272 | sqlite3_vsnprintf 273 | sqlite3_vtab_collation 274 | sqlite3_vtab_config 275 | sqlite3_vtab_distinct 276 | sqlite3_vtab_in 277 | sqlite3_vtab_in_first 278 | sqlite3_vtab_in_next 279 | sqlite3_vtab_nochange 280 | sqlite3_vtab_on_conflict 281 | sqlite3_vtab_rhs_value 282 | sqlite3_wal_autocheckpoint 283 | sqlite3_wal_checkpoint 284 | sqlite3_wal_checkpoint_v2 285 | sqlite3_wal_hook 286 | sqlite3_win32_is_nt 287 | sqlite3_win32_mbcs_to_utf8 288 | sqlite3_win32_mbcs_to_utf8_v2 289 | sqlite3_win32_set_directory 290 | sqlite3_win32_set_directory16 291 | sqlite3_win32_set_directory8 292 | sqlite3_win32_sleep 293 | sqlite3_win32_unicode_to_utf8 294 | sqlite3_win32_utf8_to_mbcs 295 | sqlite3_win32_utf8_to_mbcs_v2 296 | sqlite3_win32_utf8_to_unicode 297 | sqlite3_win32_write_debug 298 | sqlite3changegroup_add 299 | sqlite3changegroup_add_strm 300 | sqlite3changegroup_delete 301 | sqlite3changegroup_new 302 | sqlite3changegroup_output 303 | sqlite3changegroup_output_strm 304 | sqlite3changeset_apply 305 | sqlite3changeset_apply_strm 306 | sqlite3changeset_apply_v2 307 | sqlite3changeset_apply_v2_strm 308 | sqlite3changeset_concat 309 | sqlite3changeset_concat_strm 310 | sqlite3changeset_conflict 311 | sqlite3changeset_finalize 312 | sqlite3changeset_fk_conflicts 313 | sqlite3changeset_invert 314 | sqlite3changeset_invert_strm 315 | sqlite3changeset_new 316 | sqlite3changeset_next 317 | sqlite3changeset_old 318 | sqlite3changeset_op 319 | sqlite3changeset_pk 320 | sqlite3changeset_start 321 | sqlite3changeset_start_strm 322 | sqlite3changeset_start_v2 323 | sqlite3changeset_start_v2_strm 324 | sqlite3rebaser_configure 325 | sqlite3rebaser_create 326 | sqlite3rebaser_delete 327 | sqlite3rebaser_rebase 328 | sqlite3rebaser_rebase_strm 329 | sqlite3session_attach 330 | sqlite3session_changeset 331 | sqlite3session_changeset_size 332 | sqlite3session_changeset_strm 333 | sqlite3session_config 334 | sqlite3session_create 335 | sqlite3session_delete 336 | sqlite3session_diff 337 | sqlite3session_enable 338 | sqlite3session_indirect 339 | sqlite3session_isempty 340 | sqlite3session_memory_used 341 | sqlite3session_object_config 342 | sqlite3session_patchset 343 | sqlite3session_patchset_strm 344 | sqlite3session_table_filter 345 | -------------------------------------------------------------------------------- /bin/windows/64bit/sqlite3.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-rdbms/Pharo-SQLite3/a5e1363f06a5ee050d65d817725ea0c6d879e648/bin/windows/64bit/sqlite3.dll -------------------------------------------------------------------------------- /doc/getting_started.md: -------------------------------------------------------------------------------- 1 | # Getting started 2 | 3 | This section explains how to get started with [SQLite3](../README.md) in [Pharo](http://www.pharo.org). 4 | 5 | ## Creating a connection 6 | 7 | The first step is to create a connection to a SQLite3 database. 8 | There are two possibilities: 9 | 10 | - Create a database stored in memory (i.e. the RAM) 11 | 12 | ```st 13 | connection := SQLite3Connection memory. 14 | ``` 15 | 16 | - Create a database stored on the file system. 17 | 18 | ```st 19 | connection := SQLite3Connection 20 | on: (Smalltalk imageDirectory / 'mydatabase.db') fullName. 21 | ``` 22 | 23 | ## Opening a connection 24 | 25 | Either memory and file databases need to be opened before further use. 26 | This can be achieve using `#open` message. 27 | 28 | ```st 29 | connection open. 30 | ``` 31 | 32 | ## Executing a simple query 33 | 34 | Once the connection is open, it is possible to execute an arbitrary number of 35 | queries on it. 36 | 37 | In this tutorial, we create a table named `'person'`. 38 | This table has 3 columns: 39 | 40 | - `id` of type `INTEGER` being the primary key of the table. Additionally, this 41 | column is auto-incremented which means that if a row is inserted without 42 | specifying the value for `id` column, it will automatically gets the value 43 | resulting of the query `SELECT MAX(id) + 1 FROM person;` 44 | - `name` of type `TEXT` storing the name of a person as a string of arbitrary length 45 | - `age` of type `INTEGER` storing the age of a person as an integer 46 | 47 | ```st 48 | connection execute: 'CREATE TABLE person( 49 | id INTEGER PRIMARY KEY AUTOINCREMENT, 50 | name TEXT NOT NULL, 51 | age INTEGER NOT NULL 52 | );'. 53 | ``` 54 | 55 | ## Executing a parametrized query 56 | 57 | It is possible to inject parameters into a query template. 58 | Such query template are called "prepared statements". 59 | These parameters can be described in two ways in the query string: per index in 60 | an array of argument or per parameter name in a dictionary of arguments. 61 | 62 | ### Parameterize per index 63 | 64 | The interrogation mark allows to inject parameters from an array of arguments. 65 | If interrogation marks are written as is, the parameters are taken in the order 66 | they are provided by the array of arguments: 67 | 68 | ```st 69 | connection execute: 'INSERT INTO person(name,age) VALUES (?, ?);' 70 | value: 'Julien' value: 24. 71 | ``` 72 | 73 | If the interrogation mark is followed by an integer, the parameter is taken at 74 | the corresponding index of the array of arguments: 75 | 76 | ```st 77 | connection execute: 'INSERT INTO person(name,age) VALUES (?2, ?1);' 78 | value: 25 value: 'Cyril'. 79 | ``` 80 | 81 | This last query is equivalent to the following which is useful when the arguments 82 | array is big. 83 | 84 | ```st 85 | connection execute: 'INSERT INTO person(name,age) VALUES (?2, ?1);' with: #(25 'Cyril'). 86 | ``` 87 | 88 | ### Parameterize per name 89 | 90 | Parameters can be referenced through a name, either prefixed by `:` or `@` character. 91 | The two following examples are equivalent: 92 | 93 | ```st 94 | connection execute: 'INSERT INTO person(name,age) VALUES (:name, :age);' with: { 95 | ':name' -> 'Guillaume'. 96 | ':age' -> 30 } asDictionary. 97 | ``` 98 | 99 | ```st 100 | connection execute: 'INSERT INTO person(name,age) VALUES (@name, @age);' with: { 101 | '@name' -> 'Guillaume'. 102 | '@age' -> 30 } asDictionary. 103 | ``` 104 | 105 | ## Gather results from a query 106 | 107 | All calls to execute return a `SQLite3Cursor` object. 108 | This object allows one to retrieve the results of the query. 109 | 110 | ```st 111 | cursor := connection execute: 'SELECT * FROM person;'. 112 | ``` 113 | 114 | One can ask a cursor if it has more results to provide. 115 | 116 | ```st 117 | cursor hasNext. "true" 118 | ``` 119 | 120 | If the answer is true, the next row of results can be retrieved. 121 | 122 | ```st 123 | cursor next. "a SQLite3Row(id : 1, name : 'Cyril', age : 25)" 124 | ``` 125 | 126 | It is also possible to ask for all remaining rows of the cursor as an array. 127 | 128 | ```st 129 | cursor rows. 130 | "an Array(a SQLite3Row(id : 2, name : 'Julien', age : 24) 131 | a SQLite3Row(id : 3, name : 'Guillaume', age : 30) )" 132 | ``` 133 | 134 | Thus, the cursor has no more row to provide. 135 | 136 | ```st 137 | cursor hasNext. "false" 138 | ``` 139 | 140 | ## Closing a connection 141 | 142 | Either memory and file databases need to be closed when no longer needed. 143 | This can be achieve using `#close` message. 144 | 145 | ```st 146 | connection close. 147 | ``` 148 | -------------------------------------------------------------------------------- /doc/history.md: -------------------------------------------------------------------------------- 1 | # History 2 | 3 | This document describes the history of bindings for [SQLite3](https://www.sqlite.org/) in the [Squeak](http://www.squeak.org) and [Pharo](http://www.pharo.org) world and the history of the Pharo SQLite3 project for [Pharo](http://www.pharo.org). 4 | 5 | SQLite is a C-language library that implements a small, fast, self-contained, high-reliability, full-featured, SQL database engine. It perfectly fits as a tiny relational database system (RDBMS) for applications that have to persist data in a simple way. 6 | 7 | ## Early versions for Squeak 8 | 9 | Initially there was a simple FFI wrapper for SQLite Version 2 provided in 2002 by [Avi Bryant](https://twitter.com/avibryant) (creator of [Seaside](http://www.seaside.st)) for [Squeak](http://www.squeak.org) available only as a simple code file / changeset. [FFI](http://wiki.squeak.org/squeak/1414) was the foreign function interface for Squeak allowing to call external C libraries. Additionally there was another Squeak wrapper for the SQlite library written in [2005 by Fred Mannby](http://map.squeak.org/package/b396aec0-e9cd-4e70-8746-eb38284f75af). 10 | 11 | ## Versions for Pharo 12 | 13 | ### Initial SQLite binding for Pharo 1.0 - 3.0 based on FFI 14 | 15 | In 2010 [Torsten Bergmann](https://github.com/astares) wrote an initial version for an SQLite binding for Pharo based on the old Squeak code. Beside getting the code to work again several cleanups were applied like commenting, categorization of methods and removing old underscore assignments to follow standard syntax. This initial version also packaged the code using [Metacello](https://wiki.squeak.org/squeak/6157) package system and was released as "SQLite3-Core-tbn.1.mcz" in the [http://www.squeaksource.com/SQLite.html](http://www.squeaksource.com/SQLite.html) repository. 16 | 17 | Andreas Raab (Squeak VM engineer) helped maintaining it and added things like prepared statements and other at that time in the same repo. This code was hosted on old [SqueakSource](http://www.squeaksource.com) repository server until 2013 and then it was moved to [SmalltalkHub](http://www.smalltalkhub.com/) repo [http://smalltalkhub.com/#!/~TorstenBergmann/SQLite](http://smalltalkhub.com/#!/~TorstenBergmann/SQLite) which was a new code hosting page at that time. 18 | 19 | The SQLite binding in this outdated STHub repo includes the versions valid up to Pharo 3.0. 20 | 21 | ### SQLite binding based on Native Boost for Pharo 4 22 | 23 | As Pharo moved on a new foreign function interface called ["Native Boost"](http://www.esug.org/wiki/pier/Conferences/2011/Schedule-And-Talks/Native-boost) from [Igor Stasenko](https://github.com/sig) appeared in 2014 as a way to do externally bind libraries. So the old Squeak's FFI mechanism was seen as legacy for doing foreign function calls. 24 | 25 | Therefore in [2014 Pierce Ng started to port the code](https://www.samadhiweb.com/blog/2014.03.01.nbsqlite3.html) to make use of the new NativeBoost mechanism as you can read on a [blog post](https://www.samadhiweb.com/blog/2014.03.01.nbsqlite3.html) he wrote at that time. Initially this new NB version from Pierce was hosted on [http://ss3.gemstone.com/ss/NBSQLite3.html](http://ss3.gemstone.com/ss/NBSQLite3.html) in an own repository. 26 | 27 | Torsten and [Pierce](https://github.com/PierceNg) cooperated and agreed to host the common code in [http://smalltalkhub.com/#!/~PharoExtras/NBSQLite3](http://smalltalkhub.com/#!/~PharoExtras/NBSQLite3) as SmalltalkHub was the central place to host Pharo projects at that time. 28 | 29 | Pharo also had a port of the famous [Glorp ORM](http://glorp.org/) (object relational mapping) framework originally provided by Alan Knight. The Glorp framework goes back to ideas TOPLink Smalltalk which later influenced also TOPLink for Java and other ORM frameworks. 30 | 31 | Pierce contributed a lot of new code to the project and several nice things got added: [Glorp binding](https://www.samadhiweb.com/blog/2014.09.24.glorp.nbsqlite3.html), encoding, ciphers. The two maintainers also cared on setting up an early Smalltalk CI jobs and proper configurations so the SQlite3 code was easily accessible from the Pharo catalog. 32 | 33 | This native boost (NB) based version of SQLite3 binding was the officially supported version up to Pharo 4 34 | 35 | #### Sideways: a fork for DBXTalk/Garage 36 | In 2013/2014 a project called ["DBXTalk"](https://guillep.github.io/DBXTalk) was started by [Mariano Martinez Peck](https://github.com/marianopeck), Rocio Amaya, [Santiago Bragagnolo](https://github.com/sbragagnolo) and [Guillermo Polito](https://github.com/guillep) to provide a binding to [OpenDBX](https://www.linuxnetworks.de/doc/index.php/OpenDBX) drivers and get better database support for [Pharo](http://www.pharo.org). 37 | 38 | For this another project was setup by Guille called "[Garage](https://guillep.github.io/DBXTalk/garage/)" for the relational database drivers for Pharo. The idea behind Garage was to provide a common API to the different Sqlite3, Postgres V2, Mysql, OpenDBX database drivers that were in existence for Pharo at that time. 39 | 40 | Garage loaded different drivers, except for the SQLite3 binding where Garage included a full copy of the existing NB code version of Sqlite3 binding. This code was kept within the [custom Garage repo](http://www.smalltalkhub.com/#!/~DBXTalk/Garage). The existing maintainers were unaware of this copy and kept maintaining the driver in the original repos. This unfortunately lead to two independent forks. The fork in the Garage repos got quickly out of date as it stayed unmaintained. 41 | 42 | ### Sqlite3 UFFI Version for Pharo 5 and Glorp binding 43 | 44 | As Pharo moved on in Pharo 5 a new Unified Foreign Function Interface (UFFI) written by [Esteban Lorenzano](https://github.com/estebanlm) was included into the base Pharo image. UFFI was seen as the new way to bind to the external world. So the maintained code of the SQlite binding required again updates to follow the new callout rules. 45 | 46 | Inspired by the UFFI approach Torsten additionally experimented in possibly getting the database drivers unified by defining a unified database access layer for Pharo. The idea was also to cleanup and heal the situation that was lasting due to the additional unmaintained copy of the code in Garage. This experimental project was hosted in a [personal repo on STHub](http://www.smalltalkhub.com/#!/~TorstenBergmann/UDBC) 47 | This initial UDBC version of the SQLite3 binding (which is based on UFFI callouts) also included several new fixes and cleanups. 48 | 49 | [Esteban Maringolo](https://github.com/eMaringolo) worked in 2014/2015 on an updated Glorp port for Pharo which he wanted to base on Garage. Due to the unmaintained SQLite copy within Garage (it was still based on NativeBoost) Esteban switched Glorp to the maintained SQlite3 binding from Torsten and Pierce. 50 | 51 | To provide a working version to the community for Pharo 5 the [UDBC repo on SmalltalkHub](http://www.smalltalkhub.com/#!/~TorstenBergmann/UDBC/) was continuously used by the maintainers. 52 | 53 | Several new additions were done - most notably the [extension loading](https://www.samadhiweb.com/blog/2018.03.04.sqlite.ext.html) and multilingual support contributed by Pierce. 54 | 55 | ### Moving SQlite3 support to GitHub with Pharo 6 56 | 57 | While SmalltalkHub served several years as a hosting service for Pharo community projects - in Pharo 6 the versioning system was extended with Iceberg to be able to use git and modern code hosting services. Therefore the SQlite binding code was moved from SmalltalkHub to GitHub: Torsten made UDBC together with the included SQlite3 code available on [https://github.com/astares/Pharo-UDBC](https://github.com/astares/Pharo-UDBC) location. Pierce could directly commit into the repository - so both were able to keep maintaining the binding using git. 58 | 59 | [Pierce extended the library to now also handle multilingual table names](https://lists.pharo.org/pipermail/pharo-users_lists.pharo.org/2019-March/042722.html), column names and default column values; in other words, multilingual SQL statements. His contributions for the [I18N enhancement allowed to use SQLite in Pharo even more multilingual](https://www.samadhiweb.com/blog/2019.03.02.multilingual.sqlite.html). 60 | 61 | #### Glorp and Glorp SQLite on GitHub 62 | 63 | With Pharo 6 and 7 the Pharo community was step by step moving more projects to GitHub now - as it allows for better collaboration among the contributors. Beside the [central git repository for Pharo](https://github.com/pharo-project) itself two new community pages were created specific to the Pharo database support: 64 | 65 | - [https://github.com/pharo-rdbms](https://github.com/pharo-rdbms) - for Pharo community projects on relational database support 66 | - [https://github.com/pharo-nosql](https://github.com/pharo-nosql) - for Pharo community projects on NoSQL database support 67 | 68 | and several SQlite related projects are hosted there including Glorp: 69 | 70 | - [https://github.com/pharo-rdbms/glorp] - Glorp 71 | - [https://github.com/pharo-rdbms/glorp-sqlite3] - Glorp SQlite 3 binding 72 | 73 | #### Another independent fork 74 | 75 | In Mai 2019 [Julien Delpangue announced via Twitter](https://twitter.com/juldelplanque/status/1132670416852537344) created another custom fork also making several independent additions based on the original codebase. 76 | 77 | [Julien](https://github.com/juliendelplanque) made his personal fork available on [https://github.com/juliendelplanque/SQLite3](https://github.com/juliendelplanque/SQLite3) and invested time and energy on refactoring the project and providing a nice user documentation. 78 | 79 | Trying to prevent further forks on the SQlite3 library Torsten and Pierce contacted Julien to seek more alignment. The idea was to move the project forward as a real community project in the future where more maintainers can participate. 80 | 81 | ### Community owned, GitHub hosted SQLite3 project for Pharo 7 and 8 82 | 83 | In November 2019 the code was made available on GitHub in the community owned 84 | 85 | [https://github.com/pharo-rdbms/Pharo-SQLite3](https://github.com/pharo-rdbms/Pharo-SQLite3) 86 | 87 | repository. This version should be suitable for Pharo 7 and Pharo 8. 88 | 89 | Our hope this that maintainers could better coordinate and collaborate using the GitHub platform and the centralized community repo location. Special needs could be covered by own private GitHub forks while contributions could be sent in via pull requests to the community repository. Older repos were now marked as deprecated to avoid further confusion. 90 | 91 | ### Future 92 | 93 | It is planned to still revive and review some old code from the NB based version like [SQLCiphers](https://www.samadhiweb.com/blog/2015.12.24.sqlcipher.html) that did not yet make its way back to the codebase. If you want to help and contribute feel free to join. 94 | -------------------------------------------------------------------------------- /doc/migration.md: -------------------------------------------------------------------------------- 1 | # Update Guide 2 | 3 | ## Changes to previous SQlite versions 4 | 5 | - SQLite3Statement is now called SQlite3PreparedStatement 6 | - SQLite3ResultSet is now called SQliteCursor 7 | -------------------------------------------------------------------------------- /doc/starting_glorp.md: -------------------------------------------------------------------------------- 1 | # Starting with Glorp 2 | 3 | Load into Pharo using 4 | 5 | ``` 6 | Metacello new 7 | repository: 'github://pharo-rdbms/Pharo-SQLite3/src'; 8 | baseline: 'SQLite3'; 9 | load: #('glorp') 10 | ``` 11 | 12 | Set SQLite3 as the DefaultDriver 13 | 14 | ``` 15 | PharoDatabaseAccessor DefaultDriver: SQLite3Driver. 16 | ``` 17 | 18 | Create the database 19 | 20 | ``` 21 | connection := SQLite3Connection on: (Smalltalk imageDirectory / 'mydatabase.db') fullName. 22 | connection open. 23 | connection close. 24 | ``` 25 | 26 | Login to the database 27 | 28 | ``` 29 | login := Login new 30 | database: UDBCSQLite3Platform new; 31 | host: Smalltalk imageDirectory fullName; 32 | password:''; 33 | databaseName: 'mydatabase.db'; 34 | yourself. 35 | 36 | accessor := DatabaseAccessor forLogin: login. 37 | accessor login. 38 | ``` 39 | 40 | Test that its logged in 41 | 42 | ``` 43 | accessor isLoggedIn 44 | ``` 45 | -------------------------------------------------------------------------------- /scripts/install-SQLite3.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | sudo apt-get --assume-yes --no-install-recommends install sqlite3 4 | sqlite3 -version 5 | ln -s /usr/lib/x86_64-linux-gnu/libsqlite3.so.0 libsqlite3.so 6 | -------------------------------------------------------------------------------- /scripts/setupSQLite3AsDatabaseDriver.st: -------------------------------------------------------------------------------- 1 | DatabaseAccessor classForThisPlatform DefaultDriver: SQLite3Driver. 2 | GlorpDatabaseLoginResource defaultLogin: 3 | (Login new 4 | database: UDBCSQLite3Platform new; 5 | host: SmalltalkImage current imageDirectory fullName; 6 | databaseName: 'sodbxtestu.db'; 7 | password: ''; 8 | yourself). 9 | -------------------------------------------------------------------------------- /src/.properties: -------------------------------------------------------------------------------- 1 | { 2 | #format : #tonel 3 | } -------------------------------------------------------------------------------- /src/BaselineOfSQLite3/BaselineOfSQLite3.class.st: -------------------------------------------------------------------------------- 1 | " 2 | A baseline for SQlite3 support in Pharo 3 | " 4 | Class { 5 | #name : #BaselineOfSQLite3, 6 | #superclass : #BaselineOf, 7 | #category : #BaselineOfSQLite3 8 | } 9 | 10 | { #category : #baselines } 11 | BaselineOfSQLite3 >> baseline: spec [ 12 | 13 | 14 | spec 15 | for: #pharo 16 | do: [ 17 | self setUpDependencies: spec. 18 | spec 19 | package: 'SQLite3-Core'; 20 | group: 'Core' with: 'SQLite3-Core'; 21 | 22 | package: 'SQLite3-Core-Benchmarks' with: [ spec requires: 'SQLite3-Core' ]; 23 | group: 'Benchmarks' with: 'SQLite3-Core-Benchmarks'; 24 | 25 | package: 'SQLite3-Core-Tests' with: [ spec requires: 'Core' ]; 26 | group: 'Tests' with: 'SQLite3-Core-Tests'; 27 | 28 | package: 'SQLite3-Glorp' with: [ spec requires: #('Core' 'Glorp-Core') ]; 29 | group: 'glorp' with: 'SQLite3-Glorp'; 30 | 31 | package: 'SQLite3-Glorp-Tests' with: [ spec requires: #('SQLite3-Glorp' 'Glorp-Tests') ]; 32 | group: 'Tools' with: #(). 33 | 34 | spec 35 | group: 'CI' with: #('SQLite3-Glorp-Tests' 'Tests'); 36 | group: 'all' with: #('Core' 'Tests' 'Benchmarks' 'Tools'); 37 | group: 'default' with: #('all') 38 | ]. 39 | self versionSpecificBaseline: spec. 40 | ] 41 | 42 | { #category : #baselines } 43 | BaselineOfSQLite3 >> projectClass [ 44 | 45 | ^ MetacelloCypressBaselineProject 46 | ] 47 | 48 | { #category : #baselines } 49 | BaselineOfSQLite3 >> setUpDependencies: spec [ 50 | 51 | spec 52 | baseline: 'Glorp' with: [ spec repository: 'github://pharo-rdbms/glorp/' ]; 53 | project: 'Glorp-Core' copyFrom: 'Glorp' with: [ spec loads: 'Core' ]; 54 | project: 'Glorp-Tests' copyFrom: 'Glorp' with: [ spec loads: 'Glorp-Integration-Tests' ] 55 | ] 56 | 57 | { #category : #baselines } 58 | BaselineOfSQLite3 >> versionSpecificBaseline: spec [ 59 | 60 | "Add version specific packages to the spec" 61 | 62 | spec for: #( #'pharo7.x' #'pharo8.x' ) do: [ 63 | spec 64 | package: 'SQLite3-Pharo8'; 65 | group: 'Core' with: 'SQLite3-Pharo8' 66 | ]. 67 | 68 | spec for: #( #'pharo9.x' #'pharo10.x' #'pharo11.x' #'pharo12.x' ) do: [ 69 | spec 70 | package: 'SQLite3-Pharo9'; 71 | group: 'Core' with: 'SQLite3-Pharo9' 72 | ]. 73 | 74 | spec for: #( #'pharo10.x' #'pharo11.x' #'pharo12.x' ) do: [ 75 | spec 76 | package: 'SQLite3-Pharo10'; 77 | group: 'Core' with: 'SQLite3-Pharo10'. 78 | 79 | spec 80 | package: 'SQLite3-Inspector-Extensions' with: [ spec requires: #( 'Core' ) ]; 81 | group: 'Tools' with: 'SQLite3-Inspector-Extensions' 82 | ] 83 | ] 84 | -------------------------------------------------------------------------------- /src/BaselineOfSQLite3/package.st: -------------------------------------------------------------------------------- 1 | Package { #name : #BaselineOfSQLite3 } 2 | -------------------------------------------------------------------------------- /src/SQLite3-Core-Benchmarks/ManifestSQLite3CoreBenchmarks.class.st: -------------------------------------------------------------------------------- 1 | " 2 | Please describe the package using the class comment of the included manifest class. The manifest class also includes other additional metadata for the package. These meta data are used by other tools such as the SmalllintManifestChecker and the critics Browser 3 | " 4 | Class { 5 | #name : #ManifestSQLite3CoreBenchmarks, 6 | #superclass : #PackageManifest, 7 | #category : #'SQLite3-Core-Benchmarks-Manifest' 8 | } 9 | 10 | { #category : #'code coverage' } 11 | ManifestSQLite3CoreBenchmarks class >> classNamesNotUnderTest [ 12 | 13 | ^ #( ManifestSQLite3CoreBenchmarks ) 14 | ] 15 | 16 | { #category : #'code-critics' } 17 | ManifestSQLite3CoreBenchmarks class >> ruleClassNotReferencedRuleV1FalsePositive [ 18 | ^ #(#(#(#RGClassDefinition #(#SQLite3Benchmark)) #'2022-05-10T08:25:40.035+02:00') ) 19 | ] 20 | -------------------------------------------------------------------------------- /src/SQLite3-Core-Benchmarks/SQLite3Benchmark.class.st: -------------------------------------------------------------------------------- 1 | " 2 | Benchmarking harness. 3 | " 4 | Class { 5 | #name : #SQLite3Benchmark, 6 | #superclass : #Object, 7 | #instVars : [ 8 | 'db', 9 | 'stmt' 10 | ], 11 | #category : #'SQLite3-Core-Benchmarks-Benchmarking' 12 | } 13 | 14 | { #category : #running } 15 | SQLite3Benchmark >> basicExecute: anSQLText times: aCount [ 16 | 17 | db beginTransaction. 18 | 1 to: aCount do: [ :i | 19 | db basicExecute: anSQLText ]. 20 | db commitTransaction 21 | ] 22 | 23 | { #category : #'connecting-disconnecting' } 24 | SQLite3Benchmark >> connectBy: aConnectionClass [ 25 | db := aConnectionClass openOn: ':memory:' 26 | ] 27 | 28 | { #category : #'connecting-disconnecting' } 29 | SQLite3Benchmark >> disconnect [ 30 | db close 31 | ] 32 | 33 | { #category : #running } 34 | SQLite3Benchmark >> execute: anSQLText times: aCount bindingsBlock: bindingsBlock [ 35 | 36 | db beginTransaction. 37 | 1 to: aCount do: [ :i | 38 | db execute: anSQLText with: (bindingsBlock value: i) ]. 39 | db commitTransaction 40 | ] 41 | 42 | { #category : #running } 43 | SQLite3Benchmark >> finalizeStatement [ 44 | stmt ifNotNil: [ stmt finalize ] 45 | ] 46 | 47 | { #category : #running } 48 | SQLite3Benchmark >> prepStep: anSQLText times: aCount bindingsBlock: bindingsBlock [ 49 | 50 | stmt := db prepare: anSQLText. 51 | db beginTransaction. 52 | 1 to: aCount do: [ :i | 53 | bindingsBlock value: stmt value: i. 54 | stmt step; clearBindings; reset ]. 55 | db commitTransaction 56 | ] 57 | 58 | { #category : #running } 59 | SQLite3Benchmark >> runBlock: aBlock [ 60 | 61 | db beginTransaction. 62 | aBlock value: db. 63 | db commitTransaction 64 | ] 65 | -------------------------------------------------------------------------------- /src/SQLite3-Core-Benchmarks/package.st: -------------------------------------------------------------------------------- 1 | Package { #name : #'SQLite3-Core-Benchmarks' } 2 | -------------------------------------------------------------------------------- /src/SQLite3-Core-Tests/ManifestSQLite3CoreTests.class.st: -------------------------------------------------------------------------------- 1 | " 2 | Please describe the package using the class comment of the included manifest class. The manifest class also includes other additional metadata for the package. These meta data are used by other tools such as the SmalllintManifestChecker and the critics Browser 3 | " 4 | Class { 5 | #name : #ManifestSQLite3CoreTests, 6 | #superclass : #PackageManifest, 7 | #category : 'SQLite3-Core-Tests-Manifest' 8 | } 9 | 10 | { #category : #'code coverage' } 11 | ManifestSQLite3CoreTests class >> classNamesNotUnderTest [ 12 | 13 | ^ #( ManifestSQLite3CoreTests ) 14 | ] 15 | 16 | { #category : #'code-critics' } 17 | ManifestSQLite3CoreTests class >> ruleEmptyExceptionHandlerRuleV1FalsePositive [ 18 | ^ #(#(#(#RGMethodDefinition #(#SQLite3ConnectionTest #tearDown #false)) #'2022-05-10T08:25:11.111+02:00') #(#(#RGMethodDefinition #(#SQLite3BaseConnectionTest #tearDown #false)) #'2022-05-10T08:27:13.419+02:00') ) 19 | ] 20 | 21 | { #category : #'code-critics' } 22 | ManifestSQLite3CoreTests class >> ruleLiteralArrayContainsCommaRuleV1FalsePositive [ 23 | ^ #(#(#(#RGMethodDefinition #(#SQLite3BaseConnectionTest #deactivatedTestTracing #false)) #'2022-05-10T08:24:31.021+02:00') ) 24 | ] 25 | 26 | { #category : #'code-critics' } 27 | ManifestSQLite3CoreTests class >> ruleLiteralArrayContainsSuspiciousTrueFalseOrNilRuleV1FalsePositive [ 28 | ^ #(#(#(#RGMetaclassDefinition #(#'ManifestSQLite3CoreTests class' #ManifestSQLite3CoreTests)) #'2022-05-10T08:26:37.973+02:00') ) 29 | ] 30 | -------------------------------------------------------------------------------- /src/SQLite3-Core-Tests/SQLite3ColumnTest.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : #SQLite3ColumnTest, 3 | #superclass : #TestCase, 4 | #instVars : [ 5 | 'db', 6 | 'table', 7 | 'firstColumn', 8 | 'secondColumn' 9 | ], 10 | #category : 'SQLite3-Core-Tests-Base' 11 | } 12 | 13 | { #category : #running } 14 | SQLite3ColumnTest >> setUp [ 15 | super setUp. 16 | db := SQLite3Database memory. 17 | db connection open. 18 | db connection execute: self tableCreationScript. 19 | table := db tables first. 20 | firstColumn := table columns first. 21 | secondColumn := table columns second 22 | ] 23 | 24 | { #category : #accessing } 25 | SQLite3ColumnTest >> tableCreationScript [ 26 | 27 | ^'CREATE TABLE "SAMPLE" 28 | ( 29 | [ID] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 30 | [NAME] NVARCHAR(120) 31 | )' 32 | ] 33 | 34 | { #category : #running } 35 | SQLite3ColumnTest >> tearDown [ 36 | 37 | db connection close. 38 | db := nil. 39 | super tearDown 40 | ] 41 | 42 | { #category : #tests } 43 | SQLite3ColumnTest >> testHasNotNullConstraint [ 44 | 45 | self assert: firstColumn hasNotNullConstraint. 46 | self deny: secondColumn hasNotNullConstraint 47 | ] 48 | 49 | { #category : #tests } 50 | SQLite3ColumnTest >> testIndex [ 51 | 52 | self assert: firstColumn index equals: 0. 53 | self assert: secondColumn index equals: 1 54 | ] 55 | 56 | { #category : #tests } 57 | SQLite3ColumnTest >> testInitialization [ 58 | 59 | | instance | 60 | instance := SQLite3Column new. 61 | self deny: instance hasNotNullConstraint 62 | ] 63 | 64 | { #category : #tests } 65 | SQLite3ColumnTest >> testName [ 66 | 67 | self assert: firstColumn name equals: 'ID'. 68 | self assert: secondColumn name equals: 'NAME' 69 | ] 70 | 71 | { #category : #tests } 72 | SQLite3ColumnTest >> testPrintString [ 73 | 74 | self assert: firstColumn printString equals: 'a SQLite3Column("ID")'. 75 | self assert: secondColumn printString equals: 'a SQLite3Column("NAME")' 76 | ] 77 | 78 | { #category : #tests } 79 | SQLite3ColumnTest >> testType [ 80 | 81 | self assert: firstColumn type equals: 'INTEGER'. 82 | self assert: secondColumn type equals: 'NVARCHAR(120)' 83 | ] 84 | -------------------------------------------------------------------------------- /src/SQLite3-Core-Tests/SQLite3DatabaseTest.class.st: -------------------------------------------------------------------------------- 1 | " 2 | A test class for `SQLite3Database` 3 | " 4 | Class { 5 | #name : #SQLite3DatabaseTest, 6 | #superclass : #TestCase, 7 | #category : 'SQLite3-Core-Tests-Base' 8 | } 9 | 10 | { #category : #tests } 11 | SQLite3DatabaseTest >> testPrintString [ 12 | 13 | self assert: SQLite3Database memory printString equals: 'a SQLite3Database(":memory:")' 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core-Tests/SQLite3RowTest.class.st: -------------------------------------------------------------------------------- 1 | " 2 | Unit tests for SQLite3Row 3 | " 4 | Class { 5 | #name : #SQLite3RowTest, 6 | #superclass : #TestCase, 7 | #instVars : [ 8 | 'filledRow', 9 | 'emptyRow' 10 | ], 11 | #category : 'SQLite3-Core-Tests-Database' 12 | } 13 | 14 | { #category : #running } 15 | SQLite3RowTest >> setUp [ 16 | super setUp. 17 | emptyRow := SQLite3Row new. 18 | filledRow := SQLite3Row new columnNames: {'foo'. 'bar'. 'pi'}; yourself. 19 | filledRow 20 | at: 'foo' put: 1; 21 | at: 'bar' put: true; 22 | at: 'pi' put: '3.14' 23 | ] 24 | 25 | { #category : #tests } 26 | SQLite3RowTest >> testAsArray [ 27 | 28 | self assert: emptyRow asArray equals: #(). 29 | self assert: filledRow asArray equals: #(1 true '3.14') 30 | ] 31 | 32 | { #category : #tests } 33 | SQLite3RowTest >> testAsCombinedDictionary [ 34 | | dict | 35 | dict := Dictionary new. 36 | dict at: 'foo' put: 1. 37 | dict at: 'bar' put: true. 38 | dict at: 'pi' put: '3.14'. 39 | dict at: 1 put: 1. 40 | dict at: 2 put: true. 41 | dict at: 3 put: '3.14'. 42 | self assert: emptyRow asCombinedDictionary equals: Dictionary new. 43 | self assert: filledRow asCombinedDictionary equals: dict 44 | ] 45 | 46 | { #category : #tests } 47 | SQLite3RowTest >> testAsDictionary [ 48 | | dict | 49 | dict := Dictionary new. 50 | dict at: 'foo' put: 1. 51 | dict at: 'bar' put: true. 52 | dict at: 'pi' put: '3.14'. 53 | 54 | self assert: emptyRow asDictionary equals: Dictionary new. 55 | self assert: filledRow asDictionary equals: dict 56 | ] 57 | 58 | { #category : #tests } 59 | SQLite3RowTest >> testColumnAccessingIfAbsent [ 60 | |blockExecutedFlag| 61 | blockExecutedFlag := false. 62 | 63 | filledRow at: 'foo' ifAbsent: [ blockExecutedFlag := true ]. 64 | 65 | self deny: blockExecutedFlag. 66 | 67 | filledRow at: 'nope' ifAbsent: [ blockExecutedFlag := true ]. 68 | 69 | self assert: blockExecutedFlag 70 | ] 71 | 72 | { #category : #tests } 73 | SQLite3RowTest >> testColumnAccessingOnEmptyRow [ 74 | 75 | self assert: (emptyRow at: 'foo') equals: nil 76 | ] 77 | 78 | { #category : #tests } 79 | SQLite3RowTest >> testColumnAccessingOnFilledRow [ 80 | 81 | self assert: (filledRow at: 'foo') equals: 1. 82 | self assert: (filledRow at: 'bar') equals: true. 83 | self assert: (filledRow at: 'pi') equals: '3.14'. 84 | 85 | self assert: (filledRow at: 'nope') equals: nil 86 | ] 87 | 88 | { #category : #tests } 89 | SQLite3RowTest >> testColumnNamesOnEmptyRow [ 90 | 91 | self assert: emptyRow columnNames equals: #() 92 | ] 93 | 94 | { #category : #tests } 95 | SQLite3RowTest >> testColumnNamesOnFilledRow [ 96 | 97 | self assert: filledRow columnNames equals: #('foo' 'bar' 'pi') 98 | ] 99 | 100 | { #category : #tests } 101 | SQLite3RowTest >> testColumnPuttingOnEmptyRow [ 102 | 103 | self assert: (emptyRow at: 'foo') equals: nil. 104 | 105 | emptyRow at: 'foo' put: 42. 106 | 107 | self assert: (emptyRow at: 'foo') equals: 42 108 | ] 109 | 110 | { #category : #tests } 111 | SQLite3RowTest >> testColumnPuttingOnFilledRow [ 112 | 113 | self assert: (filledRow at: 'foo') equals: 1. 114 | 115 | filledRow at: 'foo' put: 2. 116 | 117 | self assert: (filledRow at: 'foo') equals: 2 118 | ] 119 | -------------------------------------------------------------------------------- /src/SQLite3-Core-Tests/SQLite3TableBasedTest.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : #SQLite3TableBasedTest, 3 | #superclass : #TestCase, 4 | #instVars : [ 5 | 'db', 6 | 'table' 7 | ], 8 | #category : #'SQLite3-Core-Tests-Base' 9 | } 10 | 11 | { #category : #testing } 12 | SQLite3TableBasedTest class >> isAbstract [ 13 | 14 | ^ self == SQLite3TableBasedTest 15 | ] 16 | 17 | { #category : #running } 18 | SQLite3TableBasedTest >> setUp [ 19 | super setUp. 20 | db := SQLite3Database memory. 21 | db connection open. 22 | db connection execute: self tableCreationScript. 23 | table := db tables first 24 | ] 25 | 26 | { #category : #accessing } 27 | SQLite3TableBasedTest >> tableCreationScript [ 28 | 29 | ^ self subclassResponsibility 30 | ] 31 | 32 | { #category : #running } 33 | SQLite3TableBasedTest >> tearDown [ 34 | db connection close. 35 | db := nil. 36 | super tearDown 37 | ] 38 | 39 | { #category : #'tests - sample' } 40 | SQLite3TableBasedTest >> testSampleTableSchema [ 41 | 42 | self assert: table schema equals: self tableCreationScript 43 | ] 44 | -------------------------------------------------------------------------------- /src/SQLite3-Core-Tests/SQLite3TableTest.class.st: -------------------------------------------------------------------------------- 1 | " 2 | A test class for `SQLite3Table` 3 | " 4 | Class { 5 | #name : #SQLite3TableTest, 6 | #superclass : #SQLite3TableBasedTest, 7 | #category : #'SQLite3-Core-Tests-Base' 8 | } 9 | 10 | { #category : #accessing } 11 | SQLite3TableTest >> tableCreationScript [ 12 | 13 | ^'CREATE TABLE "SAMPLE" 14 | ( 15 | [ID] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 16 | [NAME] NVARCHAR(120) 17 | )' 18 | ] 19 | 20 | { #category : #tests } 21 | SQLite3TableTest >> testName [ 22 | 23 | | properties instance | 24 | properties := Dictionary newFromPairs: #( #name 'SimpleTable' ). 25 | instance := SQLite3Table properties: properties in: nil. 26 | self assert: instance name equals: 'SimpleTable' 27 | ] 28 | 29 | { #category : #'tests - sample' } 30 | SQLite3TableTest >> testNumberOfRows [ 31 | 32 | self assert: table numberOfRows equals: 0 33 | ] 34 | 35 | { #category : #'tests - sample' } 36 | SQLite3TableTest >> testNumberOfRowsIsOne [ 37 | 38 | db execute: 'INSERT INTO SAMPLE(NAME) VALUES (''first example'');'. 39 | 40 | self assert: table numberOfRows equals: 1 41 | ] 42 | 43 | { #category : #'tests - sample' } 44 | SQLite3TableTest >> testNumberOfRowsIsTwo [ 45 | 46 | db execute: 'INSERT INTO SAMPLE(NAME) VALUES (''first example''), (''second example'');'. 47 | 48 | self assert: table numberOfRows equals: 2 49 | ] 50 | 51 | { #category : #tests } 52 | SQLite3TableTest >> testPrintString [ 53 | 54 | self assert: table printString equals: 'a SQLite3Table("SAMPLE")' 55 | ] 56 | 57 | { #category : #'tests - sample' } 58 | SQLite3TableTest >> testRows [ 59 | 60 | self assert: table rows isEmpty 61 | ] 62 | 63 | { #category : #'tests - sample' } 64 | SQLite3TableTest >> testRowsHasOneRow [ 65 | 66 | | rows | 67 | db execute: 'INSERT INTO SAMPLE(NAME) VALUES (''first example'');'. 68 | rows := table rows. 69 | self deny: rows isEmpty. 70 | self assert: rows size equals: 1. 71 | self assert: (rows first at: 'NAME') equals: 'first example' 72 | ] 73 | 74 | { #category : #'tests - sample' } 75 | SQLite3TableTest >> testRowsHasTwoRows [ 76 | 77 | | rows | 78 | db execute: 79 | 'INSERT INTO SAMPLE(NAME) VALUES (''first example''), (''second example'');'. 80 | rows := table rows. 81 | self deny: rows isEmpty. 82 | self assert: rows size equals: 2. 83 | self assert: (rows first at: 'NAME') equals: 'first example'. 84 | self assert: (rows second at: 'NAME') equals: 'second example' 85 | ] 86 | 87 | { #category : #'tests - sample' } 88 | SQLite3TableTest >> testSampleTable [ 89 | 90 | self assert: table name equals: 'SAMPLE' 91 | ] 92 | 93 | { #category : #'tests - sample' } 94 | SQLite3TableTest >> testSampleTableColumnNames [ 95 | 96 | self assert: table columnNames size equals: 2 97 | ] 98 | 99 | { #category : #'tests - sample' } 100 | SQLite3TableTest >> testSampleTableColumns [ 101 | 102 | self assert: table columns size equals: 2 103 | ] 104 | 105 | { #category : #'tests - sample' } 106 | SQLite3TableTest >> testSampleTableProperties [ 107 | |props| 108 | props := table properties. 109 | self assert: props size equals: 5. 110 | 111 | self assert: (props at: #type) equals: 'table'. 112 | self assert: (props at: #tbl_name) equals: 'SAMPLE'. 113 | self assert: (props at: #rootpage) equals: 2. 114 | self assert: (props at: #name) equals: 'SAMPLE'. 115 | self assert: (props at: #sql) equals: self tableCreationScript 116 | ] 117 | 118 | { #category : #tests } 119 | SQLite3TableTest >> testUnitializedName [ 120 | 121 | self assert: SQLite3Table new name equals: '' 122 | ] 123 | -------------------------------------------------------------------------------- /src/SQLite3-Core-Tests/SQLite3TableWithSpacesTest.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : #SQLite3TableWithSpacesTest, 3 | #superclass : #SQLite3TableBasedTest, 4 | #category : #'SQLite3-Core-Tests-Base' 5 | } 6 | 7 | { #category : #accessing } 8 | SQLite3TableWithSpacesTest >> tableCreationScript [ 9 | 10 | ^'CREATE TABLE "ANOTHER TABLE" 11 | ( 12 | [ID] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 13 | [SOME NAME] NVARCHAR(120) 14 | )' 15 | ] 16 | 17 | { #category : #tests } 18 | SQLite3TableWithSpacesTest >> testColumnNameHasSpace [ 19 | 20 | self assert: table columnNames size equals: 2. 21 | self assert: table columnNames second equals: 'SOME NAME' 22 | ] 23 | 24 | { #category : #tests } 25 | SQLite3TableWithSpacesTest >> testPrintStringHasTableNameWithSpace [ 26 | 27 | self assert: table printString equals: 'a SQLite3Table("ANOTHER TABLE")' 28 | ] 29 | -------------------------------------------------------------------------------- /src/SQLite3-Core-Tests/package.st: -------------------------------------------------------------------------------- 1 | Package { #name : #'SQLite3-Core-Tests' } 2 | -------------------------------------------------------------------------------- /src/SQLite3-Core/FFIExternalReference.extension.st: -------------------------------------------------------------------------------- 1 | Extension { #name : #FFIExternalReference } 2 | 3 | { #category : #'*SQLite3-Core' } 4 | FFIExternalReference >> manualRelease [ 5 | FFIExternalResourceManager uniqueInstance removeResource: self 6 | ] 7 | -------------------------------------------------------------------------------- /src/SQLite3-Core/FFIExternalResourceManager.extension.st: -------------------------------------------------------------------------------- 1 | Extension { #name : #FFIExternalResourceManager } 2 | 3 | { #category : #'*SQLite3-Core' } 4 | FFIExternalResourceManager >> removeResource: anObject [ 5 | registry remove: anObject ifAbsent: [ ] 6 | ] 7 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3Abort.class.st: -------------------------------------------------------------------------------- 1 | " 2 | This class comment was automatically generated from https://www.sqlite.org/rescode.html 3 | 4 | The SQLITE_ABORT result code indicates that an operation was aborted prior to completion, usually be application request. See also: SQLITE_INTERRUPT. 5 | 6 | If the callback function to sqlite3_exec() returns non-zero, then sqlite3_exec() will return SQLITE_ABORT. 7 | 8 | If a ROLLBACK operation occurs on the same database connection as a pending read or write, then the pending read or write may fail with an SQLITE_ABORT or SQLITE_ABORT_ROLLBACK error. 9 | 10 | In addition to being a result code, the SQLITE_ABORT value is also used as a conflict resolution mode returned from the sqlite3_vtab_on_conflict() interface. 11 | " 12 | Class { 13 | #name : #SQLite3Abort, 14 | #superclass : #SQLite3NativeError, 15 | #category : #'SQLite3-Core-Errors' 16 | } 17 | 18 | { #category : #'private - accessing' } 19 | SQLite3Abort class >> nativeErrorCode [ 20 | 21 | ^ SQLITE_ABORT 22 | ] 23 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3AbortRollback.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_ABORT_ROLLBACK error code is an extended error code for SQLITE_ABORT indicating that an SQL statement aborted because the transaction that was active when the SQL statement first started was rolled back. Pending write operations always fail with this error when a rollback occurs. A ROLLBACK will cause a pending read operation to fail only if the schema was changed within the transaction being rolled back. 3 | " 4 | Class { 5 | #name : #SQLite3AbortRollback, 6 | #superclass : #SQLite3Abort, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3AbortRollback class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_ABORT_ROLLBACK 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3AbstractError.class.st: -------------------------------------------------------------------------------- 1 | " 2 | I represent an SQLite non-ok condition. 3 | " 4 | Class { 5 | #name : #SQLite3AbstractError, 6 | #superclass : #Error, 7 | #instVars : [ 8 | 'resultCode' 9 | ], 10 | #category : #'SQLite3-Core-Errors' 11 | } 12 | 13 | { #category : #testing } 14 | SQLite3AbstractError class >> isAbstract [ 15 | 16 | ^self name = #SQLite3AbstractError 17 | ] 18 | 19 | { #category : #accessing } 20 | SQLite3AbstractError >> resultCode [ 21 | ^ resultCode 22 | ] 23 | 24 | { #category : #accessing } 25 | SQLite3AbstractError >> resultCode: anObject [ 26 | resultCode := anObject 27 | ] 28 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3AuthorizationDenied.class.st: -------------------------------------------------------------------------------- 1 | " 2 | This class comment was automatically generated from https://www.sqlite.org/rescode.html 3 | 4 | The SQLITE_AUTH error is returned when the authorizer callback indicates that an SQL statement being prepared is not authorized. 5 | " 6 | Class { 7 | #name : #SQLite3AuthorizationDenied, 8 | #superclass : #SQLite3NativeError, 9 | #category : #'SQLite3-Core-Errors' 10 | } 11 | 12 | { #category : #'private - accessing' } 13 | SQLite3AuthorizationDenied class >> nativeErrorCode [ 14 | 15 | ^ SQLITE_AUTH 16 | ] 17 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3Backup.class.st: -------------------------------------------------------------------------------- 1 | " 2 | I represent a SQLite backup operation. 3 | 4 | This is detailed at https://sqlite.org/c3ref/backup_finish.html#sqlite3backupinit 5 | " 6 | Class { 7 | #name : #SQLite3Backup, 8 | #superclass : #Object, 9 | #instVars : [ 10 | 'library', 11 | 'srcConnection', 12 | 'srcName', 13 | 'dstConnection', 14 | 'dstName', 15 | 'isOpen', 16 | 'handle' 17 | ], 18 | #category : #'SQLite3-Core-Utilities' 19 | } 20 | 21 | { #category : #creating } 22 | SQLite3Backup class >> to: dConnection named: dName from: sConnection named: sName [ 23 | ^(self new) 24 | dstConnection: dConnection; 25 | dstName: dName; 26 | srcConnection: sConnection; 27 | srcName: sName 28 | ] 29 | 30 | { #category : #accessing } 31 | SQLite3Backup >> dstConnection [ 32 | ^ dstConnection 33 | ] 34 | 35 | { #category : #accessing } 36 | SQLite3Backup >> dstConnection: anObject [ 37 | dstConnection := anObject 38 | ] 39 | 40 | { #category : #accessing } 41 | SQLite3Backup >> dstName [ 42 | ^ dstName 43 | ] 44 | 45 | { #category : #accessing } 46 | SQLite3Backup >> dstName: anObject [ 47 | dstName := anObject 48 | ] 49 | 50 | { #category : #finalization } 51 | SQLite3Backup >> finalize [ 52 | self finish 53 | ] 54 | 55 | { #category : #initialization } 56 | SQLite3Backup >> finish [ 57 | handle 58 | ifNotNil: [ 59 | library apiBackupFinish: handle. 60 | handle beNull. 61 | handle := nil] 62 | ] 63 | 64 | { #category : #accessing } 65 | SQLite3Backup >> handle [ 66 | ^ handle 67 | ] 68 | 69 | { #category : #accessing } 70 | SQLite3Backup >> handle: anObject [ 71 | handle := anObject 72 | ] 73 | 74 | { #category : #initialization } 75 | SQLite3Backup >> initialize [ 76 | super initialize. 77 | isOpen := false. 78 | library := SQLite3Library current. 79 | handle := SQLite3DatabaseExternalObject new. 80 | handle autoRelease 81 | ] 82 | 83 | { #category : #accessing } 84 | SQLite3Backup >> isOpen [ 85 | ^ isOpen 86 | ] 87 | 88 | { #category : #accessing } 89 | SQLite3Backup >> open [ 90 | handle := (library backupTo: dstConnection named: dstName from: srcConnection named: srcName). 91 | isOpen := true 92 | ] 93 | 94 | { #category : #accessing } 95 | SQLite3Backup >> srcConnection [ 96 | ^ srcConnection 97 | ] 98 | 99 | { #category : #accessing } 100 | SQLite3Backup >> srcConnection: anObject [ 101 | srcConnection := anObject 102 | ] 103 | 104 | { #category : #accessing } 105 | SQLite3Backup >> srcName [ 106 | ^ srcName 107 | ] 108 | 109 | { #category : #accessing } 110 | SQLite3Backup >> srcName: anObject [ 111 | srcName := anObject 112 | ] 113 | 114 | { #category : #accessing } 115 | SQLite3Backup >> step [ 116 | "Passing negative number means run to completion" 117 | self step: -1 118 | ] 119 | 120 | { #category : #accessing } 121 | SQLite3Backup >> step: nPages [ 122 | 123 | library backup: handle step: nPages 124 | ] 125 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3BackupExternalReference.class.st: -------------------------------------------------------------------------------- 1 | " 2 | I represent the SQLite API 'sqlite3_backup' C-level type. 3 | " 4 | Class { 5 | #name : #SQLite3BackupExternalReference, 6 | #superclass : #FFIOpaqueObject, 7 | #category : #'SQLite3-Core-UFFI-Support' 8 | } 9 | 10 | { #category : #initialization } 11 | SQLite3BackupExternalReference >> beNull [ 12 | 13 | ^ handle beNull 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3BaseConnection.class.st: -------------------------------------------------------------------------------- 1 | " 2 | I represent a connection to an SQLite database. I provide a thin wrapper over the SQLite C API. 3 | 4 | Do not use this class directly, please check and use my subclass SQLite3Connection 5 | " 6 | Class { 7 | #name : #SQLite3BaseConnection, 8 | #superclass : #Object, 9 | #instVars : [ 10 | 'dbFilename', 11 | 'dbHandle', 12 | 'isOpen', 13 | 'library', 14 | 'statementClass' 15 | ], 16 | #category : #'SQLite3-Core-Connections' 17 | } 18 | 19 | { #category : #testing } 20 | SQLite3BaseConnection class >> isAbstract [ 21 | 22 | ^ self == SQLite3BaseConnection 23 | ] 24 | 25 | { #category : #testing } 26 | SQLite3BaseConnection class >> isThreadsafe [ 27 | "Native Library Version http://sqlite.org/c3ref/libversion.html sqlite3_libversion" 28 | 29 | ^ SQLite3Library current isThreadsafe ~= 0 30 | ] 31 | 32 | { #category : #accessing } 33 | SQLite3BaseConnection class >> libraryVersion [ 34 | "Native Library Version http://sqlite.org/c3ref/libversion.html sqlite3_libversion" 35 | 36 | ^ SQLite3Library current libraryVersion 37 | ] 38 | 39 | { #category : #examples } 40 | SQLite3BaseConnection class >> memory [ 41 | 42 | ^ self on: ':memory:' 43 | ] 44 | 45 | { #category : #'instance creation' } 46 | SQLite3BaseConnection class >> on: aFilename [ 47 | 48 | ^(self new) 49 | on: aFilename; 50 | yourself 51 | ] 52 | 53 | { #category : #'instance creation' } 54 | SQLite3BaseConnection class >> openOn: aFilename [ 55 | 56 | ^(self new) 57 | on: aFilename; 58 | open; 59 | yourself 60 | ] 61 | 62 | { #category : #testing } 63 | SQLite3BaseConnection class >> threadsafe [ 64 | "This method is deprecated so consider to migrate." 65 | self deprecated: 'Please use #isThreadsafe instead' transformWith: '`@receiver threadsafe' 66 | -> '`@receiver isThreadsafe'. 67 | 68 | ^ self isThreadsafe 69 | ] 70 | 71 | { #category : #'public API - backups' } 72 | SQLite3BaseConnection >> backupDatabaseNamed: sName to: aConnection named: dName [ 73 | "database name is either 'main' or 'temp' or the name given to ATTACH DATABASE 74 | See article at https://www.oreilly.com/library/view/using-sqlite/9781449394592/re225.html" 75 | ^SQLite3Backup to: aConnection handle named: dName from: dbHandle named: sName 76 | ] 77 | 78 | { #category : #'public API - backups' } 79 | SQLite3BaseConnection >> backupTo: aConnection [ 80 | 81 | ^self backupTo: aConnection named: 'main' 82 | ] 83 | 84 | { #category : #'public API - backups' } 85 | SQLite3BaseConnection >> backupTo: aConnection named: aName [ 86 | 87 | ^SQLite3Backup to: aConnection handle named: aName from: dbHandle named: 'main' 88 | ] 89 | 90 | { #category : #'public API - operating' } 91 | SQLite3BaseConnection >> basicExecute: anSQLText [ 92 | ^ (self prepare: anSQLText) step; finalize 93 | 94 | "20190302, pierce: This used to invoke sqlite3_exec() which is an SQLite-internal convenience wrapper around prepare/step/finalize. It is now rewritten as seen to handle UTF8-encoded input properly. Rewriting this method breaks the Bobby Tables test which relies on naive SQL string construction to work." 95 | ] 96 | 97 | { #category : #'public API - transactional' } 98 | SQLite3BaseConnection >> beginTransaction [ 99 | ^ self basicExecute: 'begin' 100 | ] 101 | 102 | { #category : #'public API - introspection' } 103 | SQLite3BaseConnection >> changes [ 104 | ^ library changes: dbHandle 105 | ] 106 | 107 | { #category : #'public API - operating' } 108 | SQLite3BaseConnection >> clearBindings: aStatement [ 109 | library clearBindings: aStatement handle on: dbHandle 110 | ] 111 | 112 | { #category : #'public API - open/close' } 113 | SQLite3BaseConnection >> close [ 114 | "Do the minimal work to close the connection. Let FFIExternalResourceManager take care of calling sqlite_close_v2()." 115 | 116 | dbHandle ifNil: [ ^ self ]. 117 | "Set dbHandle to nil to allow its garbage collection. 118 | The underlying handle should not be switched to NULL here, SQLite3DatabaseExternalObject class>>doFinalizeResourceData: will take care of that" 119 | dbHandle := nil. 120 | isOpen := false 121 | ] 122 | 123 | { #category : #'public API - introspection' } 124 | SQLite3BaseConnection >> columnNamesFor: aTableName [ 125 | 126 | self isOpen 127 | ifFalse: [ SQLite3NotOpen signal ] 128 | ifTrue: [ 129 | ^ (self existTableNamed: aTableName) 130 | ifTrue: [ 131 | | columns s | 132 | columns := OrderedCollection new. 133 | s := self prepare: 'pragma table_info([' , aTableName , '])'. 134 | s basicExecute: [ :row | columns add: (row stringAt: 1) ]. 135 | s finalize. 136 | columns ] 137 | ifFalse: [ nil ] ] 138 | ] 139 | 140 | { #category : #'public API - transactional' } 141 | SQLite3BaseConnection >> commitTransaction [ 142 | ^ self basicExecute: 'commit' 143 | ] 144 | 145 | { #category : #'public API - introspection' } 146 | SQLite3BaseConnection >> declaredColumnTypesFor: aTableName [ 147 | 148 | self isOpen 149 | ifFalse: [ SQLite3NotOpen signal ] 150 | ifTrue: [ 151 | ^ (self existTableNamed: aTableName) 152 | ifTrue: [ 153 | | columns s | 154 | columns := OrderedCollection new. 155 | s := self prepare: 'pragma table_info([' , aTableName , '])'. 156 | s basicExecute: [ :row | columns add: (row stringAt: 2) ]. 157 | s finalize. 158 | columns ] 159 | ifFalse: [ nil ] ] 160 | ] 161 | 162 | { #category : #'public API - extensions' } 163 | SQLite3BaseConnection >> disableExtensions [ 164 | ^ library disableLoadExtension: dbHandle 165 | ] 166 | 167 | { #category : #'public API - extensions' } 168 | SQLite3BaseConnection >> enableExtensions [ 169 | ^ library enableLoadExtension: dbHandle 170 | ] 171 | 172 | { #category : #private } 173 | SQLite3BaseConnection >> existTableNamed: aTableName [ 174 | 175 | | tableExists s | 176 | tableExists := false. 177 | s := self prepare: 'select count(*) from sqlite_master where type = "table" and tbl_name = ?'. 178 | s at: 1 putString: aTableName. 179 | s basicExecute: [ :row | tableExists := (row integerAt: 0) = 1 ]. 180 | s finalize. 181 | ^ tableExists 182 | ] 183 | 184 | { #category : #accessing } 185 | SQLite3BaseConnection >> filename [ 186 | ^ dbFilename 187 | ] 188 | 189 | { #category : #'public API - operating' } 190 | SQLite3BaseConnection >> finalize: aStatementHandle [ 191 | library finalize: aStatementHandle on: dbHandle 192 | ] 193 | 194 | { #category : #'public API - open/close' } 195 | SQLite3BaseConnection >> forceClose [ 196 | "Forces the release of dbHandle, enabling to delete the database file without closing Pharo" 197 | 198 | dbHandle ifNotNil: [ library close: dbHandle ]. 199 | self close 200 | ] 201 | 202 | { #category : #'public API - introspection' } 203 | SQLite3BaseConnection >> getAutoCommit [ 204 | 205 | ^library getAutoCommit: dbHandle 206 | ] 207 | 208 | { #category : #accessing } 209 | SQLite3BaseConnection >> handle [ 210 | ^dbHandle 211 | ] 212 | 213 | { #category : #initialization } 214 | SQLite3BaseConnection >> initialize [ 215 | super initialize. 216 | isOpen := false. 217 | library := SQLite3Library current. 218 | dbHandle := SQLite3DatabaseExternalObject new. 219 | dbHandle autoRelease. 220 | statementClass := SQLite3PreparedStatement 221 | ] 222 | 223 | { #category : #testing } 224 | SQLite3BaseConnection >> isOpen [ 225 | ^ isOpen 226 | ] 227 | 228 | { #category : #'public API - extensions' } 229 | SQLite3BaseConnection >> loadExtension: aFilename [ 230 | ^ library loadExtension: dbHandle with: aFilename 231 | ] 232 | 233 | { #category : #private } 234 | SQLite3BaseConnection >> on: aFilename [ 235 | 236 | dbFilename := aFilename. 237 | ^ self 238 | ] 239 | 240 | { #category : #'public API - open/close' } 241 | SQLite3BaseConnection >> open [ 242 | library open: dbFilename via: dbHandle. 243 | isOpen := true 244 | ] 245 | 246 | { #category : #'public API - operating' } 247 | SQLite3BaseConnection >> prepare: anSQLText [ 248 | | s | 249 | 250 | s := self statementClass new. 251 | s connection: self. 252 | s prepare: anSQLText. 253 | ^ s 254 | ] 255 | 256 | { #category : #'public API - cleaning' } 257 | SQLite3BaseConnection >> reset: aStatement [ 258 | ^library reset: aStatement handle 259 | ] 260 | 261 | { #category : #'public API - transactional' } 262 | SQLite3BaseConnection >> rollbackTransaction [ 263 | ^ self basicExecute: 'rollback' 264 | ] 265 | 266 | { #category : #private } 267 | SQLite3BaseConnection >> signal: exceptionClass with: value [ 268 | library signal: exceptionClass with: value on: dbHandle 269 | ] 270 | 271 | { #category : #accessing } 272 | SQLite3BaseConnection >> statementClass [ 273 | ^ statementClass 274 | ] 275 | 276 | { #category : #'public API - introspection' } 277 | SQLite3BaseConnection >> tableNames [ 278 | | tables s | 279 | 280 | self isOpen 281 | ifFalse: [ SQLite3NotOpen signal ] 282 | ifTrue: [ 283 | tables := OrderedCollection new. 284 | s := self prepare: 'select tbl_name from sqlite_master where type = "table"'. 285 | s basicExecute: [ :row | 286 | (row dataValuesAvailable > 0) ifTrue: [ tables add: (row stringAt: 0) ]]. 287 | s finalize. 288 | ^ tables ] 289 | ] 290 | 291 | { #category : #'public API - introspection' } 292 | SQLite3BaseConnection >> totalChanges [ 293 | ^ library totalChanges: dbHandle 294 | ] 295 | 296 | { #category : #'public API - tracing' } 297 | SQLite3BaseConnection >> traceUsing: callback with: appdata [ 298 | library trace: dbHandle with: callback with: appdata 299 | ] 300 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3Busy.class.st: -------------------------------------------------------------------------------- 1 | " 2 | This class comment was automatically generated from https://www.sqlite.org/rescode.html 3 | 4 | The SQLITE_BUSY result code indicates that the database file could not be written (or in some cases read) because of concurrent activity by some other database connection, usually a database connection in a separate process. 5 | 6 | For example, if process A is in the middle of a large write transaction and at the same time process B attempts to start a new write transaction, process B will get back an SQLITE_BUSY result because SQLite only supports one writer at a time. Process B will need to wait for process A to finish its transaction before starting a new transaction. The sqlite3_busy_timeout() and sqlite3_busy_handler() interfaces and the busy_timeout pragma are available to process B to help it deal with SQLITE_BUSY errors. 7 | 8 | An SQLITE_BUSY error can occur at any point in a transaction: when the transaction is first started, during any write or update operations, or when the transaction commits. To avoid encountering SQLITE_BUSY errors in the middle of a transaction, the application can use BEGIN IMMEDIATE instead of just BEGIN to start a transaction. The BEGIN IMMEDIATE command might itself return SQLITE_BUSY, but if it succeeds, then SQLite guarantees that no subsequent operations on the same database through the next COMMIT will return SQLITE_BUSY. 9 | 10 | See also: SQLITE_BUSY_RECOVERY and SQLITE_BUSY_SNAPSHOT. 11 | 12 | The SQLITE_BUSY result code differs from SQLITE_LOCKED in that SQLITE_BUSY indicates a conflict with a separate database connection, probably in a separate process, whereas SQLITE_LOCKED indicates a conflict within the same database connection (or sometimes a database connection with a shared cache). 13 | " 14 | Class { 15 | #name : #SQLite3Busy, 16 | #superclass : #SQLite3NativeError, 17 | #category : #'SQLite3-Core-Errors' 18 | } 19 | 20 | { #category : #'private - accessing' } 21 | SQLite3Busy class >> nativeErrorCode [ 22 | 23 | ^ SQLITE_BUSY 24 | ] 25 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3BusyRecovery.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_BUSY_RECOVERY error code is an extended error code for SQLITE_BUSY that indicates that an operation could not continue because another process is busy recovering a WAL mode database file following a crash. The SQLITE_BUSY_RECOVERY error code only occurs on WAL mode databases. 3 | " 4 | Class { 5 | #name : #SQLite3BusyRecovery, 6 | #superclass : #SQLite3Busy, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3BusyRecovery class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_BUSY_RECOVERY 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3BusySnapshot.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_BUSY_SNAPSHOT error code is an extended error code for SQLITE_BUSY that occurs on WAL mode databases when a database connection tries to promote a read transaction into a write transaction but finds that another database connection has already written to the database and thus invalidated prior reads. 3 | 4 | The following scenario illustrates how an SQLITE_BUSY_SNAPSHOT error might arise: 5 | 6 | 1. Process A starts a read transaction on the database and does one or more SELECT statement. Process A keeps the transaction open. 7 | 2. Process B updates the database, changing values previous read by process A. 8 | 3. Process A now tries to write to the database. But process A's view of the database content is now obsolete because process B has modified the database file after process A read from it. Hence process A gets an SQLITE_BUSY_SNAPSHOT error. 9 | " 10 | Class { 11 | #name : #SQLite3BusySnapshot, 12 | #superclass : #SQLite3Busy, 13 | #category : #'SQLite3-Core-Errors-Extended' 14 | } 15 | 16 | { #category : #'private - accessing' } 17 | SQLite3BusySnapshot class >> nativeErrorCode [ 18 | 19 | ^ SQLITE_BUSY_SNAPSHOT 20 | ] 21 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3CantOpen.class.st: -------------------------------------------------------------------------------- 1 | " 2 | This class comment was automatically generated from https://www.sqlite.org/rescode.html 3 | 4 | The SQLITE_CANTOPEN result code indicates that SQLite was unable to open a file. The file in question might be a primary database file or one of several temporary disk files. 5 | " 6 | Class { 7 | #name : #SQLite3CantOpen, 8 | #superclass : #SQLite3NativeError, 9 | #category : #'SQLite3-Core-Errors' 10 | } 11 | 12 | { #category : #'private - accessing' } 13 | SQLite3CantOpen class >> nativeErrorCode [ 14 | 15 | ^ SQLITE_CANTOPEN 16 | ] 17 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3CantOpenConvertPath.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_CANTOPEN_CONVPATH error code is an extended error code for SQLITE_CANTOPEN used only by Cygwin VFS and indicating that the cygwin_conv_path() system call failed while trying to open a file. See also: SQLITE_IOERR_CONVPATH 3 | " 4 | Class { 5 | #name : #SQLite3CantOpenConvertPath, 6 | #superclass : #SQLite3CantOpen, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3CantOpenConvertPath class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_CANTOPEN_CONVPATH 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3CantOpenFullPath.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_CANTOPEN_FULLPATH error code is an extended error code for SQLITE_CANTOPEN indicating that a file open operation failed because the operating system was unable to convert the filename into a full pathname. 3 | " 4 | Class { 5 | #name : #SQLite3CantOpenFullPath, 6 | #superclass : #SQLite3CantOpen, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3CantOpenFullPath class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_CANTOPEN_FULLPATH 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3CantOpenIsDir.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_CANTOPEN_ISDIR error code is an extended error code for SQLITE_CANTOPEN indicating that a file open operation failed because the file is really a directory. 3 | " 4 | Class { 5 | #name : #SQLite3CantOpenIsDir, 6 | #superclass : #SQLite3CantOpen, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3CantOpenIsDir class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_CANTOPEN_ISDIR 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3CantOpenNoTempDir.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_CANTOPEN_NOTEMPDIR error code is no longer used. 3 | " 4 | Class { 5 | #name : #SQLite3CantOpenNoTempDir, 6 | #superclass : #SQLite3CantOpen, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3CantOpenNoTempDir class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_CANTOPEN_NOTEMPDIR 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3Column.class.st: -------------------------------------------------------------------------------- 1 | " 2 | I represent a column in a table 3 | " 4 | Class { 5 | #name : #SQLite3Column, 6 | #superclass : #Object, 7 | #instVars : [ 8 | 'name', 9 | 'index', 10 | 'type', 11 | 'hasNotNullConstraint' 12 | ], 13 | #category : #'SQLite3-Core-Base' 14 | } 15 | 16 | { #category : #accessing } 17 | SQLite3Column >> cid: anObject [ 18 | "The cid column should not be taken to mean more than 'rank within the current result set'." 19 | 20 | index := anObject 21 | ] 22 | 23 | { #category : #accessing } 24 | SQLite3Column >> hasNotNullConstraint [ 25 | 26 | ^ hasNotNullConstraint 27 | ] 28 | 29 | { #category : #accessing } 30 | SQLite3Column >> index [ 31 | 32 | ^ index 33 | ] 34 | 35 | { #category : #accessing } 36 | SQLite3Column >> index: anObject [ 37 | 38 | index := anObject 39 | ] 40 | 41 | { #category : #initialization } 42 | SQLite3Column >> initialize [ 43 | 44 | super initialize. 45 | hasNotNullConstraint := false 46 | ] 47 | 48 | { #category : #accessing } 49 | SQLite3Column >> name [ 50 | 51 | ^ name 52 | ] 53 | 54 | { #category : #accessing } 55 | SQLite3Column >> name: anObject [ 56 | 57 | name := anObject 58 | ] 59 | 60 | { #category : #accessing } 61 | SQLite3Column >> notnull: anInteger [ 62 | "whether or not the column can be NULL" 63 | 64 | hasNotNullConstraint := anInteger = 1 65 | ] 66 | 67 | { #category : #printing } 68 | SQLite3Column >> printOn: aStream [ 69 | 70 | super printOn: aStream. 71 | aStream 72 | << '("'; 73 | << self name; 74 | << '")' 75 | ] 76 | 77 | { #category : #accessing } 78 | SQLite3Column >> type [ 79 | 80 | ^ type 81 | ] 82 | 83 | { #category : #accessing } 84 | SQLite3Column >> type: anObject [ 85 | 86 | type := anObject 87 | ] 88 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3Connection.class.st: -------------------------------------------------------------------------------- 1 | " 2 | I represent a connection to an SQLite database. 3 | 4 | " 5 | Class { 6 | #name : #SQLite3Connection, 7 | #superclass : #SQLite3BaseConnection, 8 | #category : #'SQLite3-Core-Connections' 9 | } 10 | 11 | { #category : #'public API - operating' } 12 | SQLite3Connection >> execute: anSQLText [ 13 | ^ self execute: anSQLText with: #() 14 | ] 15 | 16 | { #category : #'public API - operating' } 17 | SQLite3Connection >> execute: anSQLText value: anObject [ 18 | ^ (self prepare: anSQLText) execute: (Array with: anObject) 19 | ] 20 | 21 | { #category : #'public API - operating' } 22 | SQLite3Connection >> execute: anSQLText value: object1 value: object2 [ 23 | ^ self execute: anSQLText with: (Array with: object1 with: object2) 24 | ] 25 | 26 | { #category : #'public API - operating' } 27 | SQLite3Connection >> execute: anSQLText value: object1 value: object2 value: object3 [ 28 | ^ self execute: anSQLText 29 | with: (Array with: object1 with: object2 with: object3) 30 | ] 31 | 32 | { #category : #'public API - operating' } 33 | SQLite3Connection >> execute: anSQLText value: object1 value: object2 value: object3 value: object4 [ 34 | ^ self execute: anSQLText 35 | with: (Array with: object1 with: object2 with: object3 with: object4) 36 | ] 37 | 38 | { #category : #'public API - operating' } 39 | SQLite3Connection >> execute: anSQLText with: aCollection [ 40 | ^(self prepare: anSQLText) execute: aCollection 41 | ] 42 | 43 | { #category : #'public API - operating' } 44 | SQLite3Connection >> execute: anSQLText with: aCollection doing: aBlock [ 45 | | cursor | 46 | cursor := self execute: anSQLText with: aCollection. 47 | ^ [aBlock value: cursor] 48 | ensure: [ cursor finalizeStatement ] 49 | ] 50 | 51 | { #category : #'public API - operating' } 52 | SQLite3Connection >> execute: anSQLText withAll: parameterCollection [ 53 | "execute a sql statement with many parameters" 54 | 55 | | stmt | 56 | stmt := self prepare: anSQLText. 57 | parameterCollection do: [ :parameters | stmt execute: parameters ]. 58 | stmt finalize 59 | ] 60 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3Constants.class.st: -------------------------------------------------------------------------------- 1 | " 2 | I provide SQLIte's constants. 3 | " 4 | Class { 5 | #name : #SQLite3Constants, 6 | #superclass : #SharedPool, 7 | #classVars : [ 8 | 'SQLITE3_TEXT', 9 | 'SQLITE_ABORT', 10 | 'SQLITE_ABORT_ROLLBACK', 11 | 'SQLITE_AUTH', 12 | 'SQLITE_AUTH_USER', 13 | 'SQLITE_BLOB', 14 | 'SQLITE_BUSY', 15 | 'SQLITE_BUSY_RECOVERY', 16 | 'SQLITE_BUSY_SNAPSHOT', 17 | 'SQLITE_CANTOPEN', 18 | 'SQLITE_CANTOPEN_CONVPATH', 19 | 'SQLITE_CANTOPEN_DIRTYWAL', 20 | 'SQLITE_CANTOPEN_FULLPATH', 21 | 'SQLITE_CANTOPEN_ISDIR', 22 | 'SQLITE_CANTOPEN_NOTEMPDIR', 23 | 'SQLITE_CHECKPOINT_FULL', 24 | 'SQLITE_CHECKPOINT_PASSIVE', 25 | 'SQLITE_CHECKPOINT_RESTART', 26 | 'SQLITE_CHECKPOINT_TRUNCATE', 27 | 'SQLITE_CONSTRAINT', 28 | 'SQLITE_CONSTRAINT_CHECK', 29 | 'SQLITE_CONSTRAINT_COMMITHOOK', 30 | 'SQLITE_CONSTRAINT_FOREIGNKEY', 31 | 'SQLITE_CONSTRAINT_FUNCTION', 32 | 'SQLITE_CONSTRAINT_NOTNULL', 33 | 'SQLITE_CONSTRAINT_PRIMARYKEY', 34 | 'SQLITE_CONSTRAINT_ROWID', 35 | 'SQLITE_CONSTRAINT_TRIGGER', 36 | 'SQLITE_CONSTRAINT_UNIQUE', 37 | 'SQLITE_CONSTRAINT_VTAB', 38 | 'SQLITE_CORRUPT', 39 | 'SQLITE_CORRUPT_SEQUENCE', 40 | 'SQLITE_CORRUPT_VTAB', 41 | 'SQLITE_DONE', 42 | 'SQLITE_EMPTY', 43 | 'SQLITE_ERROR', 44 | 'SQLITE_ERROR_MISSING_COLLSEQ', 45 | 'SQLITE_ERROR_RETRY', 46 | 'SQLITE_ERROR_SNAPSHOT', 47 | 'SQLITE_FLOAT', 48 | 'SQLITE_FORMAT', 49 | 'SQLITE_FULL', 50 | 'SQLITE_INTEGER', 51 | 'SQLITE_INTERNAL', 52 | 'SQLITE_INTERRUPT', 53 | 'SQLITE_IOERR', 54 | 'SQLITE_IOERR_ACCESS', 55 | 'SQLITE_IOERR_AUTH', 56 | 'SQLITE_IOERR_BEGIN_ATOMIC', 57 | 'SQLITE_IOERR_BLOCKED', 58 | 'SQLITE_IOERR_CHECKRESERVEDLOCK', 59 | 'SQLITE_IOERR_CLOSE', 60 | 'SQLITE_IOERR_COMMIT_ATOMIC', 61 | 'SQLITE_IOERR_CONVPATH', 62 | 'SQLITE_IOERR_DELETE', 63 | 'SQLITE_IOERR_DELETE_NOENT', 64 | 'SQLITE_IOERR_DIR_CLOSE', 65 | 'SQLITE_IOERR_DIR_FSYNC', 66 | 'SQLITE_IOERR_FSTAT', 67 | 'SQLITE_IOERR_FSYNC', 68 | 'SQLITE_IOERR_GETTEMPPATH', 69 | 'SQLITE_IOERR_LOCK', 70 | 'SQLITE_IOERR_MMAP', 71 | 'SQLITE_IOERR_NOMEM', 72 | 'SQLITE_IOERR_RDLOCK', 73 | 'SQLITE_IOERR_READ', 74 | 'SQLITE_IOERR_ROLLBACK_ATOMIC', 75 | 'SQLITE_IOERR_SEEK', 76 | 'SQLITE_IOERR_SHMLOCK', 77 | 'SQLITE_IOERR_SHMMAP', 78 | 'SQLITE_IOERR_SHMOPEN', 79 | 'SQLITE_IOERR_SHMSIZE', 80 | 'SQLITE_IOERR_SHORT_READ', 81 | 'SQLITE_IOERR_TRUNCATE', 82 | 'SQLITE_IOERR_UNLOCK', 83 | 'SQLITE_IOERR_VNODE', 84 | 'SQLITE_IOERR_WRITE', 85 | 'SQLITE_LOCKED', 86 | 'SQLITE_LOCKED_SHAREDCACHE', 87 | 'SQLITE_LOCKED_VTAB', 88 | 'SQLITE_MISMATCH', 89 | 'SQLITE_MISUSE', 90 | 'SQLITE_NOLFS', 91 | 'SQLITE_NOMEM', 92 | 'SQLITE_NOTADB', 93 | 'SQLITE_NOTFOUND', 94 | 'SQLITE_NOTICE', 95 | 'SQLITE_NOTICE_RECOVER_ROLLBACK', 96 | 'SQLITE_NOTICE_RECOVER_WAL', 97 | 'SQLITE_NULL', 98 | 'SQLITE_OK', 99 | 'SQLITE_OK_LOAD_PERMANENTLY', 100 | 'SQLITE_OPEN_AUTOPROXY', 101 | 'SQLITE_OPEN_CREATE', 102 | 'SQLITE_OPEN_DELETEONCLOSE', 103 | 'SQLITE_OPEN_EXCLUSIVE', 104 | 'SQLITE_OPEN_FULLMUTEX', 105 | 'SQLITE_OPEN_MAIN_DB', 106 | 'SQLITE_OPEN_MAIN_JOURNAL', 107 | 'SQLITE_OPEN_MASTER_JOURNAL', 108 | 'SQLITE_OPEN_MEMORY', 109 | 'SQLITE_OPEN_NOMUTEX', 110 | 'SQLITE_OPEN_PRIVATECACHE', 111 | 'SQLITE_OPEN_READONLY', 112 | 'SQLITE_OPEN_READWRITE', 113 | 'SQLITE_OPEN_SHAREDCACHE', 114 | 'SQLITE_OPEN_SUBJOURNAL', 115 | 'SQLITE_OPEN_TEMP_DB', 116 | 'SQLITE_OPEN_TEMP_JOURNAL', 117 | 'SQLITE_OPEN_TRANSIENT_DB', 118 | 'SQLITE_OPEN_URI', 119 | 'SQLITE_OPEN_WAL', 120 | 'SQLITE_PERM', 121 | 'SQLITE_PROTOCOL', 122 | 'SQLITE_RANGE', 123 | 'SQLITE_READONLY', 124 | 'SQLITE_READONLY_CANTINIT', 125 | 'SQLITE_READONLY_CANTLOCK', 126 | 'SQLITE_READONLY_DBMOVED', 127 | 'SQLITE_READONLY_DIRECTORY', 128 | 'SQLITE_READONLY_RECOVERY', 129 | 'SQLITE_READONLY_ROLLBACK', 130 | 'SQLITE_ROW', 131 | 'SQLITE_SCHEMA', 132 | 'SQLITE_TEXT', 133 | 'SQLITE_TOOBIG', 134 | 'SQLITE_WARNING', 135 | 'SQLITE_WARNING_AUTOINDEX' 136 | ], 137 | #category : #'SQLite3-Core-UFFI-Support' 138 | } 139 | 140 | { #category : #'private - initialization' } 141 | SQLite3Constants class >> initCheckpointModes [ 142 | 143 | SQLITE_CHECKPOINT_PASSIVE := 0. 144 | SQLITE_CHECKPOINT_FULL := 1. 145 | SQLITE_CHECKPOINT_RESTART := 2. 146 | SQLITE_CHECKPOINT_TRUNCATE := 3 147 | ] 148 | 149 | { #category : #'private - initialization' } 150 | SQLite3Constants class >> initConstants [ 151 | 152 | self 153 | initResultCodes; 154 | initErrorCodes; 155 | initExtendedErrorCodes; 156 | initFileOpenFlags 157 | ] 158 | 159 | { #category : #'private - initialization' } 160 | SQLite3Constants class >> initDataTypes [ 161 | "Fundamental Datatypes" 162 | 163 | SQLITE_INTEGER := 1. 164 | SQLITE_FLOAT := 2. 165 | SQLITE_TEXT := 3. 166 | SQLITE3_TEXT := 3. 167 | SQLITE_BLOB := 4. 168 | SQLITE_NULL := 5 169 | ] 170 | 171 | { #category : #'private - initialization constants' } 172 | SQLite3Constants class >> initErrorCodes [ 173 | "In its default configuration, SQLite API routines return one of 26 integer 174 | [SQLITE_OK | result codes]." 175 | 176 | SQLITE_ERROR := 1. "SQL error or missing database" 177 | SQLITE_INTERNAL := 2. "Internal logic error in SQLite" 178 | SQLITE_PERM := 3. "Access permission denied" 179 | SQLITE_ABORT := 4. "Callback routine requested an abort" 180 | SQLITE_BUSY := 5. "The database file is locked" 181 | SQLITE_LOCKED := 6. "A table in the database is locked" 182 | SQLITE_NOMEM := 7. "A malloc() failed" 183 | SQLITE_READONLY := 8. "Attempt to write a readonly database" 184 | SQLITE_INTERRUPT := 9. "Operation terminated by sqlite3_interrupt()" 185 | SQLITE_IOERR := 10. "Some kind of disk I/O error occurred" 186 | SQLITE_CORRUPT := 11. "The database disk image is malformed" 187 | SQLITE_NOTFOUND := 12. "Unknown opcode in sqlite3_file_control()" 188 | SQLITE_FULL := 13. "Insertion failed because database is full" 189 | SQLITE_CANTOPEN := 14. "Unable to open the database file" 190 | SQLITE_PROTOCOL := 15. "Database lock protocol error" 191 | SQLITE_EMPTY := 16. "Database is empty" 192 | SQLITE_SCHEMA := 17. "The database schema changed" 193 | SQLITE_TOOBIG := 18. "String or BLOB exceeds size limit" 194 | SQLITE_CONSTRAINT := 19. "Abort due to constraint violation" 195 | SQLITE_MISMATCH := 20. "Data type mismatch" 196 | SQLITE_MISUSE := 21. "Library used incorrectly" 197 | SQLITE_NOLFS := 22. "Uses OS features not supported on host" 198 | SQLITE_AUTH := 23. "Authorization denied" 199 | SQLITE_FORMAT := 24. "Auxiliary database format error" 200 | SQLITE_RANGE := 25. "2nd parameter to sqlite3_bind out of range" 201 | SQLITE_NOTADB := 26. "File opened that is not a database file" 202 | SQLITE_NOTICE := 27. "Notifications from sqlite3_log()" 203 | SQLITE_WARNING := 28. "Warnings from sqlite3_log()" 204 | ] 205 | 206 | { #category : #'private - initialization constants' } 207 | SQLite3Constants class >> initExtendedErrorCodes [ 208 | "Newer versions of SQLite (version 3.3.8 and later) include support for additional result codes that provide more detailed information about errors. The extended result codes are enabled or disabled on a per database connection basis using the [sqlite3_extended_result_codes()] API." 209 | 210 | SQLITE_ERROR_MISSING_COLLSEQ := (SQLITE_ERROR | (1<<8)). 211 | SQLITE_ERROR_RETRY := (SQLITE_ERROR | (2<<8)). 212 | SQLITE_ERROR_SNAPSHOT := (SQLITE_ERROR | (3<<8)). 213 | SQLITE_IOERR_READ := (SQLITE_IOERR | (1<<8)). 214 | SQLITE_IOERR_SHORT_READ := (SQLITE_IOERR | (2<<8)). 215 | SQLITE_IOERR_WRITE := (SQLITE_IOERR | (3<<8)). 216 | SQLITE_IOERR_FSYNC := (SQLITE_IOERR | (4<<8)). 217 | SQLITE_IOERR_DIR_FSYNC := (SQLITE_IOERR | (5<<8)). 218 | SQLITE_IOERR_TRUNCATE := (SQLITE_IOERR | (6<<8)). 219 | SQLITE_IOERR_FSTAT := (SQLITE_IOERR | (7<<8)). 220 | SQLITE_IOERR_UNLOCK := (SQLITE_IOERR | (8<<8)). 221 | SQLITE_IOERR_RDLOCK := (SQLITE_IOERR | (9<<8)). 222 | SQLITE_IOERR_DELETE := (SQLITE_IOERR | (10<<8)). 223 | SQLITE_IOERR_BLOCKED := (SQLITE_IOERR | (11<<8)). 224 | SQLITE_IOERR_NOMEM := (SQLITE_IOERR | (12<<8)). 225 | SQLITE_IOERR_ACCESS := (SQLITE_IOERR | (13<<8)). 226 | SQLITE_IOERR_CHECKRESERVEDLOCK := (SQLITE_IOERR | (14<<8)). 227 | SQLITE_IOERR_LOCK := (SQLITE_IOERR | (15<<8)). 228 | SQLITE_IOERR_CLOSE := (SQLITE_IOERR | (16<<8)). 229 | SQLITE_IOERR_DIR_CLOSE := (SQLITE_IOERR | (17<<8)). 230 | SQLITE_IOERR_SHMOPEN := (SQLITE_IOERR | (18<<8)). 231 | SQLITE_IOERR_SHMSIZE := (SQLITE_IOERR | (19<<8)). 232 | SQLITE_IOERR_SHMLOCK := (SQLITE_IOERR | (20<<8)). 233 | SQLITE_IOERR_SHMMAP := (SQLITE_IOERR | (21<<8)). 234 | SQLITE_IOERR_SEEK := (SQLITE_IOERR | (22<<8)). 235 | SQLITE_IOERR_DELETE_NOENT := (SQLITE_IOERR | (23<<8)). 236 | SQLITE_IOERR_MMAP := (SQLITE_IOERR | (24<<8)). 237 | SQLITE_IOERR_GETTEMPPATH := (SQLITE_IOERR | (25<<8)). 238 | SQLITE_IOERR_CONVPATH := (SQLITE_IOERR | (26<<8)). 239 | SQLITE_IOERR_VNODE := (SQLITE_IOERR | (27<<8)). 240 | SQLITE_IOERR_AUTH := (SQLITE_IOERR | (28<<8)). 241 | SQLITE_IOERR_BEGIN_ATOMIC := (SQLITE_IOERR | (29<<8)). 242 | SQLITE_IOERR_COMMIT_ATOMIC := (SQLITE_IOERR | (30<<8)). 243 | SQLITE_IOERR_ROLLBACK_ATOMIC := (SQLITE_IOERR | (31<<8)). 244 | SQLITE_LOCKED_SHAREDCACHE := (SQLITE_LOCKED | (1<<8)). 245 | SQLITE_LOCKED_VTAB := (SQLITE_LOCKED | (2<<8)). 246 | SQLITE_BUSY_RECOVERY := (SQLITE_BUSY | (1<<8)). 247 | SQLITE_BUSY_SNAPSHOT := (SQLITE_BUSY | (2<<8)). 248 | SQLITE_CANTOPEN_NOTEMPDIR := (SQLITE_CANTOPEN | (1<<8)). 249 | SQLITE_CANTOPEN_ISDIR := (SQLITE_CANTOPEN | (2<<8)). 250 | SQLITE_CANTOPEN_FULLPATH := (SQLITE_CANTOPEN | (3<<8)). 251 | SQLITE_CANTOPEN_CONVPATH := (SQLITE_CANTOPEN | (4<<8)). 252 | SQLITE_CANTOPEN_DIRTYWAL := (SQLITE_CANTOPEN | (5<<8)). "Not Used" 253 | SQLITE_CORRUPT_VTAB := (SQLITE_CORRUPT | (1<<8)). 254 | SQLITE_CORRUPT_SEQUENCE := (SQLITE_CORRUPT | (2<<8)). 255 | SQLITE_READONLY_RECOVERY := (SQLITE_READONLY | (1<<8)). 256 | SQLITE_READONLY_CANTLOCK := (SQLITE_READONLY | (2<<8)). 257 | SQLITE_READONLY_ROLLBACK := (SQLITE_READONLY | (3<<8)). 258 | SQLITE_READONLY_DBMOVED := (SQLITE_READONLY | (4<<8)). 259 | SQLITE_READONLY_CANTINIT := (SQLITE_READONLY | (5<<8)). 260 | SQLITE_READONLY_DIRECTORY := (SQLITE_READONLY | (6<<8)). 261 | SQLITE_ABORT_ROLLBACK := (SQLITE_ABORT | (2<<8)). 262 | SQLITE_CONSTRAINT_CHECK := (SQLITE_CONSTRAINT | (1<<8)). 263 | SQLITE_CONSTRAINT_COMMITHOOK := (SQLITE_CONSTRAINT | (2<<8)). 264 | SQLITE_CONSTRAINT_FOREIGNKEY := (SQLITE_CONSTRAINT | (3<<8)). 265 | SQLITE_CONSTRAINT_FUNCTION := (SQLITE_CONSTRAINT | (4<<8)). 266 | SQLITE_CONSTRAINT_NOTNULL := (SQLITE_CONSTRAINT | (5<<8)). 267 | SQLITE_CONSTRAINT_PRIMARYKEY := (SQLITE_CONSTRAINT | (6<<8)). 268 | SQLITE_CONSTRAINT_TRIGGER := (SQLITE_CONSTRAINT | (7<<8)). 269 | SQLITE_CONSTRAINT_UNIQUE := (SQLITE_CONSTRAINT | (8<<8)). 270 | SQLITE_CONSTRAINT_VTAB := (SQLITE_CONSTRAINT | (9<<8)). 271 | SQLITE_CONSTRAINT_ROWID := (SQLITE_CONSTRAINT |(10<<8)). 272 | SQLITE_NOTICE_RECOVER_WAL := (SQLITE_NOTICE | (1<<8)). 273 | SQLITE_NOTICE_RECOVER_ROLLBACK := (SQLITE_NOTICE | (2<<8)). 274 | SQLITE_WARNING_AUTOINDEX := (SQLITE_WARNING | (1<<8)). 275 | SQLITE_AUTH_USER := (SQLITE_AUTH | (1<<8)). 276 | SQLITE_OK_LOAD_PERMANENTLY := (SQLITE_OK | (1<<8)) 277 | ] 278 | 279 | { #category : #'private - initialization constants' } 280 | SQLite3Constants class >> initFileOpenFlags [ 281 | 282 | SQLITE_OPEN_READONLY := Integer readFrom: '00000001' base: 16. " Ok for sqlite3_open_v2() " 283 | SQLITE_OPEN_READWRITE := Integer readFrom: '00000002' base: 16. " Ok for sqlite3_open_v2() " 284 | SQLITE_OPEN_CREATE := Integer readFrom: '00000004' base: 16. " Ok for sqlite3_open_v2() " 285 | SQLITE_OPEN_DELETEONCLOSE := Integer readFrom: '00000008' base: 16. " VFS only " 286 | SQLITE_OPEN_EXCLUSIVE := Integer readFrom: '00000010' base: 16. " VFS only " 287 | SQLITE_OPEN_AUTOPROXY := Integer readFrom: '00000020' base: 16. " VFS only " 288 | SQLITE_OPEN_URI := Integer readFrom: '00000040' base: 16. " Ok for sqlite3_open_v2() " 289 | SQLITE_OPEN_MEMORY := Integer readFrom: '00000080' base: 16. " Ok for sqlite3_open_v2() " 290 | SQLITE_OPEN_MAIN_DB := Integer readFrom: '00000100' base: 16. " VFS only " 291 | SQLITE_OPEN_TEMP_DB := Integer readFrom: '00000200' base: 16. " VFS only " 292 | SQLITE_OPEN_TRANSIENT_DB := Integer readFrom: '00000400' base: 16. " VFS only " 293 | SQLITE_OPEN_MAIN_JOURNAL := Integer readFrom: '00000800' base: 16. " VFS only " 294 | SQLITE_OPEN_TEMP_JOURNAL := Integer readFrom: '00001000' base: 16. " VFS only " 295 | SQLITE_OPEN_SUBJOURNAL := Integer readFrom: '00002000' base: 16. " VFS only " 296 | SQLITE_OPEN_MASTER_JOURNAL := Integer readFrom: '00004000' base: 16. " VFS only " 297 | SQLITE_OPEN_NOMUTEX := Integer readFrom: '00008000' base: 16. " Ok for sqlite3_open_v2() " 298 | SQLITE_OPEN_FULLMUTEX := Integer readFrom: '00010000' base: 16. " Ok for sqlite3_open_v2() " 299 | SQLITE_OPEN_SHAREDCACHE := Integer readFrom: '00020000' base: 16. " Ok for sqlite3_open_v2() " 300 | SQLITE_OPEN_PRIVATECACHE := Integer readFrom: '00040000' base: 16. " Ok for sqlite3_open_v2() " 301 | SQLITE_OPEN_WAL := Integer readFrom: '00080000' base: 16. " VFS only " 302 | ] 303 | 304 | { #category : #'private - initialization constants' } 305 | SQLite3Constants class >> initResultCodes [ 306 | 307 | SQLITE_OK := 0. "Successful result" 308 | SQLITE_ROW := 100. "sqlite3_step() has another row ready" 309 | SQLITE_DONE := 101 "sqlite3_step() has finished executing" 310 | ] 311 | 312 | { #category : #initialization } 313 | SQLite3Constants class >> initialize [ 314 | self 315 | initConstants; 316 | initDataTypes; 317 | initCheckpointModes 318 | ] 319 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3ConstraintViolation.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_CONSTRAINT error code means that an SQL constraint violation occurred while trying to process an SQL statement. Additional information about the failed constraint can be found by consulting the accompanying error message (returned via sqlite3_errmsg() or sqlite3_errmsg16()) or by looking at the extended error code. 3 | 4 | The SQLITE_CONSTRAINT code can also be used as the return value from the xBestIndex() method of a virtual table implementation. When xBestIndex() returns SQLITE_CONSTRAINT, that indicates that the particular combination of inputs submitted to xBestIndex() cannot result in a usable query plan and should not be given further consideration. 5 | " 6 | Class { 7 | #name : #SQLite3ConstraintViolation, 8 | #superclass : #SQLite3NativeError, 9 | #category : #'SQLite3-Core-Errors' 10 | } 11 | 12 | { #category : #'private - accessing' } 13 | SQLite3ConstraintViolation class >> nativeErrorCode [ 14 | 15 | ^ SQLITE_CONSTRAINT 16 | ] 17 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3ConstraintViolationCheck.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_CONSTRAINT_CHECK error code is an extended error code for SQLITE_CONSTRAINT indicating that a CHECK constraint failed. 3 | " 4 | Class { 5 | #name : #SQLite3ConstraintViolationCheck, 6 | #superclass : #SQLite3ConstraintViolation, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3ConstraintViolationCheck class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_CONSTRAINT_CHECK 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3ConstraintViolationCommitHook.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_CONSTRAINT_COMMITHOOK error code is an extended error code for SQLITE_CONSTRAINT indicating that a commit hook callback returned non-zero that thus caused the SQL statement to be rolled back. 3 | " 4 | Class { 5 | #name : #SQLite3ConstraintViolationCommitHook, 6 | #superclass : #SQLite3ConstraintViolation, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3ConstraintViolationCommitHook class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_CONSTRAINT_COMMITHOOK 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3ConstraintViolationForeignKey.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_CONSTRAINT_FOREIGNKEY error code is an extended error code for SQLITE_CONSTRAINT indicating that a foreign key constraint failed. 3 | " 4 | Class { 5 | #name : #SQLite3ConstraintViolationForeignKey, 6 | #superclass : #SQLite3ConstraintViolation, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3ConstraintViolationForeignKey class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_CONSTRAINT_FOREIGNKEY 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3ConstraintViolationFunction.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_CONSTRAINT_FUNCTION error code is not currently used by the SQLite core. However, this error code is available for use by extension functions. 3 | " 4 | Class { 5 | #name : #SQLite3ConstraintViolationFunction, 6 | #superclass : #SQLite3ConstraintViolation, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3ConstraintViolationFunction class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_CONSTRAINT_FUNCTION 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3ConstraintViolationNotNull.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_CONSTRAINT_NOTNULL error code is an extended error code for SQLITE_CONSTRAINT indicating that a NOT NULL constraint failed. 3 | " 4 | Class { 5 | #name : #SQLite3ConstraintViolationNotNull, 6 | #superclass : #SQLite3ConstraintViolation, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3ConstraintViolationNotNull class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_CONSTRAINT_NOTNULL 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3ConstraintViolationPrimaryKey.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_CONSTRAINT_PRIMARYKEY error code is an extended error code for SQLITE_CONSTRAINT indicating that a PRIMARY KEY constraint failed. 3 | " 4 | Class { 5 | #name : #SQLite3ConstraintViolationPrimaryKey, 6 | #superclass : #SQLite3ConstraintViolation, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3ConstraintViolationPrimaryKey class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_CONSTRAINT_PRIMARYKEY 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3ConstraintViolationRowID.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_CONSTRAINT_ROWID error code is an extended error code for SQLITE_CONSTRAINT indicating that a rowid is not unique. 3 | " 4 | Class { 5 | #name : #SQLite3ConstraintViolationRowID, 6 | #superclass : #SQLite3ConstraintViolation, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3ConstraintViolationRowID class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_CONSTRAINT_ROWID 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3ConstraintViolationTrigger.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_CONSTRAINT_TRIGGER error code is an extended error code for SQLITE_CONSTRAINT indicating that a RAISE function within a trigger fired, causing the SQL statement to abort. 3 | " 4 | Class { 5 | #name : #SQLite3ConstraintViolationTrigger, 6 | #superclass : #SQLite3ConstraintViolation, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3ConstraintViolationTrigger class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_CONSTRAINT_TRIGGER 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3ConstraintViolationUnique.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_CONSTRAINT_UNIQUE error code is an extended error code for SQLITE_CONSTRAINT indicating that a UNIQUE constraint failed. 3 | " 4 | Class { 5 | #name : #SQLite3ConstraintViolationUnique, 6 | #superclass : #SQLite3ConstraintViolation, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3ConstraintViolationUnique class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_CONSTRAINT_UNIQUE 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3ConstraintViolationVirtualTable.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_CONSTRAINT_VTAB error code is not currently used by the SQLite core. However, this error code is available for use by application-defined virtual tables. 3 | " 4 | Class { 5 | #name : #SQLite3ConstraintViolationVirtualTable, 6 | #superclass : #SQLite3ConstraintViolation, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3ConstraintViolationVirtualTable class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_CONSTRAINT_VTAB 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3Corrupt.class.st: -------------------------------------------------------------------------------- 1 | " 2 | This class comment was automatically generated from https://www.sqlite.org/rescode.html 3 | 4 | The SQLITE_CORRUPT result code indicates that the database file has been corrupted. See the How To Corrupt Your Database Files for further discussion on how corruption can occur. 5 | " 6 | Class { 7 | #name : #SQLite3Corrupt, 8 | #superclass : #SQLite3NativeError, 9 | #category : #'SQLite3-Core-Errors' 10 | } 11 | 12 | { #category : #'private - accessing' } 13 | SQLite3Corrupt class >> nativeErrorCode [ 14 | 15 | ^ SQLITE_CORRUPT 16 | ] 17 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3CorruptVirtualTable.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_CORRUPT_VTAB error code is an extended error code for SQLITE_CORRUPT used by virtual tables. A virtual table might return SQLITE_CORRUPT_VTAB to indicate that content in the virtual table is corrupt. 3 | " 4 | Class { 5 | #name : #SQLite3CorruptVirtualTable, 6 | #superclass : #SQLite3Corrupt, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3CorruptVirtualTable class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_CORRUPT_VTAB 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3Cursor.class.st: -------------------------------------------------------------------------------- 1 | " 2 | I represent a set of results returned by the database. I produce UDBCSQLite3Row instances lazily. 3 | 4 | " 5 | Class { 6 | #name : #SQLite3Cursor, 7 | #superclass : #Object, 8 | #instVars : [ 9 | 'statement', 10 | 'moreRows', 11 | 'rowClass', 12 | 'rows', 13 | 'mutators' 14 | ], 15 | #pools : [ 16 | 'SQLite3Constants' 17 | ], 18 | #category : #'SQLite3-Core-Database' 19 | } 20 | 21 | { #category : #'instance creation' } 22 | SQLite3Cursor class >> on: aStatement [ 23 | ^(self new) statement: aStatement; yourself 24 | ] 25 | 26 | { #category : #accessing } 27 | SQLite3Cursor >> changes [ 28 | ^statement changes 29 | ] 30 | 31 | { #category : #API } 32 | SQLite3Cursor >> close [ 33 | " closing a cursor is not the same as closing the statement - we may reuse a prepared statement" 34 | statement ifNotNil: [ statement reset ]. 35 | statement := nil. 36 | mutators := nil 37 | ] 38 | 39 | { #category : #accessing } 40 | SQLite3Cursor >> columnNames [ 41 | ^ statement ifNotNil: [ statement columnNames ] ifNil: [ #() ] 42 | ] 43 | 44 | { #category : #accessing } 45 | SQLite3Cursor >> connection [ 46 | ^statement connection 47 | ] 48 | 49 | { #category : #enumerating } 50 | SQLite3Cursor >> do: aBlock [ 51 | "Evaluate aBlock with each of the receiver's rows as the argument." 52 | 53 | | eachRow | 54 | [ (eachRow := self next) isNotNil ] whileTrue: [ 55 | aBlock value: eachRow ] 56 | ] 57 | 58 | { #category : #API } 59 | SQLite3Cursor >> finalizeStatement [ 60 | statement finalize 61 | ] 62 | 63 | { #category : #initialization } 64 | SQLite3Cursor >> initialize [ 65 | "Initializes the receiver" 66 | 67 | super initialize. 68 | moreRows := true. 69 | rowClass := SQLite3Row 70 | ] 71 | 72 | { #category : #accessing } 73 | SQLite3Cursor >> mutators [ 74 | ^ mutators 75 | ifNil: [ mutators := self columnNames 76 | collect: [ :c | 77 | (((c substrings: ' _-()') collect: [ :ea | ea capitalized ]) 78 | joinUsing: '') uncapitalized asSymbol asMutator ] ] 79 | ] 80 | 81 | { #category : #API } 82 | SQLite3Cursor >> next [ 83 | ^ self nextOfClass: self rowClass 84 | ] 85 | 86 | { #category : #API } 87 | SQLite3Cursor >> nextOfClass: aRowClass [ 88 | | rr | 89 | moreRows ifFalse: [ ^nil ]. 90 | 91 | statement 92 | ifNil: [ SQLite3Misuse 93 | signal: 'This result set does not contain a prepared statement.' ]. 94 | moreRows 95 | ifTrue: [ 96 | rr := aRowClass new. 97 | (rr respondsTo: #columnNames:) 98 | ifTrue: [ "generic row class" 99 | rr columnNames: self columnNames. 100 | 1 to: statement dataValuesAvailable do: [ :c | rr at: c put: (statement valueOfColumn: c - 1) ]. 101 | ] 102 | ifFalse: [ | msgs | 103 | "custom object" 104 | msgs := self mutators. 105 | 1 to: msgs size do: [ :c | 106 | (rr respondsTo: (msgs at: c)) 107 | ifTrue: [ rr perform: (msgs at: c) with: (statement valueOfColumn: c - 1) ] ] 108 | ]. 109 | moreRows := statement step = SQLITE_ROW. 110 | moreRows ifFalse: [ self close ]. 111 | ^ rr ]. 112 | ^ nil 113 | ] 114 | 115 | { #category : #API } 116 | SQLite3Cursor >> onlyRow [ 117 | ^ self onlyRow: [ ] 118 | 119 | "For the common case where there is exactly one row expected. Returns nil if there is no row." 120 | ] 121 | 122 | { #category : #API } 123 | SQLite3Cursor >> onlyRow: ifNoneBlock [ 124 | ^self rows 125 | ifEmpty: [ ifNoneBlock value ] 126 | ifNotEmpty: [ rows first ]. 127 | 128 | "For the common case where there is exactly one row expected. Returns the evaluation of ifNoneBlock if there is no row." 129 | ] 130 | 131 | { #category : #API } 132 | SQLite3Cursor >> onlyValue [ 133 | ^(self onlyRow: []) ifNotNil: [ :r | r first ] 134 | ] 135 | 136 | { #category : #accessing } 137 | SQLite3Cursor >> rowClass [ 138 | ^ rowClass 139 | ] 140 | 141 | { #category : #accessing } 142 | SQLite3Cursor >> rowClass: anObject [ 143 | rowClass := anObject 144 | ] 145 | 146 | { #category : #API } 147 | SQLite3Cursor >> rows [ 148 | ^ self rowsOfClass: self rowClass 149 | ] 150 | 151 | { #category : #API } 152 | SQLite3Cursor >> rowsOfClass: aRowClass [ 153 | 154 | rows ifNil: [ rows := OrderedCollection new ]. 155 | [ moreRows ] whileTrue: [ 156 | rows add: (self nextOfClass: aRowClass) ]. 157 | ^ rows 158 | ] 159 | 160 | { #category : #accessing } 161 | SQLite3Cursor >> statement [ 162 | ^ statement 163 | ] 164 | 165 | { #category : #accessing } 166 | SQLite3Cursor >> statement: anObject [ 167 | statement := anObject. 168 | moreRows := (statement ifNil:[false ] ifNotNil: [ statement dataValuesAvailable > 0 ]) 169 | ] 170 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3Database.class.st: -------------------------------------------------------------------------------- 1 | " 2 | An SQLite3 database 3 | " 4 | Class { 5 | #name : #SQLite3Database, 6 | #superclass : #Object, 7 | #instVars : [ 8 | 'connection' 9 | ], 10 | #category : #'SQLite3-Core-Base' 11 | } 12 | 13 | { #category : #'instance creation' } 14 | SQLite3Database class >> forConnection: aConnection [ 15 | 16 | ^ self new 17 | initConnection: aConnection; 18 | yourself 19 | ] 20 | 21 | { #category : #'instance creation' } 22 | SQLite3Database class >> memory [ 23 | 24 | ^ self forConnection: SQLite3Connection memory 25 | ] 26 | 27 | { #category : #'instance creation' } 28 | SQLite3Database class >> on: aFilename [ 29 | 30 | ^ self forConnection: (SQLite3Connection on: aFilename) 31 | ] 32 | 33 | { #category : #'instance creation' } 34 | SQLite3Database class >> openOn: aFilename [ 35 | 36 | ^ (self on: aFilename) 37 | open; 38 | yourself 39 | ] 40 | 41 | { #category : #accessing } 42 | SQLite3Database class >> tableInfoFor: aFileName [ 43 | 44 | | db | 45 | db := self on: aFileName. 46 | db connection open. 47 | ^ db tables 48 | ] 49 | 50 | { #category : #'open/close' } 51 | SQLite3Database >> close [ 52 | 53 | ^ self connection close 54 | ] 55 | 56 | { #category : #accessing } 57 | SQLite3Database >> connection [ 58 | 59 | ^ connection 60 | ] 61 | 62 | { #category : #executing } 63 | SQLite3Database >> execute: anSQLStatement [ 64 | 65 | ^ self connection execute: anSQLStatement 66 | ] 67 | 68 | { #category : #executing } 69 | SQLite3Database >> execute: anSQLStatement doing: aBlock [ 70 | 71 | ^ self connection execute: anSQLStatement with: #( ) doing: aBlock 72 | ] 73 | 74 | { #category : #'private - initialization' } 75 | SQLite3Database >> initConnection: aConnection [ 76 | 77 | connection := aConnection 78 | ] 79 | 80 | { #category : #'open/close' } 81 | SQLite3Database >> open [ 82 | 83 | ^ self connection open 84 | ] 85 | 86 | { #category : #printing } 87 | SQLite3Database >> printOn: aStream [ 88 | 89 | super printOn: aStream. 90 | aStream 91 | << '("'; 92 | << self connection filename; 93 | << '")' 94 | ] 95 | 96 | { #category : #accessing } 97 | SQLite3Database >> tables [ 98 | 99 | self connection isOpen ifFalse: [ ^ SQLite3NotOpen signal ]. 100 | 101 | ^ (connection execute: ' 102 | SELECT * 103 | FROM sqlite_master 104 | WHERE 105 | type =''table'' AND 106 | name NOT LIKE ''sqlite_%'';') rows collect: [ :eachRow | 107 | SQLite3Table properties: eachRow asDictionary in: self ] 108 | ] 109 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3DatabaseExternalObject.class.st: -------------------------------------------------------------------------------- 1 | " 2 | I represent the SQLite API 'sqlite3' C-level type. 3 | " 4 | Class { 5 | #name : #SQLite3DatabaseExternalObject, 6 | #superclass : #FFIOpaqueObject, 7 | #category : #'SQLite3-Core-UFFI-Support' 8 | } 9 | 10 | { #category : #'instance finalization' } 11 | SQLite3DatabaseExternalObject class >> doFinalizeResourceData: resourceData [ 12 | 13 | SQLite3Library current ffiCall: 14 | #( int sqlite3_close_v2 #( void * resourceData ) ) 15 | ] 16 | 17 | { #category : #finalization } 18 | SQLite3DatabaseExternalObject class >> finalizeResourceData: aHandle [ 19 | 20 | self doFinalizeResourceData: aHandle. 21 | aHandle beNull 22 | ] 23 | 24 | { #category : #initialization } 25 | SQLite3DatabaseExternalObject >> beNull [ 26 | 27 | ^ handle beNull 28 | ] 29 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3DoneResult.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_DONE result code indicates that an operation has completed. The SQLITE_DONE result code is most commonly seen as a return value from sqlite3_step() indicating that the SQL statement has run to completion. But SQLITE_DONE can also be returned by other multi-step interfaces such as sqlite3_backup_step(). 3 | " 4 | Class { 5 | #name : #SQLite3DoneResult, 6 | #superclass : #SQLite3Result, 7 | #category : #'SQLite3-Core-Results' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3DoneResult class >> nativeResultCode [ 12 | 13 | ^ SQLITE_DONE 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3Empty.class.st: -------------------------------------------------------------------------------- 1 | " 2 | This class comment was automatically generated from https://www.sqlite.org/rescode.html 3 | 4 | The SQLITE_EMPTY result code is not currently used. 5 | " 6 | Class { 7 | #name : #SQLite3Empty, 8 | #superclass : #SQLite3NativeError, 9 | #category : #'SQLite3-Core-Errors' 10 | } 11 | 12 | { #category : #'private - accessing' } 13 | SQLite3Empty class >> nativeErrorCode [ 14 | 15 | ^ SQLITE_EMPTY 16 | ] 17 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3Error.class.st: -------------------------------------------------------------------------------- 1 | " 2 | This class comment was automatically generated from https://www.sqlite.org/rescode.html 3 | 4 | The SQLITE_ERROR result code is a generic error code that is used when no other more specific error code is available. 5 | " 6 | Class { 7 | #name : #SQLite3Error, 8 | #superclass : #SQLite3NativeError, 9 | #category : #'SQLite3-Core-Errors' 10 | } 11 | 12 | { #category : #'private - accessing' } 13 | SQLite3Error class >> nativeErrorCode [ 14 | 15 | ^ SQLITE_ERROR 16 | ] 17 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3Format.class.st: -------------------------------------------------------------------------------- 1 | " 2 | This class comment was automatically generated from https://www.sqlite.org/rescode.html 3 | 4 | The SQLITE_FORMAT result code is not currently used. 5 | " 6 | Class { 7 | #name : #SQLite3Format, 8 | #superclass : #SQLite3NativeError, 9 | #category : #'SQLite3-Core-Errors' 10 | } 11 | 12 | { #category : #'private - accessing' } 13 | SQLite3Format class >> nativeErrorCode [ 14 | 15 | ^ SQLITE_FORMAT 16 | ] 17 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3Full.class.st: -------------------------------------------------------------------------------- 1 | " 2 | This class comment was automatically generated from https://www.sqlite.org/rescode.html 3 | 4 | The SQLITE_FULL result code indicates that a write could not complete because the disk is full. Note that this error can occur when trying to write information into the main database file, or it can also occur when writing into temporary disk files. 5 | 6 | Sometimes applications encounter this error even though there is an abundance of primary disk space because the error occurs when writing into temporary disk files on a system where temporary files are stored on a separate partition with much less space that the primary disk. 7 | " 8 | Class { 9 | #name : #SQLite3Full, 10 | #superclass : #SQLite3NativeError, 11 | #category : #'SQLite3-Core-Errors' 12 | } 13 | 14 | { #category : #'private - accessing' } 15 | SQLite3Full class >> nativeErrorCode [ 16 | 17 | ^ SQLITE_FULL 18 | ] 19 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOError.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR result code says that the operation could not finish because the operating system reported an I/O error. 3 | 4 | A full disk drive will normally give an SQLITE_FULL error rather than an SQLITE_IOERR error. 5 | 6 | There are many different extended result codes for I/O errors that identify the specific I/O operation that failed. 7 | " 8 | Class { 9 | #name : #SQLite3IOError, 10 | #superclass : #SQLite3NativeError, 11 | #category : #'SQLite3-Core-Errors' 12 | } 13 | 14 | { #category : #'private - accessing' } 15 | SQLite3IOError class >> nativeErrorCode [ 16 | 17 | ^ SQLITE_IOERR 18 | ] 19 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorAccess.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_ACCESS error code is an extended error code for SQLITE_IOERR indicating an I/O error within the xAccess method on the sqlite3_vfs object. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorAccess, 6 | #superclass : #SQLite3IOError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorAccess class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_ACCESS 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorBlocked.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_BLOCKED error code is no longer used. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorBlocked, 6 | #superclass : #SQLite3IOError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorBlocked class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_BLOCKED 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorCheckReservedLock.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_CHECKRESERVEDLOCK error code is an extended error code for SQLITE_IOERR indicating an I/O error within the xCheckReservedLock method on the sqlite3_io_methods object. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorCheckReservedLock, 6 | #superclass : #SQLite3IOError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorCheckReservedLock class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_CHECKRESERVEDLOCK 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorClose.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_CLOSE error code is an extended error code for SQLITE_IOERR indicating an I/O error within the xClose method on the sqlite3_io_methods object. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorClose, 6 | #superclass : #SQLite3IOError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorClose class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_CLOSE 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorConvertPath.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_CONVPATH error code is an extended error code for SQLITE_IOERR used only by Cygwin VFS and indicating that the cygwin_conv_path() system call failed. See also: SQLITE_CANTOPEN_CONVPATH 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorConvertPath, 6 | #superclass : #SQLite3IOError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorConvertPath class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_CONVPATH 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorDelete.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_DELETE error code is an extended error code for SQLITE_IOERR indicating an I/O error within xDelete method on the sqlite3_vfs object. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorDelete, 6 | #superclass : #SQLite3IOError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorDelete class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_DELETE 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorDeleteNoEntry.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_DELETE_NOENT error code is an extended error code for SQLITE_IOERR indicating that the xDelete method on the sqlite3_vfs object failed because the file being deleted does not exist. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorDeleteNoEntry, 6 | #superclass : #SQLite3IOErrorDelete, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorDeleteNoEntry class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_DELETE_NOENT 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorDirClose.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_DIR_CLOSE error code is no longer used. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorDirClose, 6 | #superclass : #SQLite3IOError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorDirClose class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_DIR_CLOSE 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorDirFSync.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_DIR_FSYNC error code is an extended error code for SQLITE_IOERR indicating an I/O error in the VFS layer while trying to invoke fsync() on a directory. The unix VFS attempts to fsync() directories after creating or deleting certain files to ensure that those files will still appear in the filesystem following a power loss or system crash. This error code indicates a problem attempting to perform that fsync(). 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorDirFSync, 6 | #superclass : #SQLite3IOError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorDirFSync class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_DIR_FSYNC 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorFStat.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_FSTAT error code is an extended error code for SQLITE_IOERR indicating an I/O error in the VFS layer while trying to invoke fstat() (or the equivalent) on a file in order to determine information such as the file size or access permissions. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorFStat, 6 | #superclass : #SQLite3IOError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorFStat class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_FSTAT 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorFSync.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_FSYNC error code is an extended error code for SQLITE_IOERR indicating an I/O error in the VFS layer while trying to flush previously written content out of OS and/or disk-control buffers and into persistent storage. In other words, this code indicates a problem with the fsync() system call in unix or the FlushFileBuffers() system call in windows. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorFSync, 6 | #superclass : #SQLite3IOError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorFSync class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_FSYNC 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorGetTempPath.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_GETTEMPPATH error code is an extended error code for SQLITE_IOERR indicating that the VFS is unable to determine a suitable directory in which to place temporary files. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorGetTempPath, 6 | #superclass : #SQLite3IOError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorGetTempPath class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_GETTEMPPATH 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorLock.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_LOCK error code is an extended error code for SQLITE_IOERR indicating an I/O error in the advisory file locking logic. Usually an SQLITE_IOERR_LOCK error indicates a problem obtaining a PENDING lock. However it can also indicate miscellaneous locking errors on some of the specialized VFSes used on Macs. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorLock, 6 | #superclass : #SQLite3IOError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorLock class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_LOCK 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorMemoryMap.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_MMAP error code is an extended error code for SQLITE_IOERR indicating an I/O error within the xFetch or xUnfetch methods on the sqlite3_io_methods object while trying to map or unmap part of the database file into the process address space. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorMemoryMap, 6 | #superclass : #SQLite3IOError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorMemoryMap class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_MMAP 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorNoMemory.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_NOMEM error code is sometimes returned by the VFS layer to indicate that an operation could not be completed due to the inability to allocate sufficient memory. This error code is normally converted into SQLITE_NOMEM by the higher layers of SQLite before being returned to the application. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorNoMemory, 6 | #superclass : #SQLite3IOError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorNoMemory class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_NOMEM 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorRead.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_READ error code is an extended error code for SQLITE_IOERR indicating an I/O error in the VFS layer while trying to read from a file on disk. This error might result from a hardware malfunction or because a filesystem came unmounted while the file was open. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorRead, 6 | #superclass : #SQLite3IOError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorRead class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_READ 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorReadLock.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_RDLOCK error code is an extended error code for SQLITE_IOERR indicating an I/O error within xLock method on the sqlite3_io_methods object while trying to obtain a read lock. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorReadLock, 6 | #superclass : #SQLite3IOError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorReadLock class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_RDLOCK 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorSeek.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_SEEK error code is an extended error code for SQLITE_IOERR indicating an I/O error within the xRead or xWrite methods on the sqlite3_io_methods object while trying to seek a file descriptor to the beginning point of the file where the read or write is to occur. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorSeek, 6 | #superclass : #SQLite3IOError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorSeek class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_SEEK 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorSharedMemoryError.class.st: -------------------------------------------------------------------------------- 1 | " 2 | Abstract superclass for extended errors on shared memory access in SQlite3 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorSharedMemoryError, 6 | #superclass : #SQLite3IOError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #testing } 11 | SQLite3IOErrorSharedMemoryError class >> isAbstract [ 12 | 13 | ^self name = #SQLite3IOErrorSharedMemoryError 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorSharedMemoryLock.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_SHMLOCK error code is no longer used. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorSharedMemoryLock, 6 | #superclass : #SQLite3IOErrorSharedMemoryError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorSharedMemoryLock class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_SHMLOCK 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorSharedMemoryMap.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_SHMMAP error code is an extended error code for SQLITE_IOERR indicating an I/O error within the xShmMap method on the sqlite3_io_methods object while trying to map a shared memory segment into the process address space. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorSharedMemoryMap, 6 | #superclass : #SQLite3IOErrorSharedMemoryError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorSharedMemoryMap class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_SHMMAP 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorSharedMemoryOpen.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_SHMOPEN error code is an extended error code for SQLITE_IOERR indicating an I/O error within the xShmMap method on the sqlite3_io_methods object while trying to open a new shared memory segment. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorSharedMemoryOpen, 6 | #superclass : #SQLite3IOErrorSharedMemoryError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorSharedMemoryOpen class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_SHMOPEN 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorSharedMemorySize.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_SHMSIZE error code is an extended error code for SQLITE_IOERR indicating an I/O error within the xShmMap method on the sqlite3_io_methods object while trying to enlarge a ""shm"" file as part of WAL mode transaction processing. This error may indicate that the underlying filesystem volume is out of space. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorSharedMemorySize, 6 | #superclass : #SQLite3IOErrorSharedMemoryError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorSharedMemorySize class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_SHMSIZE 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorShortRead.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_SHORT_READ error code is an extended error code for SQLITE_IOERR indicating that a read attempt in the VFS layer was unable to obtain as many bytes as was requested. This might be due to a truncated file. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorShortRead, 6 | #superclass : #SQLite3IOError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorShortRead class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_SHORT_READ 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorTruncate.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_TRUNCATE error code is an extended error code for SQLITE_IOERR indicating an I/O error in the VFS layer while trying to truncate a file to a smaller size. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorTruncate, 6 | #superclass : #SQLite3IOError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorTruncate class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_TRUNCATE 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorUnlock.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_UNLOCK error code is an extended error code for SQLITE_IOERR indicating an I/O error within xUnlock method on the sqlite3_io_methods object. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorUnlock, 6 | #superclass : #SQLite3IOError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorUnlock class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_UNLOCK 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3IOErrorWrite.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_IOERR_WRITE error code is an extended error code for SQLITE_IOERR indicating an I/O error in the VFS layer while trying to write into a file on disk. This error might result from a hardware malfunction or because a filesystem came unmounted while the file was open. This error should not occur if the filesystem is full as there is a separate error code (SQLITE_FULL) for that purpose. 3 | " 4 | Class { 5 | #name : #SQLite3IOErrorWrite, 6 | #superclass : #SQLite3IOError, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3IOErrorWrite class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_IOERR_WRITE 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3Internal.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_INTERNAL result code indicates an internal malfunction. In a working version of SQLite, an application should never see this result code. If application does encounter this result code, it shows that there is a bug in the database engine. 3 | 4 | SQLite does not currently generate this result code. However, application-defined SQL functions or virtual tables, or VFSes, or other extensions might cause this result code to be returned. 5 | " 6 | Class { 7 | #name : #SQLite3Internal, 8 | #superclass : #SQLite3NativeError, 9 | #category : #'SQLite3-Core-Errors' 10 | } 11 | 12 | { #category : #'private - accessing' } 13 | SQLite3Internal class >> nativeErrorCode [ 14 | 15 | ^ SQLITE_INTERNAL 16 | ] 17 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3Interrupt.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_INTERRUPT result code indicates that an operation was interrupted by the sqlite3_interrupt() interface. See also: SQLITE_ABORT 3 | " 4 | Class { 5 | #name : #SQLite3Interrupt, 6 | #superclass : #SQLite3NativeError, 7 | #category : #'SQLite3-Core-Errors' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3Interrupt class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_INTERRUPT 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3Locked.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_LOCKED result code indicates that a write operation could not continue because of a conflict within the same database connection or a conflict with a different database connection that uses a shared cache. 3 | 4 | For example, a DROP TABLE statement cannot be run while another thread is reading from that table on the same database connection because dropping the table would delete the table out from under the concurrent reader. 5 | 6 | The SQLITE_LOCKED result code differs from SQLITE_BUSY in that SQLITE_LOCKED indicates a conflict on the same database connection (or on a connection with a shared cache) whereas SQLITE_BUSY indicates a conflict with a different database connection, probably in a different process. 7 | " 8 | Class { 9 | #name : #SQLite3Locked, 10 | #superclass : #SQLite3NativeError, 11 | #category : #'SQLite3-Core-Errors' 12 | } 13 | 14 | { #category : #'private - accessing' } 15 | SQLite3Locked class >> nativeErrorCode [ 16 | 17 | ^ SQLITE_LOCKED 18 | ] 19 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3LockedSharedCache.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_LOCKED_SHAREDCACHE error code is an extended error code for SQLITE_LOCKED indicating that the locking conflict has occurred due to contention with a different database connection that happens to hold a shared cache with the database connection to which the error was returned. For example, if the other database connection is holding an exclusive lock on the database, then the database connection that receives this error will be unable to read or write any part of the database file unless it has the read_uncommitted pragma enabled. 3 | 4 | The SQLITE_LOCKED_SHARECACHE error code works very much like the SQLITE_BUSY error code except that SQLITE_LOCKED_SHARECACHE is for separate database connections that share a cache whereas SQLITE_BUSY is for the much more common case of separate database connections that do not share the same cache. Also, the sqlite3_busy_handler() and sqlite3_busy_timeout() interfaces do not help in resolving SQLITE_LOCKED_SHAREDCACHE conflicts. 5 | " 6 | Class { 7 | #name : #SQLite3LockedSharedCache, 8 | #superclass : #SQLite3Locked, 9 | #category : #'SQLite3-Core-Errors-Extended' 10 | } 11 | 12 | { #category : #'private - accessing' } 13 | SQLite3LockedSharedCache class >> nativeErrorCode [ 14 | 15 | ^ SQLITE_LOCKED_SHAREDCACHE 16 | ] 17 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3LogNotice.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_NOTICE result code is not returned by any C/C++ interface. However, SQLITE_NOTICE (or rather one of its extended error codes) is sometimes used as the first argument in an sqlite3_log() callback to indicate that an unusual operation is taking place. 3 | " 4 | Class { 5 | #name : #SQLite3LogNotice, 6 | #superclass : #SQLite3NativeError, 7 | #category : #'SQLite3-Core-Errors' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3LogNotice class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_NOTICE 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3LogNoticeRecoverRollback.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_NOTICE_RECOVER_ROLLBACK result code is passed to the callback of sqlite3_log() when a hot journal is rolled back. 3 | " 4 | Class { 5 | #name : #SQLite3LogNoticeRecoverRollback, 6 | #superclass : #SQLite3LogNotice, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3LogNoticeRecoverRollback class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_NOTICE_RECOVER_ROLLBACK 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3LogNoticeRecoverWriteAheadLogging.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_NOTICE_RECOVER_WAL result code is passed to the callback of sqlite3_log() when a WAL mode database file is recovered. 3 | " 4 | Class { 5 | #name : #SQLite3LogNoticeRecoverWriteAheadLogging, 6 | #superclass : #SQLite3LogNotice, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3LogNoticeRecoverWriteAheadLogging class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_NOTICE_RECOVER_WAL 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3LogWarning.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_WARNING result code is not returned by any C/C++ interface. However, SQLITE_WARNING (or rather one of its extended error codes) is sometimes used as the first argument in an sqlite3_log() callback to indicate that an unusual and possibly ill-advised operation is taking place. 3 | " 4 | Class { 5 | #name : #SQLite3LogWarning, 6 | #superclass : #SQLite3NativeError, 7 | #category : #'SQLite3-Core-Errors' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3LogWarning class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_WARNING 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3LogWarningAutoIndex.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_WARNING_AUTOINDEX result code is passed to the callback of sqlite3_log() whenever automatic indexing is used. This can serve as a warning to application designers that the database might benefit from additional indexes. 3 | " 4 | Class { 5 | #name : #SQLite3LogWarningAutoIndex, 6 | #superclass : #SQLite3LogWarning, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3LogWarningAutoIndex class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_WARNING_AUTOINDEX 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3Mismatch.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_MISMATCH error code indicates a datatype mismatch. 3 | 4 | SQLite is normally very forgiving about mismatches between the type of a value and the declared type of the container in which that value is to be stored. For example, SQLite allows the application to store a large BLOB in a column with a declared type of BOOLEAN. But in a few cases, SQLite is strict about types. The SQLITE_MISMATCH error is returned in those few cases when the types do not match. 5 | 6 | The rowid of a table must be an integer. Attempt to set the rowid to anything other than an integer (or a NULL which will be automatically converted into the next available integer rowid) results in an SQLITE_MISMATCH error. 7 | " 8 | Class { 9 | #name : #SQLite3Mismatch, 10 | #superclass : #SQLite3NativeError, 11 | #category : #'SQLite3-Core-Errors' 12 | } 13 | 14 | { #category : #'private - accessing' } 15 | SQLite3Mismatch class >> nativeErrorCode [ 16 | 17 | ^ SQLITE_MISMATCH 18 | ] 19 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3Misuse.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_MISUSE return code might be returned if the application uses any SQLite interface in a way that is undefined or unsupported. For example, using a prepared statement after that prepared statement has been finalized might result in an SQLITE_MISUSE error. 3 | 4 | SQLite tries to detect misuse and report the misuse using this result code. However, there is no guarantee that the detection of misuse will be successful. Misuse detection is probabilistic. Applications should never depend on an SQLITE_MISUSE return value. 5 | 6 | If SQLite ever returns SQLITE_MISUSE from any interface, that means that the application is incorrectly coded and needs to be fixed. Do not ship an application that sometimes returns SQLITE_MISUSE from a standard SQLite interface because that application contains potentially serious bugs. 7 | " 8 | Class { 9 | #name : #SQLite3Misuse, 10 | #superclass : #SQLite3NativeError, 11 | #category : #'SQLite3-Core-Errors' 12 | } 13 | 14 | { #category : #'private - accessing' } 15 | SQLite3Misuse class >> nativeErrorCode [ 16 | 17 | ^ SQLITE_MISUSE 18 | ] 19 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3NativeError.class.st: -------------------------------------------------------------------------------- 1 | " 2 | Common subclass for errors corresponding to a native SQLite3 C library error code. 3 | 4 | Typically one uses this class to create and access instances of subclasses: 5 | 6 | (SQLite3NativeError forNativeErrorCode: SQLITE_INTERRUPT messageText: 'Interrupted') signal 7 | " 8 | Class { 9 | #name : #SQLite3NativeError, 10 | #superclass : #SQLite3AbstractError, 11 | #pools : [ 12 | 'SQLite3Constants' 13 | ], 14 | #category : #'SQLite3-Core-Errors' 15 | } 16 | 17 | { #category : #examples } 18 | SQLite3NativeError class >> example [ 19 | 20 | (SQLite3NativeError forNativeErrorCode: SQLITE_INTERRUPT messageText: 'Interrupted') signal 21 | ] 22 | 23 | { #category : #accessing } 24 | SQLite3NativeError class >> forNativeErrorCode: anInteger messageText: aString [ 25 | 26 | ^(self subclassForNativeErrorCode: anInteger) new 27 | messageText: aString; 28 | yourself 29 | ] 30 | 31 | { #category : #testing } 32 | SQLite3NativeError class >> isAbstract [ 33 | 34 | ^self name = #SQLite3NativeError 35 | ] 36 | 37 | { #category : #'private - accessing' } 38 | SQLite3NativeError class >> nativeErrorCode [ 39 | "Returns the native error code as defined by SQLite C library." 40 | 41 | ^ self subclassResponsibility 42 | ] 43 | 44 | { #category : #'private - accessing' } 45 | SQLite3NativeError class >> subclassForNativeErrorCode: anInteger [ 46 | ^ self subclasses 47 | detect: [ :subclass | subclass nativeErrorCode = anInteger ] 48 | ] 49 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3NoLargeFileSupport.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_NOLFS error can be returned on systems that do not support large files when the database grows to be larger than what the filesystem can handle. ""NOLFS"" stands for ""NO Large File Support"". 3 | " 4 | Class { 5 | #name : #SQLite3NoLargeFileSupport, 6 | #superclass : #SQLite3NativeError, 7 | #category : #'SQLite3-Core-Errors' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3NoLargeFileSupport class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_NOLFS 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3NoMemory.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_NOMEM result code indicates that SQLite was unable to allocate all the memory it needed to complete the operation. In other words, an internal call to sqlite3_malloc() or sqlite3_realloc() has failed in a case where the memory being allocated was required in order to continue the operation. 3 | " 4 | Class { 5 | #name : #SQLite3NoMemory, 6 | #superclass : #SQLite3NativeError, 7 | #category : #'SQLite3-Core-Errors' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3NoMemory class >> nativeErrorCode [ 12 | 13 | ^SQLITE_NOMEM 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3NotADatabase.class.st: -------------------------------------------------------------------------------- 1 | " 2 | When attempting to open a file, the SQLITE_NOTADB error indicates that the file being opened does not appear to be an SQLite database file. 3 | " 4 | Class { 5 | #name : #SQLite3NotADatabase, 6 | #superclass : #SQLite3NativeError, 7 | #category : #'SQLite3-Core-Errors' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3NotADatabase class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_NOTADB 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3NotFound.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_NOTFOUND result code is used in two contexts. SQLITE_NOTFOUND can be returned by the sqlite3_file_control() interface to indicate that the file control opcode passed as the third argument was not recognized by the underlying VFS. SQLITE_NOTFOUND can also be returned by the xSetSystemCall() method of an sqlite3_vfs object. 3 | 4 | The SQLITE_NOTFOUND result code is also used internally by the SQLite implementation, but those internal uses are not exposed to the application. 5 | " 6 | Class { 7 | #name : #SQLite3NotFound, 8 | #superclass : #SQLite3NativeError, 9 | #category : #'SQLite3-Core-Errors' 10 | } 11 | 12 | { #category : #'private - accessing' } 13 | SQLite3NotFound class >> nativeErrorCode [ 14 | 15 | ^ SQLITE_NOTFOUND 16 | ] 17 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3NotOpen.class.st: -------------------------------------------------------------------------------- 1 | " 2 | I am signalled when operations are invoked on a database that is not open. 3 | 4 | " 5 | Class { 6 | #name : #SQLite3NotOpen, 7 | #superclass : #SQLite3AbstractError, 8 | #category : #'SQLite3-Core-Errors' 9 | } 10 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3OKResult.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_OK result code means that the operation was successful and that there were no errors. Most other result codes indicate an error. 3 | " 4 | Class { 5 | #name : #SQLite3OKResult, 6 | #superclass : #SQLite3Result, 7 | #category : #'SQLite3-Core-Results' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3OKResult class >> nativeResultCode [ 12 | 13 | ^ SQLITE_OK 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3OutOfRange.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_RANGE error indices that the parameter number argument to one of the sqlite3_bind routines or the column number in one of the sqlite3_column routines is out of range. 3 | " 4 | Class { 5 | #name : #SQLite3OutOfRange, 6 | #superclass : #SQLite3NativeError, 7 | #category : #'SQLite3-Core-Errors' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3OutOfRange class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_RANGE 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3Permission.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_PERM result code indicates that the requested access mode for a newly created database could not be provided. 3 | " 4 | Class { 5 | #name : #SQLite3Permission, 6 | #superclass : #SQLite3NativeError, 7 | #category : #'SQLite3-Core-Errors' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3Permission class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_PERM 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3PreparedStatement.class.st: -------------------------------------------------------------------------------- 1 | " 2 | I represent an SQLite prepared statement. 3 | " 4 | Class { 5 | #name : #SQLite3PreparedStatement, 6 | #superclass : #Object, 7 | #instVars : [ 8 | 'connection', 9 | 'handle', 10 | 'changes', 11 | 'columnNames', 12 | 'bindings' 13 | ], 14 | #pools : [ 15 | 'SQLite3Constants' 16 | ], 17 | #category : #'SQLite3-Core-Database' 18 | } 19 | 20 | { #category : #bindings } 21 | SQLite3PreparedStatement >> at: aColumn putBoolean: aBoolean [ 22 | 23 | ^ self library 24 | with: handle 25 | at: aColumn 26 | putInteger: (aBoolean ifTrue: [ 1 ] ifFalse: [ 0 ]) 27 | 28 | "See http://www.sqlite.org/datatype3.html." 29 | ] 30 | 31 | { #category : #bindings } 32 | SQLite3PreparedStatement >> at: aColumn putByteArray: anObject [ 33 | 34 | | byteArray | 35 | byteArray := self bindingAt: anObject ifAbsentPut: [ anObject ]. 36 | ^ self library with: handle at: aColumn putBlob: byteArray 37 | ] 38 | 39 | { #category : #bindings } 40 | SQLite3PreparedStatement >> at: aColumn putDate: aDate [ 41 | 42 | | string | 43 | 44 | string := self bindingAt: aDate ifAbsentPut: [ 45 | String streamContents: [ :stream | 46 | BasicDatePrinter new printDate: aDate format: #( ) on: stream ] ]. 47 | ^ self library with: handle at: aColumn putText: string 48 | ] 49 | 50 | { #category : #bindings } 51 | SQLite3PreparedStatement >> at: aColumn putDateTime: aDateTime [ 52 | 53 | | string | 54 | 55 | string := self 56 | bindingAt: aDateTime 57 | ifAbsentPut: [ String streamContents: [ :stream | aDateTime asDateAndTime printOn: stream ] ]. 58 | ^ self library with: handle at: aColumn putText: string 59 | ] 60 | 61 | { #category : #bindings } 62 | SQLite3PreparedStatement >> at: aColumn putFloat: aFloat [ 63 | | f | 64 | 65 | f := (aFloat isKindOf: Fraction) 66 | ifTrue: [ aFloat asFloat ] 67 | ifFalse: [ aFloat ]. 68 | ^ self library with: handle at: aColumn putFloat: f 69 | ] 70 | 71 | { #category : #bindings } 72 | SQLite3PreparedStatement >> at: aColumn putInteger: anInteger [ 73 | 74 | ^ self library with: handle at: aColumn putInteger: anInteger 75 | ] 76 | 77 | { #category : #bindings } 78 | SQLite3PreparedStatement >> at: aColumn putNil: anObject [ 79 | "Goofy interface note - anObject is ignored here." 80 | "When used by SQLite3Connection, anObject will always be nil." 81 | ^ self library with: handle putNullAt: aColumn 82 | ] 83 | 84 | { #category : #bindings } 85 | SQLite3PreparedStatement >> at: aColumn putObject: anObject [ 86 | 87 | | blob | 88 | blob := self bindingAt: anObject ifAbsentPut: [ FLSerializer serializeToByteArray: anObject ]. 89 | ^ self library 90 | with: handle 91 | at: aColumn 92 | putBlob: blob 93 | ] 94 | 95 | { #category : #bindings } 96 | SQLite3PreparedStatement >> at: aColumn putString: aString [ 97 | 98 | | s | 99 | 100 | s := self bindingAt: aString ifAbsentPut: [ aString ]. 101 | ^ self library with: handle at: aColumn putText: s 102 | ] 103 | 104 | { #category : #bindings } 105 | SQLite3PreparedStatement >> at: aColumn putTime: aTime [ 106 | 107 | | string | 108 | 109 | string := self 110 | bindingAt: aTime 111 | ifAbsentPut: [ String streamContents: [ :stream | aTime printOn: stream ] ]. 112 | ^ self library with: handle at: aColumn putText: string 113 | ] 114 | 115 | { #category : #public } 116 | SQLite3PreparedStatement >> basicExecute: aBlock [ 117 | | ret | 118 | 119 | ret := self step. 120 | (ret = SQLITE_DONE) " == SQLITE_DONE, meaning step should not be sent again." 121 | ifTrue: [ aBlock value: self ] 122 | ifFalse: [ 123 | [ ret = SQLITE_ROW ] whileTrue: [ " == SQLITE_ROW, meaning another row is available." 124 | aBlock value: self. 125 | ret := self step ]] 126 | ] 127 | 128 | { #category : #bindings } 129 | SQLite3PreparedStatement >> bindParameterCount [ 130 | ^ self library bindParameterCount: handle 131 | ] 132 | 133 | { #category : #bindings } 134 | SQLite3PreparedStatement >> bindParameterIndex: aName [ 135 | ^ self library bindParameterIndex: handle for: aName 136 | ] 137 | 138 | { #category : #bindings } 139 | SQLite3PreparedStatement >> bindParameters: parameters [ 140 | 141 | "A 'variable' or 'parameter' token specifies a placeholder in the expression for a value that is filled in at runtime using the sqlite3_bind() family of C/C++ interfaces. Parameters can take several forms: 142 | 143 | ?NNN A question mark followed by a number NNN holds a spot for the NNN-th parameter. NNN must be between 1 and SQLITE_MAX_VARIABLE_NUMBER. 144 | ? A question mark that is not followed by a number creates a parameter with a number one greater than the largest parameter number already assigned. If this means the parameter number is greater than SQLITE_MAX_VARIABLE_NUMBER, it is an error. This parameter format is provided for compatibility with other database engines. But because it is easy to miscount the question marks, the use of this parameter format is discouraged. Programmers are encouraged to use one of the symbolic formats below or the ?NNN format above instead. 145 | :AAAA A colon followed by an identifier name holds a spot for a named parameter with the name :AAAA. Named parameters are also numbered. The number assigned is one greater than the largest parameter number already assigned. If this means the parameter would be assigned a number greater than SQLITE_MAX_VARIABLE_NUMBER, it is an error. To avoid confusion, it is best to avoid mixing named and numbered parameters. 146 | @AAAA An 'at' sign works exactly like a colon, except that the name of the parameter created is @AAAA. 147 | $AAAA A dollar-sign followed by an identifier name also holds a spot for a named parameter with the name $AAAA. The identifier name in this case can include one or more occurrences of '::' and a suffix enclosed in '(...)' containing any text at all. This syntax is the form of a variable name in the Tcl programming language. The presence of this syntax results from the fact that SQLite is really a Tcl extension that has escaped into the wild. 148 | Parameters that are not assigned values using sqlite3_bind() are treated as NULL. The sqlite3_bind_parameter_index() interface can be used to translate a symbolic parameter name into its equivalent numeric index." 149 | 150 | (parameters isCollection and: [ parameters isString not ]) ifFalse: [ 151 | SQLite3AbstractError signal: 152 | 'Unable to execute SQL on instance of ' , parameters class asString ]. 153 | 154 | parameters keysAndValuesDo: [ :k :v | 155 | | idx | 156 | k isInteger 157 | ifTrue: [ idx := k ] 158 | ifFalse: [ 159 | idx := self bindParameterIndex: k. 160 | idx = 0 ifTrue: [ idx := self bindParameterIndex: '@' , k ]. 161 | idx = 0 ifTrue: [ idx := self bindParameterIndex: ':' , k ]. 162 | idx = 0 ifTrue: [ idx := self bindParameterIndex: '$' , k ]. 163 | (idx = 0 and: [ k isAllDigits ]) ifTrue: [ idx := k asInteger ] ]. 164 | idx > 0 ifTrue: [ 165 | self perform: (self dataTypeForObject: v) with: idx with: v ] ] 166 | ] 167 | 168 | { #category : #bindings } 169 | SQLite3PreparedStatement >> bindingAt: anObject ifAbsentPut: aBlock [ 170 | ^bindings at: anObject ifAbsentPut: aBlock 171 | ] 172 | 173 | { #category : #fetching } 174 | SQLite3PreparedStatement >> booleanAt: aColumn [ 175 | ^self library booleanFrom: handle at: aColumn 176 | ] 177 | 178 | { #category : #fetching } 179 | SQLite3PreparedStatement >> byteArrayAt: aColumn [ 180 | ^ self library blobFrom: handle at: aColumn 181 | ] 182 | 183 | { #category : #'public - accessing' } 184 | SQLite3PreparedStatement >> changes [ 185 | ^changes ifNil: [ changes := 0 ] 186 | ] 187 | 188 | { #category : #private } 189 | SQLite3PreparedStatement >> checkOk: aValue [ 190 | 191 | "These are normal conditions." 192 | aValue = SQLITE_OK ifTrue: [ ^aValue ]. 193 | 194 | "These are error conditions." 195 | (aValue = SQLITE_BUSY) 196 | ifTrue: [ connection signal: SQLite3Busy with: aValue ]. 197 | (aValue = SQLITE_MISUSE) 198 | ifTrue: [ connection signal: SQLite3Misuse with: aValue ]. 199 | 200 | "Catch any error not specifically handled above." 201 | connection signal: SQLite3AbstractError with: aValue 202 | ] 203 | 204 | { #category : #bindings } 205 | SQLite3PreparedStatement >> clearBindings [ 206 | 207 | | cleared | 208 | cleared := self library clearBindings: handle on: connection handle. 209 | bindings removeAll. 210 | ^cleared 211 | ] 212 | 213 | { #category : #public } 214 | SQLite3PreparedStatement >> columnCount [ 215 | ^self library columnCount: handle 216 | ] 217 | 218 | { #category : #'public - accessing' } 219 | SQLite3PreparedStatement >> columnNames [ 220 | 221 | ^ columnNames ifNil: [ 222 | columnNames := (1 to: self columnCount) collect: [ :c | self nameOfColumn: c - 1 ]. 223 | columnNames ] 224 | ] 225 | 226 | { #category : #'private - accessing' } 227 | SQLite3PreparedStatement >> connection: anObject [ 228 | connection := anObject 229 | ] 230 | 231 | { #category : #bindings } 232 | SQLite3PreparedStatement >> dataTypeForObject: anObject [ 233 | 234 | anObject ifNil: [ ^ #at:putNil: ]. 235 | 236 | ( anObject isKindOf: Boolean ) 237 | ifTrue: [ ^ #at:putBoolean: ]. 238 | 239 | ( anObject isKindOf: Integer ) 240 | ifTrue: [ ^ #at:putInteger: ]. 241 | 242 | ( self isFloatLike: anObject ) 243 | ifTrue: [ ^ #at:putFloat: ]. 244 | 245 | ( anObject isKindOf: String ) 246 | ifTrue: [ ^ #at:putString: ]. 247 | 248 | ( anObject isKindOf: ByteArray ) 249 | ifTrue: [ ^ #at:putByteArray: ]. 250 | 251 | ( anObject isKindOf: DateAndTime ) 252 | ifTrue: [ ^ #at:putDateTime: ]. 253 | 254 | ( anObject isKindOf: Time ) 255 | ifTrue: [ ^ #at:putTime: ]. 256 | 257 | ( anObject isKindOf: Date ) 258 | ifTrue: [ ^ #at:putDate: ]. 259 | 260 | ^ #at:putObject: 261 | ] 262 | 263 | { #category : #'public - accessing' } 264 | SQLite3PreparedStatement >> dataValuesAvailable [ 265 | ^ self library dataValuesAvailable: handle 266 | ] 267 | 268 | { #category : #fetching } 269 | SQLite3PreparedStatement >> dateAt: aColumn [ 270 | 271 | ^ Date fromString: ( self stringAt: aColumn ) 272 | ] 273 | 274 | { #category : #fetching } 275 | SQLite3PreparedStatement >> dateTimeAt: aColumn [ 276 | 277 | ^ DateAndTime fromString: ( self stringAt: aColumn ) 278 | ] 279 | 280 | { #category : #'private - accessing' } 281 | SQLite3PreparedStatement >> dbHandle [ 282 | ^(self library dbHandle: handle) 283 | ] 284 | 285 | { #category : #operating } 286 | SQLite3PreparedStatement >> execute: parameters [ 287 | 288 | | result | 289 | self checkOk: self reset. 290 | self clearBindings. 291 | self bindParameters: parameters. 292 | result := self step. 293 | changes := connection changes. 294 | ^ SQLite3Cursor on: self 295 | ] 296 | 297 | { #category : #initialization } 298 | SQLite3PreparedStatement >> finalize [ 299 | "Finalize the statement as required by the SQLite3 API. As per the API, the user is expected to finalize a statement after use. 300 | 301 | Since executing a new statement without having finalized the previous one might cause SQLITE_BUSY errors, we can't rely on the garbage collector to execute the finalization, or we'll be exposed to non-deterministic behaviour." 302 | 303 | handle 304 | ifNotNil: 305 | [ "Remove the statement object from its finalization registry. This should happen before the actual finalization to avoid finalizing the statement twice, which might result in 'undefined and undesirable behavior such as segfaults and heap corruption' as per the SQLite3 API" 306 | handle manualRelease. 307 | connection finalize: handle. 308 | handle := nil ]. 309 | ^ 0 310 | ] 311 | 312 | { #category : #fetching } 313 | SQLite3PreparedStatement >> floatAt: aColumn [ 314 | 315 | ^self library floatFrom: handle at: aColumn 316 | ] 317 | 318 | { #category : #'private - accessing' } 319 | SQLite3PreparedStatement >> handle [ 320 | ^ handle 321 | ] 322 | 323 | { #category : #initialization } 324 | SQLite3PreparedStatement >> initialize [ 325 | 326 | super initialize. 327 | bindings := IdentityDictionary new. 328 | handle := SQLite3StatementExternalObject new. 329 | handle autoRelease 330 | ] 331 | 332 | { #category : #fetching } 333 | SQLite3PreparedStatement >> integerAt: aColumn [ 334 | ^self library integerFrom: handle at: aColumn 335 | ] 336 | 337 | { #category : #'private - testing' } 338 | SQLite3PreparedStatement >> isFloatLike: anObject [ 339 | ^ (anObject isKindOf: Float) or: [ anObject isKindOf: Fraction ] 340 | ] 341 | 342 | { #category : #'public - accessing' } 343 | SQLite3PreparedStatement >> isReadOnly [ 344 | ^self library statementReadOnly: handle 345 | ] 346 | 347 | { #category : #'private - accessing' } 348 | SQLite3PreparedStatement >> library [ 349 | ^SQLite3Library current 350 | ] 351 | 352 | { #category : #fetching } 353 | SQLite3PreparedStatement >> nameOfColumn: aColumn [ 354 | ^ self library nameFor: handle at: aColumn 355 | ] 356 | 357 | { #category : #fetching } 358 | SQLite3PreparedStatement >> nilAt: aColumn [ 359 | ^ nil 360 | ] 361 | 362 | { #category : #fetching } 363 | SQLite3PreparedStatement >> objectAt: aColumn [ 364 | ^ FLMaterializer materializeFromByteArray: (self library blobFrom: handle at: aColumn) 365 | ] 366 | 367 | { #category : #public } 368 | SQLite3PreparedStatement >> prepare: anSQLText [ 369 | self library prepare: handle on: connection handle with: anSQLText 370 | ] 371 | 372 | { #category : #public } 373 | SQLite3PreparedStatement >> reset [ 374 | ^connection reset: self 375 | ] 376 | 377 | { #category : #operating } 378 | SQLite3PreparedStatement >> sqlText [ 379 | ^ self library sqlText: handle 380 | ] 381 | 382 | { #category : #public } 383 | SQLite3PreparedStatement >> step [ 384 | ^ self stepOk: (self library step: handle) 385 | ] 386 | 387 | { #category : #private } 388 | SQLite3PreparedStatement >> stepOk: aValue [ 389 | 390 | "These are normal conditions." 391 | (aValue = SQLITE_ROW or: [aValue = SQLITE_DONE]) ifTrue: [ 392 | changes := connection changes. 393 | ^aValue ]. 394 | 395 | "These are error conditions." 396 | (aValue = SQLITE_BUSY) 397 | ifTrue: [ connection signal: SQLite3Busy with: aValue ]. 398 | (aValue = SQLITE_MISUSE) 399 | ifTrue: [ connection signal: SQLite3Misuse with: aValue ]. 400 | (aValue = SQLITE_CONSTRAINT) 401 | ifTrue: [ connection signal: SQLite3ConstraintViolation with: aValue]. 402 | 403 | "Catch any error not specifically handled above." 404 | connection signal: SQLite3AbstractError with: aValue 405 | ] 406 | 407 | { #category : #fetching } 408 | SQLite3PreparedStatement >> stringAt: aColumn [ 409 | "Answer the string from the specified column" 410 | 411 | "#stringFrom:at: is supplied in a version specific package. 412 | If there are no implementers the appropriate package needs to be loaded. :-)" 413 | ^ self library stringFrom: handle at: aColumn 414 | ] 415 | 416 | { #category : #fetching } 417 | SQLite3PreparedStatement >> timeAt: aColumn [ 418 | 419 | ^ Time fromString: ( self stringAt: aColumn ) 420 | ] 421 | 422 | { #category : #fetching } 423 | SQLite3PreparedStatement >> timestampAt: aColumn [ 424 | 425 | ^ DateAndTime fromString: ( self stringAt: aColumn ) 426 | ] 427 | 428 | { #category : #fetching } 429 | SQLite3PreparedStatement >> typeOfColumn: aColumn [ 430 | ^ self library typeFor: handle at: aColumn 431 | ] 432 | 433 | { #category : #fetching } 434 | SQLite3PreparedStatement >> valueOfColumn: aColumn [ 435 | ^ self perform: (self typeOfColumn: aColumn) with: aColumn 436 | ] 437 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3Protocol.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_PROTOCOL result code indicates a problem with the file locking protocol used by SQLite. The SQLITE_PROTOCOL error is currently only returned when using WAL mode and attempting to start a new transaction. There is a race condition that can occur when two separate database connections both try to start a transaction at the same time in WAL mode. The loser of the race backs off and tries again, after a brief delay. If the same connection loses the locking race dozens of times over a span of multiple seconds, it will eventually give up and return SQLITE_PROTOCOL. The SQLITE_PROTOCOL error should appear in practice very, very rarely, and only when there are many separate processes all competing intensely to write to the same database. 3 | " 4 | Class { 5 | #name : #SQLite3Protocol, 6 | #superclass : #SQLite3NativeError, 7 | #category : #'SQLite3-Core-Errors' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3Protocol class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_PROTOCOL 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3ReadOnly.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_READONLY result code is returned when an attempt is made to alter some data for which the current database connection does not have write permission. 3 | " 4 | Class { 5 | #name : #SQLite3ReadOnly, 6 | #superclass : #SQLite3NativeError, 7 | #category : #'SQLite3-Core-Errors' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3ReadOnly class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_READONLY 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3ReadOnlyCantLock.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_READONLY_CANTLOCK error code is an extended error code for SQLITE_READONLY. The SQLITE_READONLY_CANTLOCK error code indicates that SQLite is unable to obtain a read lock on a WAL mode database because the shared-memory file associated with that database is read-only. 3 | " 4 | Class { 5 | #name : #SQLite3ReadOnlyCantLock, 6 | #superclass : #SQLite3ReadOnly, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3ReadOnlyCantLock class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_READONLY_CANTLOCK 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3ReadOnlyDBMoved.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_READONLY_DBMOVED error code is an extended error code for SQLITE_READONLY. The SQLITE_READONLY_DBMOVED error code indicates that a database cannot be modified because the database file has been moved since it was opened, and so any attempt to modify the database might result in database corruption if the processes crashes because the rollback journal would not be correctly named. 3 | " 4 | Class { 5 | #name : #SQLite3ReadOnlyDBMoved, 6 | #superclass : #SQLite3ReadOnly, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3ReadOnlyDBMoved class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_READONLY_DBMOVED 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3ReadOnlyRecovery.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_READONLY_RECOVERY error code is an extended error code for SQLITE_READONLY. The SQLITE_READONLY_RECOVERY error code indicates that a WAL mode database cannot be opened because the database file needs to be recovered and recovery requires write access but only read access is available. 3 | " 4 | Class { 5 | #name : #SQLite3ReadOnlyRecovery, 6 | #superclass : #SQLite3ReadOnly, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3ReadOnlyRecovery class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_READONLY_RECOVERY 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3ReadOnlyRollback.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_READONLY_ROLLBACK error code is an extended error code for SQLITE_READONLY. The SQLITE_READONLY_ROLLBACK error code indicates that a database cannot be opened because it has a hot journal that needs to be rolled back but cannot because the database is readonly. 3 | " 4 | Class { 5 | #name : #SQLite3ReadOnlyRollback, 6 | #superclass : #SQLite3ReadOnly, 7 | #category : #'SQLite3-Core-Errors-Extended' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3ReadOnlyRollback class >> nativeErrorCode [ 12 | 13 | ^ SQLITE_READONLY_ROLLBACK 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3Result.class.st: -------------------------------------------------------------------------------- 1 | " 2 | I am an abstract superclass for corresponding classes to result codes created by SQLite3 C library. 3 | 4 | Subclasses should not be instantiated directly. Instead use #forNativeResultCode: with a valid result constant. 5 | 6 | SQLite3Result forNativeResultCode: SQLITE_OK 7 | " 8 | Class { 9 | #name : #SQLite3Result, 10 | #superclass : #Object, 11 | #pools : [ 12 | 'SQLite3Constants' 13 | ], 14 | #category : #'SQLite3-Core-Results' 15 | } 16 | 17 | { #category : #accessing } 18 | SQLite3Result class >> forNativeResultCode: anInteger [ 19 | ^ (self subclassForNativeResultCode: anInteger) new 20 | ] 21 | 22 | { #category : #testing } 23 | SQLite3Result class >> isAbstract [ 24 | 25 | ^self name = #SQLite3Result 26 | ] 27 | 28 | { #category : #'private - accessing' } 29 | SQLite3Result class >> nativeResultCode [ 30 | 31 | ^ self subclassResponsibility 32 | ] 33 | 34 | { #category : #'private - accessing' } 35 | SQLite3Result class >> subclassForNativeResultCode: anInteger [ 36 | ^ self subclasses 37 | detect: [ :subclass | subclass nativeResultCode = anInteger ] 38 | ] 39 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3Row.class.st: -------------------------------------------------------------------------------- 1 | " 2 | I represent a row of results returned by the database. 3 | 4 | " 5 | Class { 6 | #name : #SQLite3Row, 7 | #superclass : #Object, 8 | #instVars : [ 9 | 'values', 10 | 'columnNames' 11 | ], 12 | #category : #'SQLite3-Core-Base' 13 | } 14 | 15 | { #category : #'instance creation' } 16 | SQLite3Row class >> new: anInteger [ 17 | ^(self new) 18 | columnNames:(Array new:anInteger); 19 | values: (Array new: anInteger); 20 | yourself 21 | ] 22 | 23 | { #category : #converting } 24 | SQLite3Row >> asArray [ 25 | ^ self values asArray 26 | ] 27 | 28 | { #category : #converting } 29 | SQLite3Row >> asCombinedDictionary [ 30 | ^self asDictionary addAll: ((self values collectWithIndex:[:v :i | i -> v]) asDictionary); yourself 31 | ] 32 | 33 | { #category : #converting } 34 | SQLite3Row >> asDictionary [ 35 | "Borrowed from the future - Pharo 8" 36 | | dict | 37 | dict := Dictionary new. 38 | self columnNames with: self values do: [ :k :v | dict at: k put: v ]. 39 | ^ dict 40 | ] 41 | 42 | { #category : #accessing } 43 | SQLite3Row >> at: aKey [ 44 | ^ self at: aKey ifAbsent: [ ] 45 | ] 46 | 47 | { #category : #accessing } 48 | SQLite3Row >> at: aKey ifAbsent: aBlock [ 49 | ^ aKey isInteger 50 | ifTrue: [ self values at: aKey ifAbsent: aBlock ] 51 | ifFalse: [ self values at:(self columnNames indexOf: aKey) ifAbsent: aBlock ] 52 | ] 53 | 54 | { #category : #accessing } 55 | SQLite3Row >> at: aKey put: anObject [ 56 | ^ aKey isInteger 57 | ifTrue: [self atIndex: aKey put: anObject] 58 | ifFalse: [ self atName: aKey put: anObject ] 59 | ] 60 | 61 | { #category : #accessing } 62 | SQLite3Row >> atIndex: anIndex [ 63 | ^ values at: anIndex ifAbsent: [ ] 64 | ] 65 | 66 | { #category : #accessing } 67 | SQLite3Row >> atIndex: anIndex put: anObject [ 68 | ^ self values at: anIndex put: anObject 69 | ] 70 | 71 | { #category : #accessing } 72 | SQLite3Row >> atName: aKey [ 73 | | idx | 74 | idx := self columnNames indexOf: aKey. 75 | ^idx = 0 76 | ifTrue: [ SQLite3Misuse 77 | signal: 'Attept to set invalid column name ', aKey, ' in result set' ] 78 | ifFalse: [ values at: idx ] 79 | ] 80 | 81 | { #category : #accessing } 82 | SQLite3Row >> atName: aKey put: anObject [ 83 | | idx | 84 | ^ (idx := self columnNames indexOf: aKey) isZero 85 | ifTrue: [ 86 | columnNames := self columnNames copyWith: aKey. 87 | values := self values copyWith: anObject ] 88 | ifFalse: [ values at: idx put: anObject ] 89 | ] 90 | 91 | { #category : #accessing } 92 | SQLite3Row >> columnNames [ 93 | ^ columnNames ifNil: [ #() ] 94 | ] 95 | 96 | { #category : #accessing } 97 | SQLite3Row >> columnNames: anArray [ 98 | columnNames := anArray. 99 | values := Array new: anArray size 100 | ] 101 | 102 | { #category : #accessing } 103 | SQLite3Row >> data [ 104 | "compatibility" 105 | ^self asCombinedDictionary 106 | ] 107 | 108 | { #category : #accessing } 109 | SQLite3Row >> dataCount [ 110 | ^ self columnNames size 111 | ] 112 | 113 | { #category : #'reflective operations' } 114 | SQLite3Row >> doesNotUnderstand: aMessage [ 115 | 116 | ^ self at: aMessage selector asString 117 | ifAbsent: [ 118 | "20160514: This bit, for Glorp integration, feels a bit iffy." 119 | self at: aMessage selector asString asUppercase 120 | ifAbsent: [ super doesNotUnderstand: aMessage ]] 121 | ] 122 | 123 | { #category : #accessing } 124 | SQLite3Row >> first [ 125 | ^ self values ifEmpty: [] ifNotEmpty: [:v | v first ] 126 | ] 127 | 128 | { #category : #accessing } 129 | SQLite3Row >> last [ 130 | ^ self values ifEmpty: [ nil ] ifNotEmpty: [:v | v last ] 131 | ] 132 | 133 | { #category : #accessing } 134 | SQLite3Row >> size [ 135 | ^ self columnNames size 136 | ] 137 | 138 | { #category : #accessing } 139 | SQLite3Row >> values [ 140 | ^values ifNil: [ #() ] 141 | ] 142 | 143 | { #category : #accessing } 144 | SQLite3Row >> values: anArray [ 145 | values := anArray 146 | ] 147 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3RowResult.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_ROW result code returned by sqlite3_step() indicates that another row of output is available. 3 | " 4 | Class { 5 | #name : #SQLite3RowResult, 6 | #superclass : #SQLite3Result, 7 | #category : #'SQLite3-Core-Results' 8 | } 9 | 10 | { #category : #'private - accessing' } 11 | SQLite3RowResult class >> nativeResultCode [ 12 | 13 | ^ SQLITE_ROW 14 | ] 15 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3SchemaChanged.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_SCHEMA result code indicates that the database schema has changed. This result code can be returned from sqlite3_step() for a prepared statement that was generated using sqlite3_prepare() or sqlite3_prepare16(). If the database schema was changed by some other process in between the time that the statement was prepared and the time the statement was run, this error can result. 3 | 4 | If a prepared statement is generated from sqlite3_prepare_v2() then the statement is automatically re-prepared if the schema changes, up to SQLITE_MAX_SCHEMA_RETRY times (default: 50). The sqlite3_step() interface will only return SQLITE_SCHEMA back to the application if the failure persists after these many retries. 5 | " 6 | Class { 7 | #name : #SQLite3SchemaChanged, 8 | #superclass : #SQLite3NativeError, 9 | #category : #'SQLite3-Core-Errors' 10 | } 11 | 12 | { #category : #'private - accessing' } 13 | SQLite3SchemaChanged class >> nativeErrorCode [ 14 | 15 | ^ SQLITE_SCHEMA 16 | ] 17 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3StatementExternalObject.class.st: -------------------------------------------------------------------------------- 1 | " 2 | I represent the SQLite API 'sqlite3_stmt' C-level type. 3 | 4 | " 5 | Class { 6 | #name : #SQLite3StatementExternalObject, 7 | #superclass : #FFIOpaqueObject, 8 | #category : #'SQLite3-Core-UFFI-Support' 9 | } 10 | 11 | { #category : #'instance finalization' } 12 | SQLite3StatementExternalObject class >> doFinalizeResourceData: aHandle [ 13 | 14 | SQLite3Library current ffiCall: 15 | #( int sqlite3_finalize #( void * aHandle ) ) 16 | ] 17 | 18 | { #category : #finalization } 19 | SQLite3StatementExternalObject class >> finalizeResourceData: aHandle [ 20 | 21 | self doFinalizeResourceData: aHandle. 22 | aHandle beNull 23 | ] 24 | 25 | { #category : #initialization } 26 | SQLite3StatementExternalObject >> beNull [ 27 | 28 | ^ handle beNull 29 | ] 30 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3Table.class.st: -------------------------------------------------------------------------------- 1 | " 2 | A table within a SQLite3 database 3 | " 4 | Class { 5 | #name : #SQLite3Table, 6 | #superclass : #Object, 7 | #instVars : [ 8 | 'database', 9 | 'properties' 10 | ], 11 | #category : #'SQLite3-Core-Base' 12 | } 13 | 14 | { #category : #'instance creation' } 15 | SQLite3Table class >> properties: aDictionary in: aDatabase [ 16 | ^ self new 17 | database: aDatabase; 18 | properties: aDictionary; 19 | yourself 20 | ] 21 | 22 | { #category : #accessing } 23 | SQLite3Table >> columnNames [ 24 | 25 | ^ self columns collect: [:each | each name ] 26 | ] 27 | 28 | { #category : #accessing } 29 | SQLite3Table >> columns [ 30 | 31 | ^ (self database execute: 'pragma table_info([' , self name , ']);') 32 | rowClass: SQLite3Column; 33 | rows 34 | ] 35 | 36 | { #category : #accessing } 37 | SQLite3Table >> database [ 38 | 39 | ^ database 40 | ] 41 | 42 | { #category : #'private - accessing' } 43 | SQLite3Table >> database: anObject [ 44 | 45 | database := anObject 46 | ] 47 | 48 | { #category : #accessing } 49 | SQLite3Table >> name [ 50 | 51 | ^ self properties at: #name ifAbsent: [ '' ] 52 | ] 53 | 54 | { #category : #accessing } 55 | SQLite3Table >> numberOfRows [ 56 | 57 | ^ (self database execute: 'SELECT COUNT(*) FROM [' , self name , '];') 58 | onlyValue 59 | ] 60 | 61 | { #category : #printing } 62 | SQLite3Table >> printOn: aStream [ 63 | 64 | super printOn: aStream. 65 | aStream 66 | << '("'; 67 | << self name; 68 | << '")' 69 | ] 70 | 71 | { #category : #accessing } 72 | SQLite3Table >> properties [ 73 | 74 | ^ properties ifNil: [ properties := Dictionary new ] 75 | ] 76 | 77 | { #category : #'private - accessing' } 78 | SQLite3Table >> properties: anObject [ 79 | 80 | properties := anObject 81 | ] 82 | 83 | { #category : #accessing } 84 | SQLite3Table >> rows [ 85 | 86 | ^ (self database execute: 'SELECT * 87 | FROM [' , self name , '] 88 | LIMIT 1000;') rows 89 | ] 90 | 91 | { #category : #accessing } 92 | SQLite3Table >> schema [ 93 | 94 | ^ self properties at: #sql ifAbsent: '' 95 | ] 96 | -------------------------------------------------------------------------------- /src/SQLite3-Core/SQLite3TooBig.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The SQLITE_TOOBIG error code indicates that a string or BLOB was too large. The default maximum length of a string or BLOB in SQLite is 1,000,000,000 bytes. This maximum length can be changed at compile-time using the SQLITE_MAX_LENGTH compile-time option, or at run-time using the sqlite3_limit(db,SQLITE_LIMIT_LENGTH,...) interface. The SQLITE_TOOBIG error results when SQLite encounters a string or BLOB that exceeds the compile-time or run-time limit. 3 | 4 | The SQLITE_TOOBIG error code can also result when an oversized SQL statement is passed into one of the sqlite3_prepare_v2() interfaces. The maximum length of an SQL statement defaults to a much smaller value of 1,000,000 bytes. The maximum SQL statement length can be set at compile-time using SQLITE_MAX_SQL_LENGTH or at run-time using sqlite3_limit(db,SQLITE_LIMIT_SQL_LENGTH,...). 5 | " 6 | Class { 7 | #name : #SQLite3TooBig, 8 | #superclass : #SQLite3NativeError, 9 | #category : #'SQLite3-Core-Errors' 10 | } 11 | 12 | { #category : #'private - accessing' } 13 | SQLite3TooBig class >> nativeErrorCode [ 14 | 15 | ^ SQLITE_TOOBIG 16 | ] 17 | -------------------------------------------------------------------------------- /src/SQLite3-Core/package.st: -------------------------------------------------------------------------------- 1 | Package { #name : #'SQLite3-Core' } 2 | -------------------------------------------------------------------------------- /src/SQLite3-Glorp-Tests/GlorpBlobTest.extension.st: -------------------------------------------------------------------------------- 1 | Extension { #name : #GlorpBlobTest } 2 | 3 | { #category : #'*SQLite3-Glorp-Tests' } 4 | GlorpBlobTest >> expectedFailures [ 5 | 6 | "testBlob is working with version 3.32.3 of SQLite" 7 | 8 | ^ ( IceSemanticVersion 9 | fromArray: ( ( SQLite3Library current apiLibVersion splitOn: '.' ) collect: #asNumber ) ) 10 | < ( IceSemanticVersion major: 3 minor: 32 patch: 3 ) 11 | ifTrue: [ super expectedFailures , #(testBlob) ] 12 | ifFalse: [ super expectedFailures ] 13 | ] 14 | -------------------------------------------------------------------------------- /src/SQLite3-Glorp-Tests/package.st: -------------------------------------------------------------------------------- 1 | Package { #name : #'SQLite3-Glorp-Tests' } 2 | -------------------------------------------------------------------------------- /src/SQLite3-Glorp/SQLite3BaseConnection.extension.st: -------------------------------------------------------------------------------- 1 | Extension { #name : #SQLite3BaseConnection } 2 | 3 | { #category : #'*SQLite3-Glorp' } 4 | SQLite3BaseConnection >> queryEncoding [ 5 | 6 | ^ #utf8 7 | ] 8 | -------------------------------------------------------------------------------- /src/SQLite3-Glorp/SQLite3Cursor.extension.st: -------------------------------------------------------------------------------- 1 | Extension { #name : #SQLite3Cursor } 2 | 3 | { #category : #'*SQLite3-Glorp' } 4 | SQLite3Cursor >> atEnd [ 5 | 6 | ^ moreRows not 7 | ] 8 | 9 | { #category : #'*SQLite3-Glorp' } 10 | SQLite3Cursor >> rowCount [ 11 | 12 | ^ statement ifNil: [0] ifNotNil: [ statement changes ] 13 | ] 14 | 15 | { #category : #'*SQLite3-Glorp' } 16 | SQLite3Cursor >> upToEnd [ 17 | 18 | ^ self rows 19 | ] 20 | -------------------------------------------------------------------------------- /src/SQLite3-Glorp/SQLite3Driver.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : #SQLite3Driver, 3 | #superclass : #DatabaseDriver, 4 | #instVars : [ 5 | 'isInTransaction', 6 | 'transactionMutex', 7 | 'rowCount' 8 | ], 9 | #category : #'SQLite3-Glorp' 10 | } 11 | 12 | { #category : #executing } 13 | SQLite3Driver >> basicExecuteSQLString: aString [ 14 | 15 | | result | 16 | 17 | result := self basicExecuteSQLString: aString binding: #(). 18 | rowCount := result rowCount. 19 | ^ result 20 | ] 21 | 22 | { #category : #executing } 23 | SQLite3Driver >> basicExecuteSQLString: aString binding: aBinding [ 24 | 25 | ^ connection execute: aString with: aBinding 26 | ] 27 | 28 | { #category : #transactions } 29 | SQLite3Driver >> beginTransaction [ 30 | 31 | transactionMutex 32 | critical: [ 33 | isInTransaction 34 | ifFalse: [ 35 | connection beginTransaction. 36 | isInTransaction := true 37 | ] 38 | ] 39 | ] 40 | 41 | { #category : #transactions } 42 | SQLite3Driver >> commitTransaction [ 43 | 44 | transactionMutex 45 | critical: [ 46 | isInTransaction 47 | ifTrue: [ 48 | connection commitTransaction. 49 | isInTransaction := false 50 | ] 51 | ] 52 | ] 53 | 54 | { #category : #accessing } 55 | SQLite3Driver >> connect: aLogin [ 56 | 57 | connection := self connectionClass 58 | openOn: ( aLogin host asFileReference / aLogin databaseName ) fullName 59 | ] 60 | 61 | { #category : #accessing } 62 | SQLite3Driver >> connectionClass [ 63 | 64 | ^ SQLite3Connection 65 | ] 66 | 67 | { #category : #initialization } 68 | SQLite3Driver >> initialize [ 69 | 70 | super initialize. 71 | isInTransaction := false. 72 | transactionMutex := Semaphore forMutualExclusion. 73 | rowCount := 0 74 | ] 75 | 76 | { #category : #testing } 77 | SQLite3Driver >> isConnected [ 78 | 79 | ^ connection isNotNil and: [ connection isOpen ] 80 | ] 81 | 82 | { #category : #login } 83 | SQLite3Driver >> logout [ 84 | 85 | connection close 86 | ] 87 | 88 | { #category : #transactions } 89 | SQLite3Driver >> rollbackTransaction [ 90 | 91 | transactionMutex 92 | critical: [ 93 | isInTransaction 94 | ifTrue: [ 95 | connection rollbackTransaction. 96 | isInTransaction := false 97 | ] 98 | ] 99 | ] 100 | 101 | { #category : #accessing } 102 | SQLite3Driver >> rowCount [ 103 | 104 | ^ rowCount 105 | ] 106 | -------------------------------------------------------------------------------- /src/SQLite3-Glorp/package.st: -------------------------------------------------------------------------------- 1 | Package { #name : #'SQLite3-Glorp' } 2 | -------------------------------------------------------------------------------- /src/SQLite3-Inspector-Extensions/AbstractFileReference.extension.st: -------------------------------------------------------------------------------- 1 | Extension { #name : #AbstractFileReference } 2 | 3 | { #category : #'*SQLite3-Inspector-Extensions' } 4 | AbstractFileReference >> databaseSize [ 5 | |s| 6 | s := self size. 7 | s / 1024 > 1024 ifTrue: [ ^ ((s / 1024 / 1024) roundDownTo: 0.01) asString, ' MB' ]. 8 | ^ ((s / 1024) roundDownTo: 0.01) asString, ' KB' 9 | ] 10 | 11 | { #category : #'*SQLite3-Inspector-Extensions' } 12 | AbstractFileReference >> inspectionSQLite3Info [ 13 | 14 | 15 | | label1 label2 | 16 | label1 := SpLabeledPresenter 17 | label: 'Database file:' 18 | input: (SpTextInputFieldPresenter new text: self fullName). 19 | label2 := SpLabeledPresenter 20 | label: 'Database size:' 21 | input: (SpTextInputFieldPresenter new text: self databaseSize). 22 | ^ SpPresenter new 23 | layout: (SpBoxLayout newTopToBottom 24 | add: label1; 25 | add: label2; 26 | yourself); 27 | yourself 28 | ] 29 | 30 | { #category : #'*SQLite3-Inspector-Extensions' } 31 | AbstractFileReference >> inspectionSQLite3InfoContext: aContext [ 32 | 33 | ^ aContext active: self isSQlite3Database 34 | ] 35 | 36 | { #category : #'*SQLite3-Inspector-Extensions' } 37 | AbstractFileReference >> inspectionSQLite3Tables [ 38 | 39 | 40 | ^ SpTablePresenter new 41 | items: (SQLite3Database tableInfoFor: self fullName); 42 | addColumn: (SpStringTableColumn title: 'Table Name' evaluated: [ :assoc | assoc name ]); 43 | addColumn: (SpStringTableColumn title: 'Number of Rows' evaluated: [ :assoc | assoc numberOfRows ]); 44 | yourself 45 | ] 46 | 47 | { #category : #'*SQLite3-Inspector-Extensions' } 48 | AbstractFileReference >> inspectionSQLite3TablesContext: aContext [ 49 | 50 | ^ aContext active: self isSQlite3Database 51 | ] 52 | 53 | { #category : #'*SQLite3-Inspector-Extensions' } 54 | AbstractFileReference >> isSQlite3Database [ 55 | "Return true if the reference is an SQLite3 database file" 56 | 57 | ^ self isFile and: [ 58 | self extension = 'db' and: [ 59 | (self readStreamDo: [ :s | s next: 16 ]) 60 | = ('SQLite format 3' , Character null asString) ] ] 61 | ] 62 | -------------------------------------------------------------------------------- /src/SQLite3-Inspector-Extensions/SQLite3Database.extension.st: -------------------------------------------------------------------------------- 1 | Extension { #name : #SQLite3Database } 2 | 3 | { #category : #'*SQLite3-Inspector-Extensions' } 4 | SQLite3Database >> inspectionSQLite3Tables [ 5 | 6 | 7 | ^ SpTablePresenter new 8 | items: self tables; 9 | addColumn: (SpStringTableColumn title: 'Name' evaluated: [ :assoc | assoc name ]); 10 | addColumn: (SpStringTableColumn title: 'Number of rows' evaluated: [ :assoc | assoc numberOfRows ]); 11 | yourself 12 | ] 13 | -------------------------------------------------------------------------------- /src/SQLite3-Inspector-Extensions/SQLite3Row.extension.st: -------------------------------------------------------------------------------- 1 | Extension { #name : #SQLite3Row } 2 | 3 | { #category : #'*SQLite3-Inspector-Extensions' } 4 | SQLite3Row >> inspectionSQLite3Row [ 5 | 6 | 7 | | presenter | 8 | presenter := SpTablePresenter new. 9 | presenter items: (Array with: self). 10 | self columnNames do: [:each | 11 | presenter addColumn: (SpStringTableColumn title: each evaluated: [ :assoc | self at: each ]) 12 | 13 | ]. 14 | 15 | ^presenter 16 | ] 17 | -------------------------------------------------------------------------------- /src/SQLite3-Inspector-Extensions/SQLite3Table.extension.st: -------------------------------------------------------------------------------- 1 | Extension { #name : #SQLite3Table } 2 | 3 | { #category : #'*SQLite3-Inspector-Extensions' } 4 | SQLite3Table >> inspectionSQLite3Columns [ 5 | 6 | 7 | ^ SpTablePresenter new 8 | items: self columns; 9 | addColumn: (SpStringTableColumn title: 'Column Name' evaluated: [ :each | each name ]); 10 | addColumn: (SpStringTableColumn title: 'Column Type' evaluated: [ :each | each type ]); 11 | addColumn: (SpStringTableColumn title: 'Non-empty values' evaluated: [ :each | each hasNotNullConstraint ifTrue: ['NOT NULL'] ifFalse: [''] ]); 12 | yourself 13 | ] 14 | 15 | { #category : #'*SQLite3-Inspector-Extensions' } 16 | SQLite3Table >> inspectionSQLite3Data [ 17 | 18 | 19 | | presenter | 20 | presenter := SpTablePresenter new. 21 | presenter items: self rows. 22 | 23 | self columnNames do: [:col | 24 | presenter addColumn: (SpStringTableColumn title: col evaluated: [ :each | each at: col ]) 25 | ]. 26 | ^presenter 27 | ] 28 | 29 | { #category : #'*SQLite3-Inspector-Extensions' } 30 | SQLite3Table >> inspectionSQLite3Schema [ 31 | 32 | 33 | ^ SpTextPresenter new 34 | text: self schema; 35 | yourself 36 | ] 37 | 38 | { #category : #'*SQLite3-Inspector-Extensions' } 39 | SQLite3Table >> inspectionSQLite3TableProperties [ 40 | 41 | 42 | ^ SpTablePresenter new 43 | items: self properties associations; 44 | addColumn: (SpStringTableColumn title: 'Property' evaluated: [ :assoc | assoc key ]); 45 | addColumn: (SpStringTableColumn title: 'Value' evaluated: [ :assoc | assoc value ]); 46 | yourself 47 | ] 48 | -------------------------------------------------------------------------------- /src/SQLite3-Inspector-Extensions/package.st: -------------------------------------------------------------------------------- 1 | Package { #name : #'SQLite3-Inspector-Extensions' } 2 | -------------------------------------------------------------------------------- /src/SQLite3-Pharo10/Random.extension.st: -------------------------------------------------------------------------------- 1 | Extension { #name : #Random } 2 | 3 | { #category : #'*SQLite3-Pharo10' } 4 | Random >> nextInt: anInteger [ 5 | 6 | ^ self nextInteger: anInteger 7 | ] 8 | -------------------------------------------------------------------------------- /src/SQLite3-Pharo10/package.st: -------------------------------------------------------------------------------- 1 | Package { #name : #'SQLite3-Pharo10' } 2 | -------------------------------------------------------------------------------- /src/SQLite3-Pharo8/SQLite3Library.extension.st: -------------------------------------------------------------------------------- 1 | Extension { #name : #SQLite3Library } 2 | 3 | { #category : #'*SQLite3-Pharo8' } 4 | SQLite3Library >> stringFrom: aStatement at: aColumn [ 5 | ^ self utf8StringToPharo: (self apiColumnText: aStatement atColumn: aColumn) 6 | ] 7 | 8 | { #category : #'*SQLite3-Pharo8' } 9 | SQLite3Library >> utf8StringToPharo: anUTF8String [ 10 | "Converts from SQLite UTF-8 to Pharo Multibyte Characters" 11 | 12 | ^ (ZnCharacterReadStream on: anUTF8String asByteArray readStream) upToEnd 13 | ] 14 | -------------------------------------------------------------------------------- /src/SQLite3-Pharo8/package.st: -------------------------------------------------------------------------------- 1 | Package { #name : #'SQLite3-Pharo8' } 2 | -------------------------------------------------------------------------------- /src/SQLite3-Pharo9/SQLite3Library.extension.st: -------------------------------------------------------------------------------- 1 | Extension { #name : #SQLite3Library } 2 | 3 | { #category : #'*SQLite3-Pharo9' } 4 | SQLite3Library >> stringFrom: aStatement at: aColumn [ 5 | ^ self apiColumnText: aStatement atColumn: aColumn 6 | ] 7 | -------------------------------------------------------------------------------- /src/SQLite3-Pharo9/package.st: -------------------------------------------------------------------------------- 1 | Package { #name : #'SQLite3-Pharo9' } 2 | --------------------------------------------------------------------------------