From e118e891070378ced4eab5f506fc241b5d24b3f3 Mon Sep 17 00:00:00 2001 From: Andrea Maria Piana Date: Tue, 27 Aug 2019 14:04:15 +0200 Subject: [PATCH] Add persistent datasync, use single database and handle negotiated filters (#1580) --- api/backend.go | 4 +- go.mod | 8 +- go.sum | 20 +- services/shhext/db.go | 173 - services/shhext/service.go | 107 +- services/shhext/service_test.go | 42 +- sqlite/migrate.go | 4 +- .../mutecomm/go-sqlcipher/.travis.yml | 3 +- .../mutecomm/go-sqlcipher/MAINTENANCE | 2 +- .../github.com/mutecomm/go-sqlcipher/Makefile | 8 + .../mutecomm/go-sqlcipher/README.md | 2 + .../github.com/mutecomm/go-sqlcipher/go.mod | 9 + .../github.com/mutecomm/go-sqlcipher/go.sum | 11 + .../mutecomm/go-sqlcipher/sqlite3.c | 19100 ++++++++++------ .../mutecomm/go-sqlcipher/sqlite3.h | 641 +- .../v4/database/sqlcipher/sqlcipher.go | 2 +- .../status-im/status-protocol-go/adapters.go | 11 +- .../status-protocol-go/encryption/protocol.go | 2 +- .../encryption/publisher/persistence.go | 38 +- .../encryption/publisher/publisher.go | 20 +- .../status-im/status-protocol-go/go.mod | 10 +- .../status-im/status-protocol-go/go.sum | 16 +- .../status-im/status-protocol-go/messenger.go | 52 +- .../status-im/status-protocol-go/sqlite/db.go | 40 +- .../status-protocol-go/sqlite/migrations.go | 65 + .../transport/whisper/whisper_service.go | 9 +- .../status-protocol-go/v1/status_message.go | 3 +- .../testify/assert/assertion_format.go | 82 + .../testify/assert/assertion_forward.go | 164 + .../testify/assert/assertion_order.go | 309 + .../stretchr/testify/assert/assertions.go | 96 +- .../stretchr/testify/require/require.go | 716 +- .../stretchr/testify/require/require.go.tmpl | 2 +- .../testify/require/require_forward.go | 164 + .../stretchr/testify/suite/suite.go | 80 +- .../vacp2p/mvds/node/epoch_persistency.go | 33 + .../vacp2p/mvds/node/migrations/migrations.go | 319 + vendor/github.com/vacp2p/mvds/node/node.go | 93 +- .../github.com/vacp2p/mvds/node/payloads.go | 3 +- .../mvds/peers/migrations/migrations.go | 319 + .../vacp2p/mvds/peers/persistence.go | 28 - .../vacp2p/mvds/peers/persistence_memory.go | 32 + .../vacp2p/mvds/peers/persistence_sqlite.go | 63 + .../vacp2p/mvds/persistenceutil/migrations.go | 70 + .../vacp2p/mvds/persistenceutil/sqlite.go | 124 + .../mvds/state/migrations/migrations.go | 319 + vendor/github.com/vacp2p/mvds/state/state.go | 2 +- .../vacp2p/mvds/state/state_memory.go | 2 +- .../vacp2p/mvds/state/state_sqlite.go | 166 + .../vacp2p/mvds/store/messagestore_dummy.go | 4 +- .../vacp2p/mvds/store/messagestore_sqlite.go | 67 + .../mvds/store/migrations/migrations.go | 319 + vendor/gopkg.in/yaml.v2/.travis.yml | 12 + vendor/gopkg.in/yaml.v2/LICENSE | 201 + vendor/gopkg.in/yaml.v2/LICENSE.libyaml | 31 + vendor/gopkg.in/yaml.v2/NOTICE | 13 + vendor/gopkg.in/yaml.v2/README.md | 133 + vendor/gopkg.in/yaml.v2/apic.go | 739 + vendor/gopkg.in/yaml.v2/decode.go | 775 + vendor/gopkg.in/yaml.v2/emitterc.go | 1685 ++ vendor/gopkg.in/yaml.v2/encode.go | 390 + vendor/gopkg.in/yaml.v2/go.mod | 5 + vendor/gopkg.in/yaml.v2/parserc.go | 1095 + vendor/gopkg.in/yaml.v2/readerc.go | 412 + vendor/gopkg.in/yaml.v2/resolve.go | 258 + vendor/gopkg.in/yaml.v2/scannerc.go | 2696 +++ vendor/gopkg.in/yaml.v2/sorter.go | 113 + vendor/gopkg.in/yaml.v2/writerc.go | 26 + vendor/gopkg.in/yaml.v2/yaml.go | 466 + vendor/gopkg.in/yaml.v2/yamlh.go | 738 + vendor/gopkg.in/yaml.v2/yamlprivateh.go | 173 + vendor/modules.txt | 29 +- 72 files changed, 26081 insertions(+), 7887 deletions(-) delete mode 100644 services/shhext/db.go create mode 100644 vendor/github.com/mutecomm/go-sqlcipher/Makefile create mode 100644 vendor/github.com/mutecomm/go-sqlcipher/go.mod create mode 100644 vendor/github.com/mutecomm/go-sqlcipher/go.sum create mode 100644 vendor/github.com/status-im/status-protocol-go/sqlite/migrations.go create mode 100644 vendor/github.com/stretchr/testify/assert/assertion_order.go create mode 100644 vendor/github.com/vacp2p/mvds/node/epoch_persistency.go create mode 100644 vendor/github.com/vacp2p/mvds/node/migrations/migrations.go create mode 100644 vendor/github.com/vacp2p/mvds/peers/migrations/migrations.go create mode 100644 vendor/github.com/vacp2p/mvds/peers/persistence_memory.go create mode 100644 vendor/github.com/vacp2p/mvds/peers/persistence_sqlite.go create mode 100644 vendor/github.com/vacp2p/mvds/persistenceutil/migrations.go create mode 100644 vendor/github.com/vacp2p/mvds/persistenceutil/sqlite.go create mode 100644 vendor/github.com/vacp2p/mvds/state/migrations/migrations.go create mode 100644 vendor/github.com/vacp2p/mvds/state/state_sqlite.go create mode 100644 vendor/github.com/vacp2p/mvds/store/messagestore_sqlite.go create mode 100644 vendor/github.com/vacp2p/mvds/store/migrations/migrations.go create mode 100644 vendor/gopkg.in/yaml.v2/.travis.yml create mode 100644 vendor/gopkg.in/yaml.v2/LICENSE create mode 100644 vendor/gopkg.in/yaml.v2/LICENSE.libyaml create mode 100644 vendor/gopkg.in/yaml.v2/NOTICE create mode 100644 vendor/gopkg.in/yaml.v2/README.md create mode 100644 vendor/gopkg.in/yaml.v2/apic.go create mode 100644 vendor/gopkg.in/yaml.v2/decode.go create mode 100644 vendor/gopkg.in/yaml.v2/emitterc.go create mode 100644 vendor/gopkg.in/yaml.v2/encode.go create mode 100644 vendor/gopkg.in/yaml.v2/go.mod create mode 100644 vendor/gopkg.in/yaml.v2/parserc.go create mode 100644 vendor/gopkg.in/yaml.v2/readerc.go create mode 100644 vendor/gopkg.in/yaml.v2/resolve.go create mode 100644 vendor/gopkg.in/yaml.v2/scannerc.go create mode 100644 vendor/gopkg.in/yaml.v2/sorter.go create mode 100644 vendor/gopkg.in/yaml.v2/writerc.go create mode 100644 vendor/gopkg.in/yaml.v2/yaml.go create mode 100644 vendor/gopkg.in/yaml.v2/yamlh.go create mode 100644 vendor/gopkg.in/yaml.v2/yamlprivateh.go diff --git a/api/backend.go b/api/backend.go index 3d8cebe7f..97746a858 100644 --- a/api/backend.go +++ b/api/backend.go @@ -782,7 +782,7 @@ func (b *StatusBackend) SelectAccount(loginParams account.LoginParams) error { return err } - if err := st.InitProtocolWithPassword(loginParams.ChatAddress.String(), loginParams.Password); err != nil { + if err := st.InitProtocol(b.appDB); err != nil { return err } } @@ -871,7 +871,7 @@ func (b *StatusBackend) InjectChatAccount(chatKeyHex, encryptionKeyHex string) e return err } - if err := st.InitProtocolWithEncyptionKey(chatAccount.Address.Hex(), encryptionKeyHex); err != nil { + if err := st.InitProtocol(b.appDB); err != nil { return err } } diff --git a/go.mod b/go.mod index 0685b16f2..0091c9074 100644 --- a/go.mod +++ b/go.mod @@ -15,15 +15,15 @@ require ( github.com/lib/pq v1.0.0 github.com/libp2p/go-libp2p-core v0.0.3 github.com/multiformats/go-multiaddr v0.0.4 - github.com/mutecomm/go-sqlcipher v0.0.0-20170920224653-f799951b4ab2 + github.com/mutecomm/go-sqlcipher v0.0.0-20190227152316-55dbde17881f github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222 github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a github.com/status-im/doubleratchet v2.0.0+incompatible - github.com/status-im/migrate/v4 v4.3.1-status + github.com/status-im/migrate/v4 v4.0.0-20190821140204-a9d340ec8fb76af4afda06acf01740d45d2661ed github.com/status-im/rendezvous v1.3.0 - github.com/status-im/status-protocol-go v0.0.0-20190701094942-9f0db157bf5a1ac9b52c47bbea37fc7dbe14e8fe + github.com/status-im/status-protocol-go v0.0.0-20190701094942-1dd03f74d712ac9b965b718963dc86ca9c3540fb github.com/status-im/whisper v1.4.14 - github.com/stretchr/testify v1.3.0 + github.com/stretchr/testify v1.3.1-0.20190712000136-221dbe5ed467 github.com/syndtr/goleveldb v1.0.0 go.uber.org/zap v1.10.0 golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 diff --git a/go.sum b/go.sum index 7ad9f12d5..f6d55b00e 100644 --- a/go.sum +++ b/go.sum @@ -365,8 +365,8 @@ github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= -github.com/mutecomm/go-sqlcipher v0.0.0-20170920224653-f799951b4ab2 h1:Q5L04ENac5Rx1K+vuxM7cjsrCgqSJNumYy3SHOQC4ec= -github.com/mutecomm/go-sqlcipher v0.0.0-20170920224653-f799951b4ab2/go.mod h1:S9Hougr2LhvUtZGY1fCTj9nr9P53lfsCCQ2XqVMFZX8= +github.com/mutecomm/go-sqlcipher v0.0.0-20190227152316-55dbde17881f h1:hd3r+uv9DNLScbOrnlj82rBldHQf3XWmCeXAWbw8euQ= +github.com/mutecomm/go-sqlcipher v0.0.0-20190227152316-55dbde17881f/go.mod h1:MyUWrZlB1aI5bs7j9/pJ8ckLLZ4QcCYcNiSbsAW32D4= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8/go.mod h1:86wM1zFnC6/uDBfZGNwB65O+pR2OFi5q/YQaEUid1qA= github.com/naoina/toml v0.0.0-20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= @@ -446,30 +446,31 @@ github.com/status-im/go-fcm v1.0.0-status h1:eUNKm4ooAXdEf9/GaTYeTELna5aVMOEbzjb github.com/status-im/go-fcm v1.0.0-status/go.mod h1:0JGzul9SfemcbTdw0mkzLR42j+BTNci5aQWlI0o/uk8= github.com/status-im/go-multiaddr-ethv4 v1.2.0 h1:OT84UsUzTCwguqCpJqkrCMiL4VZ1SvUtH9a5MsZupBk= github.com/status-im/go-multiaddr-ethv4 v1.2.0/go.mod h1:2VQ3C+9zEurcceasz12gPAtmEzCeyLUGPeKLSXYQKHo= -github.com/status-im/migrate/v4 v4.3.1-status h1:tJwsEYLgbFkvlTSMk89APwRDfpr4yG8wcwPeudsqPwo= -github.com/status-im/migrate/v4 v4.3.1-status/go.mod h1:r8HggRBZ/k7TRwByq/Hp3P/ubFppIna0nvyavVK0pjA= +github.com/status-im/migrate/v4 v4.0.0-20190821140204-a9d340ec8fb76af4afda06acf01740d45d2661ed h1:K2iga8l8OQIHnk2bBq2QsZTO2Q38YWy04xIspdITCdM= +github.com/status-im/migrate/v4 v4.0.0-20190821140204-a9d340ec8fb76af4afda06acf01740d45d2661ed/go.mod h1:r8HggRBZ/k7TRwByq/Hp3P/ubFppIna0nvyavVK0pjA= github.com/status-im/rendezvous v1.3.0 h1:7RK/MXXW+tlm0asKm1u7Qp7Yni6AO29a7j8+E4Lbjg4= github.com/status-im/rendezvous v1.3.0/go.mod h1:+hzjuP+j/XzLPeF6E50b88pWOTLdTcwjvNYt+Gh1W1s= -github.com/status-im/status-protocol-go v0.0.0-20190701094942-9f0db157bf5a1ac9b52c47bbea37fc7dbe14e8fe h1:QqpJe7fgZk8nKWfjUiYi9SCoN3Ozveyn60b8xWq3rik= -github.com/status-im/status-protocol-go v0.0.0-20190701094942-9f0db157bf5a1ac9b52c47bbea37fc7dbe14e8fe/go.mod h1:thrQ4V0ZUmLZPDf74xVzub1gxgSNFaSTeTQdxtRJnTU= +github.com/status-im/status-protocol-go v0.0.0-20190701094942-1dd03f74d712ac9b965b718963dc86ca9c3540fb h1:zJ7gHLGOw3CeTOri61Y6dO+j/vxlg8TKxFgydMWErnU= +github.com/status-im/status-protocol-go v0.0.0-20190701094942-1dd03f74d712ac9b965b718963dc86ca9c3540fb/go.mod h1:ASO3pqc3cEFT3LPKfClp4f39jbP1m2XvSmIfBk9Ssxc= github.com/status-im/whisper v1.4.14 h1:9VHqx4+PUYfhDnYYtDxHkg/3cfVvkHjPNciY4LO83yc= github.com/status-im/whisper v1.4.14/go.mod h1:WS6z39YJQ8WJa9s+DmTuEM/s2nVF6Iz3B1SZYw5cYf0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v0.0.0-20170809224252-890a5c3458b4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v0.0.0-20190716104307-221dbe5ed46703ee255b1da0dec05086f5035f62/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.3.1-0.20190712000136-221dbe5ed467 h1:/pva5wyh0PKqe0bnHBbndEzbqsilMKFNXI0GPbO+L8c= +github.com/stretchr/testify v1.3.1-0.20190712000136-221dbe5ed467/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/syndtr/goleveldb v0.0.0-20181128100959-b001fa50d6b2/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/uber/jaeger-client-go v0.0.0-20180607151842-f7e0d4744fa6/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v0.0.0-20180615202729-a51202d6f4a7/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/vacp2p/mvds v0.0.19 h1:ZXopUNicQPzmIsggqa9Pbd6cqphFiyhthe3kneuJpC8= -github.com/vacp2p/mvds v0.0.19/go.mod h1:MxvN/VFp5zkjhUfJdBft+NrsVDwMsvueDIP2x0h6Tx8= +github.com/vacp2p/mvds v0.0.0-20190705123435-a8dc37599bf99958b0ea19431c9bb7a47bd7fa8f h1:iBJcVbX4RaPtufXJ/PJtCF1jYPzlmyEF+imcQq5pTDs= +github.com/vacp2p/mvds v0.0.0-20190705123435-a8dc37599bf99958b0ea19431c9bb7a47bd7fa8f/go.mod h1:Xc3UWtA230lUzZoXStJHQd/BkqJK5BAZyXBsiR6XrXM= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= @@ -523,6 +524,7 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190225153610-fe579d43d832/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= diff --git a/services/shhext/db.go b/services/shhext/db.go deleted file mode 100644 index 8e6c0876d..000000000 --- a/services/shhext/db.go +++ /dev/null @@ -1,173 +0,0 @@ -package shhext - -import ( - "fmt" - "os" - - sqliteDriver "github.com/mutecomm/go-sqlcipher" // We require go sqlcipher that overrides default implementation - - "github.com/status-im/status-protocol-go/sqlite" -) - -const exportDB = "SELECT sqlcipher_export('newdb')" - -// The default number of kdf iterations in sqlcipher (from version 3.0.0) -// https://github.com/sqlcipher/sqlcipher/blob/fda4c68bb474da7e955be07a2b807bda1bb19bd2/CHANGELOG.md#300---2013-11-05 -// https://www.zetetic.net/sqlcipher/sqlcipher-api/#kdf_iter -const defaultKdfIterationsNumber = 64000 - -// The reduced number of kdf iterations (for performance reasons) which is -// currently used for derivation of the database key -// https://github.com/status-im/status-go/pull/1343 -// https://notes.status.im/i8Y_l7ccTiOYq09HVgoFwA -const KdfIterationsNumber = 3200 - -func migrateDBFile(oldPath string, newPath string, oldKey string, newKey string) error { - _, err := os.Stat(oldPath) - - // No files, nothing to do - if os.IsNotExist(err) { - return nil - } - - // Any other error, throws - if err != nil { - return err - } - - if err := os.Rename(oldPath, newPath); err != nil { - return err - } - - db, err := sqlite.OpenWithIter(newPath, oldKey, defaultKdfIterationsNumber, sqlite.MigrationConfig{}) - if err != nil { - return err - } - - keyString := fmt.Sprintf("PRAGMA rekey = '%s'", newKey) - - if _, err = db.Exec(keyString); err != nil { - return err - } - - return nil -} - -// migrateDBKeyKdfIterations changes the number of kdf iterations executed -// during the database key derivation. This change is necessary because -// of performance reasons. -// https://github.com/status-im/status-go/pull/1343 -// `sqlcipher_export` is used for migration, check out this link for details: -// https://www.zetetic.net/sqlcipher/sqlcipher-api/#sqlcipher_export -func migrateDBKeyKdfIterations(oldPath string, newPath string, key string) error { - _, err := os.Stat(oldPath) - - // No files, nothing to do - if os.IsNotExist(err) { - return nil - } - - // Any other error, throws - if err != nil { - return err - } - - isEncrypted, err := sqliteDriver.IsEncrypted(oldPath) - if err != nil { - return err - } - - // Nothing to do, move db to the next migration - if !isEncrypted { - return os.Rename(oldPath, newPath) - } - - db, err := sqlite.OpenWithIter(oldPath, key, defaultKdfIterationsNumber, sqlite.MigrationConfig{}) - if err != nil { - return err - } - - attach := fmt.Sprintf( - "ATTACH DATABASE '%s' AS newdb KEY '%s'", - newPath, - key) - - if _, err = db.Exec(attach); err != nil { - return err - } - - changeKdfIter := fmt.Sprintf( - "PRAGMA newdb.kdf_iter = %d", - KdfIterationsNumber) - - if _, err = db.Exec(changeKdfIter); err != nil { - return err - } - - if _, err = db.Exec(exportDB); err != nil { - return err - } - - if err = db.Close(); err != nil { - return err - } - - return os.Remove(oldPath) -} - -// encryptDatabase encrypts an unencrypted database with key -func encryptDatabase(oldPath string, newPath string, key string) error { - _, err := os.Stat(oldPath) - - // No files, nothing to do - if os.IsNotExist(err) { - return nil - } - - // Any other error, throws - if err != nil { - return err - } - - isEncrypted, err := sqliteDriver.IsEncrypted(oldPath) - if err != nil { - return err - } - - // Nothing to do, already encrypted - if isEncrypted { - return os.Rename(oldPath, newPath) - } - - db, err := sqlite.OpenWithIter(oldPath, "", defaultKdfIterationsNumber, sqlite.MigrationConfig{}) - if err != nil { - return err - } - - attach := fmt.Sprintf( - "ATTACH DATABASE '%s' AS newdb KEY '%s'", - newPath, - key) - - if _, err = db.Exec(attach); err != nil { - return err - } - - changeKdfIter := fmt.Sprintf( - "PRAGMA newdb.kdf_iter = %d", - KdfIterationsNumber) - - if _, err = db.Exec(changeKdfIter); err != nil { - return err - } - - if _, err = db.Exec(exportDB); err != nil { - return err - } - - if err = db.Close(); err != nil { - return err - } - - return os.Remove(oldPath) -} diff --git a/services/shhext/service.go b/services/shhext/service.go index c1569cad5..91c291042 100644 --- a/services/shhext/service.go +++ b/services/shhext/service.go @@ -3,6 +3,7 @@ package shhext import ( "context" "crypto/ecdsa" + "database/sql" "fmt" "github.com/status-im/status-go/logutils" "os" @@ -27,7 +28,6 @@ import ( whisper "github.com/status-im/whisper/whisperv6" "github.com/syndtr/goleveldb/leveldb" "go.uber.org/zap" - "golang.org/x/crypto/sha3" ) const ( @@ -97,18 +97,7 @@ func New(w *whisper.Whisper, handler EnvelopeEventsHandler, ldb *leveldb.DB, con } } -func (s *Service) InitProtocolWithPassword(address string, password string) error { - digest := sha3.Sum256([]byte(password)) - encKey := fmt.Sprintf("%x", digest) - return s.initProtocol(address, encKey, password) -} - -// InitProtocolWithEncyptionKey creates an instance of ProtocolService given an address and encryption key. -func (s *Service) InitProtocolWithEncyptionKey(address string, encKey string) error { - return s.initProtocol(address, encKey, "") -} - -func (s *Service) initProtocol(address, encKey, password string) error { // nolint: gocyclo +func (s *Service) InitProtocol(db *sql.DB) error { // nolint: gocyclo if !s.config.PFSEnabled { return nil } @@ -118,70 +107,6 @@ func (s *Service) initProtocol(address, encKey, password string) error { // noli if err := os.MkdirAll(dataDir, os.ModePerm); err != nil { return err } - v0Path := filepath.Join(dataDir, fmt.Sprintf("%x.db", address)) - v1Path := filepath.Join(dataDir, fmt.Sprintf("%s.db", s.config.InstallationID)) - v2Path := filepath.Join(dataDir, fmt.Sprintf("%s.v2.db", s.config.InstallationID)) - v3Path := filepath.Join(dataDir, fmt.Sprintf("%s.v3.db", s.config.InstallationID)) - v4Path := filepath.Join(dataDir, fmt.Sprintf("%s.v4.db", s.config.InstallationID)) - - if password != "" { - if err := migrateDBFile(v0Path, v1Path, "ON", password); err != nil { - return err - } - - if err := migrateDBFile(v1Path, v2Path, password, encKey); err != nil { - // Remove db file as created with a blank password and never used, - // and there's no need to rekey in this case - os.Remove(v1Path) - os.Remove(v2Path) - } - } - - if err := migrateDBKeyKdfIterations(v2Path, v3Path, encKey); err != nil { - os.Remove(v2Path) - os.Remove(v3Path) - } - - // Fix IOS not encrypting database - if err := encryptDatabase(v3Path, v4Path, encKey); err != nil { - os.Remove(v3Path) - os.Remove(v4Path) - } - - // Desktop was passing a network dependent directory, which meant that - // if running on testnet it would not access the right db. This copies - // the db from mainnet to the root location. - networkDependentPath := filepath.Join(dataDir, "ethereum", "mainnet_rpc", fmt.Sprintf("%s.v4.db", s.config.InstallationID)) - if _, err := os.Stat(networkDependentPath); err == nil { - if err := os.Rename(networkDependentPath, v4Path); err != nil { - return err - } - } else if !os.IsNotExist(err) { - return err - } - - // In one of the versions, we split the database file into multiple ones. - // Later, we discovered that it really hurts the performance so we consolidated - // it again but in a better way keeping migrations in separate packages. - sessionsDatabasePath := filepath.Join(dataDir, fmt.Sprintf("%s.sessions.v4.sql", s.config.InstallationID)) - sessionsStat, sessionsStatErr := os.Stat(sessionsDatabasePath) - v4PathStat, v4PathStatErr := os.Stat(v4Path) - - if sessionsStatErr == nil && os.IsNotExist(v4PathStatErr) { - // This is a clear situation where we have the sessions.v4.sql file and v4Path does not exist. - // In the previous migration, we removed v4Path when it is successfully copied into the sessions sql file. - if err := os.Rename(sessionsDatabasePath, v4Path); err != nil { - return err - } - } else if sessionsStatErr == nil && v4PathStatErr == nil { - // Both files exist so probably the migration to split databases failed. - if sessionsStat.ModTime().After(v4PathStat.ModTime()) { - // Sessions sql file is newer. - if err := os.Rename(sessionsDatabasePath, v4Path); err != nil { - return err - } - } - } // Create a custom zap.Logger which will forward logs from status-protocol-go to status-go logger. zapLogger, err := logutils.NewZapLoggerWithAdapter(logutils.Logger()) @@ -198,7 +123,7 @@ func (s *Service) initProtocol(address, encKey, password string) error { // noli EnvelopeEventsHandler: EnvelopeSignalHandler{}, Logger: zapLogger, } - options := buildMessengerOptions(s.config, v4Path, encKey, envelopesMonitorConfig, zapLogger) + options := buildMessengerOptions(s.config, db, envelopesMonitorConfig, zapLogger) selectedKeyID := s.w.SelectedKeyPairID() identity, err := s.w.GetPrivateKey(selectedKeyID) @@ -439,12 +364,34 @@ func (s *Service) syncMessages(ctx context.Context, mailServerID []byte, r whisp } } -func buildMessengerOptions(config params.ShhextConfig, dbPath, dbKey string, envelopesMonitorConfig *protocolwhisper.EnvelopesMonitorConfig, logger *zap.Logger) []protocol.Option { +func onNegotiatedFilters(filters []*protocolwhisper.Filter) { + var signalFilters []*signal.Filter + for _, filter := range filters { + + signalFilter := &signal.Filter{ + ChatID: filter.ChatID, + SymKeyID: filter.SymKeyID, + Listen: filter.Listen, + FilterID: filter.FilterID, + Identity: filter.Identity, + Topic: filter.Topic, + } + + signalFilters = append(signalFilters, signalFilter) + } + if len(filters) != 0 { + handler := PublisherSignalHandler{} + handler.WhisperFilterAdded(signalFilters) + } +} + +func buildMessengerOptions(config params.ShhextConfig, db *sql.DB, envelopesMonitorConfig *protocolwhisper.EnvelopesMonitorConfig, logger *zap.Logger) []protocol.Option { options := []protocol.Option{ protocol.WithCustomLogger(logger), - protocol.WithDatabaseConfig(dbPath, dbKey), + protocol.WithDatabase(db), protocol.WithEnvelopesMonitorConfig(envelopesMonitorConfig), + protocol.WithOnNegotiatedFilters(onNegotiatedFilters), } if !config.DisableGenericDiscoveryTopic { diff --git a/services/shhext/service_test.go b/services/shhext/service_test.go index 3191446f7..ed55c7f74 100644 --- a/services/shhext/service_test.go +++ b/services/shhext/service_test.go @@ -20,13 +20,13 @@ import ( "github.com/ethereum/go-ethereum/p2p/enode" "github.com/status-im/status-go/mailserver" "github.com/status-im/status-go/params" + "github.com/status-im/status-go/sqlite" "github.com/status-im/status-go/t/helpers" "github.com/status-im/status-go/t/utils" whisper "github.com/status-im/whisper/whisperv6" "github.com/stretchr/testify/suite" "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/storage" - "golang.org/x/crypto/sha3" ) const ( @@ -132,7 +132,14 @@ func (s *ShhExtSuite) SetupTest() { db, err := leveldb.Open(storage.NewMemStorage(), nil) s.Require().NoError(err) s.services[i] = New(s.whisper[i], nil, db, config) - s.Require().NoError(s.services[i].InitProtocolWithPassword(fmt.Sprintf("%d", i), "password")) + + tmpdir, err := ioutil.TempDir("", "test-shhext-service") + s.Require().NoError(err) + + sqlDB, err := sqlite.OpenDB(fmt.Sprintf("%s/%d", tmpdir, i), "password") + s.Require().NoError(err) + + s.Require().NoError(s.services[i].InitProtocol(sqlDB)) s.NoError(stack.Register(func(n *node.ServiceContext) (node.Service, error) { return s.services[i], nil })) @@ -163,12 +170,13 @@ func (s *ShhExtSuite) TestInitProtocol() { service := New(shh, nil, db, config) - err = service.InitProtocolWithPassword("example-address", "`090///\nhtaa\rhta9x8923)$$'23") - s.NoError(err) + tmpdir, err := ioutil.TempDir("", "test-shhext-service-init-protocol") + s.Require().NoError(err) - digest := sha3.Sum256([]byte("`090///\nhtaa\rhta9x8923)$$'23")) - encKey := fmt.Sprintf("%x", digest) - err = service.InitProtocolWithEncyptionKey("example-address", encKey) + sqlDB, err := sqlite.OpenDB(fmt.Sprintf("%s/db.sql", tmpdir), "password") + s.Require().NoError(err) + + err = service.InitProtocol(sqlDB) s.NoError(err) } @@ -307,7 +315,14 @@ func (s *ShhExtSuite) TestRequestMessagesSuccess() { PFSEnabled: true, } service := New(shh, mock, nil, config) - s.Require().NoError(service.InitProtocolWithPassword("abc", "password")) + + tmpdir, err := ioutil.TempDir("", "test-shhext-service-request-messages") + s.Require().NoError(err) + + sqlDB, err := sqlite.OpenDB(fmt.Sprintf("%s/db.sql", tmpdir), "password") + s.Require().NoError(err) + + s.Require().NoError(service.InitProtocol(sqlDB)) s.Require().NoError(service.Start(aNode.Server())) api := NewPublicAPI(service) @@ -525,7 +540,14 @@ func (s *RequestWithTrackingHistorySuite) SetupTest() { s.localContext = NewContextFromService(context.Background(), s.localService, s.localService.storage) localPkey, err := crypto.GenerateKey() s.Require().NoError(err) - s.Require().NoError(s.localService.InitProtocolWithPassword("local-service", "password")) + + tmpdir, err := ioutil.TempDir("", "test-shhext-service") + s.Require().NoError(err) + + sqlDB, err := sqlite.OpenDB(fmt.Sprintf("%s/db.sql", tmpdir), "password") + s.Require().NoError(err) + + s.Require().NoError(s.localService.InitProtocol(sqlDB)) s.Require().NoError(s.localService.Start(&p2p.Server{Config: p2p.Config{PrivateKey: localPkey}})) s.localAPI = NewPublicAPI(s.localService) @@ -535,7 +557,7 @@ func (s *RequestWithTrackingHistorySuite) SetupTest() { s.remoteMailserver = &mailserver.WMailServer{} remote.RegisterServer(s.remoteMailserver) password := "test" - tmpdir, err := ioutil.TempDir("", "tracking-history-tests-") + tmpdir, err = ioutil.TempDir("", "tracking-history-tests-") s.Require().NoError(err) s.Require().NoError(s.remoteMailserver.Init(remote, ¶ms.WhisperConfig{ DataDir: tmpdir, diff --git a/sqlite/migrate.go b/sqlite/migrate.go index 895c5c380..29b6ff960 100644 --- a/sqlite/migrate.go +++ b/sqlite/migrate.go @@ -15,7 +15,9 @@ func Migrate(db *sql.DB, resources *bindata.AssetSource) error { return err } - driver, err := sqlcipher.WithInstance(db, &sqlcipher.Config{}) + driver, err := sqlcipher.WithInstance(db, &sqlcipher.Config{ + MigrationsTable: "status_go_" + sqlcipher.DefaultMigrationsTable, + }) if err != nil { return err } diff --git a/vendor/github.com/mutecomm/go-sqlcipher/.travis.yml b/vendor/github.com/mutecomm/go-sqlcipher/.travis.yml index 9e820def7..1a46db04a 100644 --- a/vendor/github.com/mutecomm/go-sqlcipher/.travis.yml +++ b/vendor/github.com/mutecomm/go-sqlcipher/.travis.yml @@ -1,6 +1,7 @@ language: go -go: 1.8 +go: 1.12 before_install: - go get github.com/frankbraun/gocheck + - go get -t github.com/mutecomm/go-sqlcipher script: - gocheck -g -c -e _example -e sqlite3_test diff --git a/vendor/github.com/mutecomm/go-sqlcipher/MAINTENANCE b/vendor/github.com/mutecomm/go-sqlcipher/MAINTENANCE index 972ce0a7e..490f17f81 100644 --- a/vendor/github.com/mutecomm/go-sqlcipher/MAINTENANCE +++ b/vendor/github.com/mutecomm/go-sqlcipher/MAINTENANCE @@ -26,7 +26,7 @@ sqlite3_test/sqltest.go Update code from https://github.com/sqlcipher/sqlcipher ------------------------------------------------------- -Current release: v3.4.1 +Current release: v3.4.2 Execute: ./configure diff --git a/vendor/github.com/mutecomm/go-sqlcipher/Makefile b/vendor/github.com/mutecomm/go-sqlcipher/Makefile new file mode 100644 index 000000000..e734b30a6 --- /dev/null +++ b/vendor/github.com/mutecomm/go-sqlcipher/Makefile @@ -0,0 +1,8 @@ +.PHONY: all update-modules + +all: + env GO111MODULE=on go build -v . ./_example/simple/... + +update-modules: + env GO111MODULE=on go get -u + env GO111MODULE=on go mod tidy -v diff --git a/vendor/github.com/mutecomm/go-sqlcipher/README.md b/vendor/github.com/mutecomm/go-sqlcipher/README.md index e34ccfabf..0d79ab053 100644 --- a/vendor/github.com/mutecomm/go-sqlcipher/README.md +++ b/vendor/github.com/mutecomm/go-sqlcipher/README.md @@ -11,6 +11,8 @@ conforming to the built-in database/sql interface. It is based on: SQLite itself is part of SQLCipher. +go-sqlcipher currently only supports the SQLCipher 3.x releases. + ### Installation diff --git a/vendor/github.com/mutecomm/go-sqlcipher/go.mod b/vendor/github.com/mutecomm/go-sqlcipher/go.mod new file mode 100644 index 000000000..4e1b6e61e --- /dev/null +++ b/vendor/github.com/mutecomm/go-sqlcipher/go.mod @@ -0,0 +1,9 @@ +module github.com/mutecomm/go-sqlcipher + +go 1.12 + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/stretchr/testify v1.3.0 + golang.org/x/net v0.0.0-20190225153610-fe579d43d832 +) diff --git a/vendor/github.com/mutecomm/go-sqlcipher/go.sum b/vendor/github.com/mutecomm/go-sqlcipher/go.sum new file mode 100644 index 000000000..ad18f81b2 --- /dev/null +++ b/vendor/github.com/mutecomm/go-sqlcipher/go.sum @@ -0,0 +1,11 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +golang.org/x/net v0.0.0-20190225153610-fe579d43d832 h1:2IdId8zoI92l1bUzjAOygcAOkmCe13HY1j0rqPPPzB8= +golang.org/x/net v0.0.0-20190225153610-fe579d43d832/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= diff --git a/vendor/github.com/mutecomm/go-sqlcipher/sqlite3.c b/vendor/github.com/mutecomm/go-sqlcipher/sqlite3.c index 3aee1fb5a..cc40a9f4e 100644 --- a/vendor/github.com/mutecomm/go-sqlcipher/sqlite3.c +++ b/vendor/github.com/mutecomm/go-sqlcipher/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.15.2. By combining all the individual C code files into this +** version 3.20.1. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -22,6 +22,758 @@ #ifndef SQLITE_PRIVATE # define SQLITE_PRIVATE static #endif +/************** Begin file ctime.c *******************************************/ +/* +** 2010 February 23 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file implements routines used to report what compile-time options +** SQLite was built with. +*/ + +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS + +/* +** Include the configuration header output by 'configure' if we're using the +** autoconf-based build +*/ +#if defined(_HAVE_SQLITE_CONFIG_H) && !defined(SQLITECONFIG_H) +#include "config.h" +#define SQLITECONFIG_H 1 +#endif + +/* These macros are provided to "stringify" the value of the define +** for those options in which the value is meaningful. */ +#define CTIMEOPT_VAL_(opt) #opt +#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt) + +/* +** An array of names of all compile-time options. This array should +** be sorted A-Z. +** +** This array looks large, but in a typical installation actually uses +** only a handful of compile-time options, so most times this array is usually +** rather short and uses little memory space. +*/ +static const char * const sqlite3azCompileOpt[] = { + +/* +** BEGIN CODE GENERATED BY tool/mkctime.tcl +*/ +#if SQLITE_32BIT_ROWID + "32BIT_ROWID", +#endif +#if SQLITE_4_BYTE_ALIGNED_MALLOC + "4_BYTE_ALIGNED_MALLOC", +#endif +#if SQLITE_64BIT_STATS + "64BIT_STATS", +#endif +#if SQLITE_ALLOW_COVERING_INDEX_SCAN + "ALLOW_COVERING_INDEX_SCAN", +#endif +#if SQLITE_ALLOW_URI_AUTHORITY + "ALLOW_URI_AUTHORITY", +#endif +#ifdef SQLITE_BITMASK_TYPE + "BITMASK_TYPE=" CTIMEOPT_VAL(SQLITE_BITMASK_TYPE), +#endif +#if SQLITE_BUG_COMPATIBLE_20160819 + "BUG_COMPATIBLE_20160819", +#endif +#if SQLITE_CASE_SENSITIVE_LIKE + "CASE_SENSITIVE_LIKE", +#endif +#if SQLITE_CHECK_PAGES + "CHECK_PAGES", +#endif +#if defined(__clang__) && defined(__clang_major__) + "COMPILER=clang-" CTIMEOPT_VAL(__clang_major__) "." + CTIMEOPT_VAL(__clang_minor__) "." + CTIMEOPT_VAL(__clang_patchlevel__), +#elif defined(_MSC_VER) + "COMPILER=msvc-" CTIMEOPT_VAL(_MSC_VER), +#elif defined(__GNUC__) && defined(__VERSION__) + "COMPILER=gcc-" __VERSION__, +#endif +#if SQLITE_COVERAGE_TEST + "COVERAGE_TEST", +#endif +#if SQLITE_DEBUG + "DEBUG", +#endif +#if SQLITE_DEFAULT_AUTOMATIC_INDEX + "DEFAULT_AUTOMATIC_INDEX", +#endif +#if SQLITE_DEFAULT_AUTOVACUUM + "DEFAULT_AUTOVACUUM", +#endif +#ifdef SQLITE_DEFAULT_CACHE_SIZE + "DEFAULT_CACHE_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_CACHE_SIZE), +#endif +#if SQLITE_DEFAULT_CKPTFULLFSYNC + "DEFAULT_CKPTFULLFSYNC", +#endif +#ifdef SQLITE_DEFAULT_FILE_FORMAT + "DEFAULT_FILE_FORMAT=" CTIMEOPT_VAL(SQLITE_DEFAULT_FILE_FORMAT), +#endif +#ifdef SQLITE_DEFAULT_FILE_PERMISSIONS + "DEFAULT_FILE_PERMISSIONS=" CTIMEOPT_VAL(SQLITE_DEFAULT_FILE_PERMISSIONS), +#endif +#if SQLITE_DEFAULT_FOREIGN_KEYS + "DEFAULT_FOREIGN_KEYS", +#endif +#ifdef SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT + "DEFAULT_JOURNAL_SIZE_LIMIT=" CTIMEOPT_VAL(SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT), +#endif +#ifdef SQLITE_DEFAULT_LOCKING_MODE + "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE), +#endif +#ifdef SQLITE_DEFAULT_LOOKASIDE + "DEFAULT_LOOKASIDE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOOKASIDE), +#endif +#if SQLITE_DEFAULT_MEMSTATUS + "DEFAULT_MEMSTATUS", +#endif +#ifdef SQLITE_DEFAULT_MMAP_SIZE + "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE), +#endif +#ifdef SQLITE_DEFAULT_PAGE_SIZE + "DEFAULT_PAGE_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_PAGE_SIZE), +#endif +#ifdef SQLITE_DEFAULT_PCACHE_INITSZ + "DEFAULT_PCACHE_INITSZ=" CTIMEOPT_VAL(SQLITE_DEFAULT_PCACHE_INITSZ), +#endif +#ifdef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS + "DEFAULT_PROXYDIR_PERMISSIONS=" CTIMEOPT_VAL(SQLITE_DEFAULT_PROXYDIR_PERMISSIONS), +#endif +#if SQLITE_DEFAULT_RECURSIVE_TRIGGERS + "DEFAULT_RECURSIVE_TRIGGERS", +#endif +#ifdef SQLITE_DEFAULT_ROWEST + "DEFAULT_ROWEST=" CTIMEOPT_VAL(SQLITE_DEFAULT_ROWEST), +#endif +#ifdef SQLITE_DEFAULT_SECTOR_SIZE + "DEFAULT_SECTOR_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_SECTOR_SIZE), +#endif +#ifdef SQLITE_DEFAULT_SYNCHRONOUS + "DEFAULT_SYNCHRONOUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_SYNCHRONOUS), +#endif +#ifdef SQLITE_DEFAULT_WAL_AUTOCHECKPOINT + "DEFAULT_WAL_AUTOCHECKPOINT=" CTIMEOPT_VAL(SQLITE_DEFAULT_WAL_AUTOCHECKPOINT), +#endif +#ifdef SQLITE_DEFAULT_WAL_SYNCHRONOUS + "DEFAULT_WAL_SYNCHRONOUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_WAL_SYNCHRONOUS), +#endif +#ifdef SQLITE_DEFAULT_WORKER_THREADS + "DEFAULT_WORKER_THREADS=" CTIMEOPT_VAL(SQLITE_DEFAULT_WORKER_THREADS), +#endif +#if SQLITE_DIRECT_OVERFLOW_READ + "DIRECT_OVERFLOW_READ", +#endif +#if SQLITE_DISABLE_DIRSYNC + "DISABLE_DIRSYNC", +#endif +#if SQLITE_DISABLE_FTS3_UNICODE + "DISABLE_FTS3_UNICODE", +#endif +#if SQLITE_DISABLE_FTS4_DEFERRED + "DISABLE_FTS4_DEFERRED", +#endif +#if SQLITE_DISABLE_INTRINSIC + "DISABLE_INTRINSIC", +#endif +#if SQLITE_DISABLE_LFS + "DISABLE_LFS", +#endif +#if SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS + "DISABLE_PAGECACHE_OVERFLOW_STATS", +#endif +#if SQLITE_DISABLE_SKIPAHEAD_DISTINCT + "DISABLE_SKIPAHEAD_DISTINCT", +#endif +#ifdef SQLITE_ENABLE_8_3_NAMES + "ENABLE_8_3_NAMES=" CTIMEOPT_VAL(SQLITE_ENABLE_8_3_NAMES), +#endif +#if SQLITE_ENABLE_API_ARMOR + "ENABLE_API_ARMOR", +#endif +#if SQLITE_ENABLE_ATOMIC_WRITE + "ENABLE_ATOMIC_WRITE", +#endif +#if SQLITE_ENABLE_CEROD + "ENABLE_CEROD", +#endif +#if SQLITE_ENABLE_COLUMN_METADATA + "ENABLE_COLUMN_METADATA", +#endif +#if SQLITE_ENABLE_COLUMN_USED_MASK + "ENABLE_COLUMN_USED_MASK", +#endif +#if SQLITE_ENABLE_COSTMULT + "ENABLE_COSTMULT", +#endif +#if SQLITE_ENABLE_CURSOR_HINTS + "ENABLE_CURSOR_HINTS", +#endif +#if SQLITE_ENABLE_DBSTAT_VTAB + "ENABLE_DBSTAT_VTAB", +#endif +#if SQLITE_ENABLE_EXPENSIVE_ASSERT + "ENABLE_EXPENSIVE_ASSERT", +#endif +#if SQLITE_ENABLE_FTS1 + "ENABLE_FTS1", +#endif +#if SQLITE_ENABLE_FTS2 + "ENABLE_FTS2", +#endif +#if SQLITE_ENABLE_FTS3 + "ENABLE_FTS3", +#endif +#if SQLITE_ENABLE_FTS3_PARENTHESIS + "ENABLE_FTS3_PARENTHESIS", +#endif +#if SQLITE_ENABLE_FTS3_TOKENIZER + "ENABLE_FTS3_TOKENIZER", +#endif +#if SQLITE_ENABLE_FTS4 + "ENABLE_FTS4", +#endif +#if SQLITE_ENABLE_FTS5 + "ENABLE_FTS5", +#endif +#if SQLITE_ENABLE_HIDDEN_COLUMNS + "ENABLE_HIDDEN_COLUMNS", +#endif +#if SQLITE_ENABLE_ICU + "ENABLE_ICU", +#endif +#if SQLITE_ENABLE_IOTRACE + "ENABLE_IOTRACE", +#endif +#if SQLITE_ENABLE_JSON1 + "ENABLE_JSON1", +#endif +#if SQLITE_ENABLE_LOAD_EXTENSION + "ENABLE_LOAD_EXTENSION", +#endif +#ifdef SQLITE_ENABLE_LOCKING_STYLE + "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE), +#endif +#if SQLITE_ENABLE_MEMORY_MANAGEMENT + "ENABLE_MEMORY_MANAGEMENT", +#endif +#if SQLITE_ENABLE_MEMSYS3 + "ENABLE_MEMSYS3", +#endif +#if SQLITE_ENABLE_MEMSYS5 + "ENABLE_MEMSYS5", +#endif +#if SQLITE_ENABLE_MULTIPLEX + "ENABLE_MULTIPLEX", +#endif +#if SQLITE_ENABLE_NULL_TRIM + "ENABLE_NULL_TRIM", +#endif +#if SQLITE_ENABLE_OVERSIZE_CELL_CHECK + "ENABLE_OVERSIZE_CELL_CHECK", +#endif +#if SQLITE_ENABLE_PREUPDATE_HOOK + "ENABLE_PREUPDATE_HOOK", +#endif +#if SQLITE_ENABLE_QPSG + "ENABLE_QPSG", +#endif +#if SQLITE_ENABLE_RBU + "ENABLE_RBU", +#endif +#if SQLITE_ENABLE_RTREE + "ENABLE_RTREE", +#endif +#if SQLITE_ENABLE_SELECTTRACE + "ENABLE_SELECTTRACE", +#endif +#if SQLITE_ENABLE_SESSION + "ENABLE_SESSION", +#endif +#if SQLITE_ENABLE_SNAPSHOT + "ENABLE_SNAPSHOT", +#endif +#if SQLITE_ENABLE_SQLLOG + "ENABLE_SQLLOG", +#endif +#if defined(SQLITE_ENABLE_STAT4) + "ENABLE_STAT4", +#elif defined(SQLITE_ENABLE_STAT3) + "ENABLE_STAT3", +#endif +#if SQLITE_ENABLE_STMTVTAB + "ENABLE_STMTVTAB", +#endif +#if SQLITE_ENABLE_STMT_SCANSTATUS + "ENABLE_STMT_SCANSTATUS", +#endif +#if SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION + "ENABLE_UNKNOWN_SQL_FUNCTION", +#endif +#if SQLITE_ENABLE_UNLOCK_NOTIFY + "ENABLE_UNLOCK_NOTIFY", +#endif +#if SQLITE_ENABLE_UPDATE_DELETE_LIMIT + "ENABLE_UPDATE_DELETE_LIMIT", +#endif +#if SQLITE_ENABLE_URI_00_ERROR + "ENABLE_URI_00_ERROR", +#endif +#if SQLITE_ENABLE_VFSTRACE + "ENABLE_VFSTRACE", +#endif +#if SQLITE_ENABLE_WHERETRACE + "ENABLE_WHERETRACE", +#endif +#if SQLITE_ENABLE_ZIPVFS + "ENABLE_ZIPVFS", +#endif +#if SQLITE_EXPLAIN_ESTIMATED_ROWS + "EXPLAIN_ESTIMATED_ROWS", +#endif +#if SQLITE_EXTRA_IFNULLROW + "EXTRA_IFNULLROW", +#endif +#ifdef SQLITE_EXTRA_INIT + "EXTRA_INIT=" CTIMEOPT_VAL(SQLITE_EXTRA_INIT), +#endif +#ifdef SQLITE_EXTRA_SHUTDOWN + "EXTRA_SHUTDOWN=" CTIMEOPT_VAL(SQLITE_EXTRA_SHUTDOWN), +#endif +#ifdef SQLITE_FTS3_MAX_EXPR_DEPTH + "FTS3_MAX_EXPR_DEPTH=" CTIMEOPT_VAL(SQLITE_FTS3_MAX_EXPR_DEPTH), +#endif +#if SQLITE_FTS5_ENABLE_TEST_MI + "FTS5_ENABLE_TEST_MI", +#endif +#if SQLITE_FTS5_NO_WITHOUT_ROWID + "FTS5_NO_WITHOUT_ROWID", +#endif +#if SQLITE_HAS_CODEC + "HAS_CODEC", +#endif +#if HAVE_ISNAN || SQLITE_HAVE_ISNAN + "HAVE_ISNAN", +#endif +#if SQLITE_HOMEGROWN_RECURSIVE_MUTEX + "HOMEGROWN_RECURSIVE_MUTEX", +#endif +#if SQLITE_IGNORE_AFP_LOCK_ERRORS + "IGNORE_AFP_LOCK_ERRORS", +#endif +#if SQLITE_IGNORE_FLOCK_LOCK_ERRORS + "IGNORE_FLOCK_LOCK_ERRORS", +#endif +#if SQLITE_INLINE_MEMCPY + "INLINE_MEMCPY", +#endif +#if SQLITE_INT64_TYPE + "INT64_TYPE", +#endif +#ifdef SQLITE_INTEGRITY_CHECK_ERROR_MAX + "INTEGRITY_CHECK_ERROR_MAX=" CTIMEOPT_VAL(SQLITE_INTEGRITY_CHECK_ERROR_MAX), +#endif +#if SQLITE_LIKE_DOESNT_MATCH_BLOBS + "LIKE_DOESNT_MATCH_BLOBS", +#endif +#if SQLITE_LOCK_TRACE + "LOCK_TRACE", +#endif +#if SQLITE_LOG_CACHE_SPILL + "LOG_CACHE_SPILL", +#endif +#ifdef SQLITE_MALLOC_SOFT_LIMIT + "MALLOC_SOFT_LIMIT=" CTIMEOPT_VAL(SQLITE_MALLOC_SOFT_LIMIT), +#endif +#ifdef SQLITE_MAX_ATTACHED + "MAX_ATTACHED=" CTIMEOPT_VAL(SQLITE_MAX_ATTACHED), +#endif +#ifdef SQLITE_MAX_COLUMN + "MAX_COLUMN=" CTIMEOPT_VAL(SQLITE_MAX_COLUMN), +#endif +#ifdef SQLITE_MAX_COMPOUND_SELECT + "MAX_COMPOUND_SELECT=" CTIMEOPT_VAL(SQLITE_MAX_COMPOUND_SELECT), +#endif +#ifdef SQLITE_MAX_DEFAULT_PAGE_SIZE + "MAX_DEFAULT_PAGE_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_DEFAULT_PAGE_SIZE), +#endif +#ifdef SQLITE_MAX_EXPR_DEPTH + "MAX_EXPR_DEPTH=" CTIMEOPT_VAL(SQLITE_MAX_EXPR_DEPTH), +#endif +#ifdef SQLITE_MAX_FUNCTION_ARG + "MAX_FUNCTION_ARG=" CTIMEOPT_VAL(SQLITE_MAX_FUNCTION_ARG), +#endif +#ifdef SQLITE_MAX_LENGTH + "MAX_LENGTH=" CTIMEOPT_VAL(SQLITE_MAX_LENGTH), +#endif +#ifdef SQLITE_MAX_LIKE_PATTERN_LENGTH + "MAX_LIKE_PATTERN_LENGTH=" CTIMEOPT_VAL(SQLITE_MAX_LIKE_PATTERN_LENGTH), +#endif +#ifdef SQLITE_MAX_MEMORY + "MAX_MEMORY=" CTIMEOPT_VAL(SQLITE_MAX_MEMORY), +#endif +#ifdef SQLITE_MAX_MMAP_SIZE + "MAX_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE), +#endif +#ifdef SQLITE_MAX_MMAP_SIZE_ + "MAX_MMAP_SIZE_=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE_), +#endif +#ifdef SQLITE_MAX_PAGE_COUNT + "MAX_PAGE_COUNT=" CTIMEOPT_VAL(SQLITE_MAX_PAGE_COUNT), +#endif +#ifdef SQLITE_MAX_PAGE_SIZE + "MAX_PAGE_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_PAGE_SIZE), +#endif +#ifdef SQLITE_MAX_SCHEMA_RETRY + "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY), +#endif +#ifdef SQLITE_MAX_SQL_LENGTH + "MAX_SQL_LENGTH=" CTIMEOPT_VAL(SQLITE_MAX_SQL_LENGTH), +#endif +#ifdef SQLITE_MAX_TRIGGER_DEPTH + "MAX_TRIGGER_DEPTH=" CTIMEOPT_VAL(SQLITE_MAX_TRIGGER_DEPTH), +#endif +#ifdef SQLITE_MAX_VARIABLE_NUMBER + "MAX_VARIABLE_NUMBER=" CTIMEOPT_VAL(SQLITE_MAX_VARIABLE_NUMBER), +#endif +#ifdef SQLITE_MAX_VDBE_OP + "MAX_VDBE_OP=" CTIMEOPT_VAL(SQLITE_MAX_VDBE_OP), +#endif +#ifdef SQLITE_MAX_WORKER_THREADS + "MAX_WORKER_THREADS=" CTIMEOPT_VAL(SQLITE_MAX_WORKER_THREADS), +#endif +#if SQLITE_MEMDEBUG + "MEMDEBUG", +#endif +#if SQLITE_MIXED_ENDIAN_64BIT_FLOAT + "MIXED_ENDIAN_64BIT_FLOAT", +#endif +#if SQLITE_MMAP_READWRITE + "MMAP_READWRITE", +#endif +#if SQLITE_MUTEX_NOOP + "MUTEX_NOOP", +#endif +#if SQLITE_MUTEX_NREF + "MUTEX_NREF", +#endif +#if SQLITE_MUTEX_OMIT + "MUTEX_OMIT", +#endif +#if SQLITE_MUTEX_PTHREADS + "MUTEX_PTHREADS", +#endif +#if SQLITE_MUTEX_W32 + "MUTEX_W32", +#endif +#if SQLITE_NEED_ERR_NAME + "NEED_ERR_NAME", +#endif +#if SQLITE_NOINLINE + "NOINLINE", +#endif +#if SQLITE_NO_SYNC + "NO_SYNC", +#endif +#if SQLITE_OMIT_ALTERTABLE + "OMIT_ALTERTABLE", +#endif +#if SQLITE_OMIT_ANALYZE + "OMIT_ANALYZE", +#endif +#if SQLITE_OMIT_ATTACH + "OMIT_ATTACH", +#endif +#if SQLITE_OMIT_AUTHORIZATION + "OMIT_AUTHORIZATION", +#endif +#if SQLITE_OMIT_AUTOINCREMENT + "OMIT_AUTOINCREMENT", +#endif +#if SQLITE_OMIT_AUTOINIT + "OMIT_AUTOINIT", +#endif +#if SQLITE_OMIT_AUTOMATIC_INDEX + "OMIT_AUTOMATIC_INDEX", +#endif +#if SQLITE_OMIT_AUTORESET + "OMIT_AUTORESET", +#endif +#if SQLITE_OMIT_AUTOVACUUM + "OMIT_AUTOVACUUM", +#endif +#if SQLITE_OMIT_BETWEEN_OPTIMIZATION + "OMIT_BETWEEN_OPTIMIZATION", +#endif +#if SQLITE_OMIT_BLOB_LITERAL + "OMIT_BLOB_LITERAL", +#endif +#if SQLITE_OMIT_BTREECOUNT + "OMIT_BTREECOUNT", +#endif +#if SQLITE_OMIT_CAST + "OMIT_CAST", +#endif +#if SQLITE_OMIT_CHECK + "OMIT_CHECK", +#endif +#if SQLITE_OMIT_COMPLETE + "OMIT_COMPLETE", +#endif +#if SQLITE_OMIT_COMPOUND_SELECT + "OMIT_COMPOUND_SELECT", +#endif +#if SQLITE_OMIT_CONFLICT_CLAUSE + "OMIT_CONFLICT_CLAUSE", +#endif +#if SQLITE_OMIT_CTE + "OMIT_CTE", +#endif +#if SQLITE_OMIT_DATETIME_FUNCS + "OMIT_DATETIME_FUNCS", +#endif +#if SQLITE_OMIT_DECLTYPE + "OMIT_DECLTYPE", +#endif +#if SQLITE_OMIT_DEPRECATED + "OMIT_DEPRECATED", +#endif +#if SQLITE_OMIT_DISKIO + "OMIT_DISKIO", +#endif +#if SQLITE_OMIT_EXPLAIN + "OMIT_EXPLAIN", +#endif +#if SQLITE_OMIT_FLAG_PRAGMAS + "OMIT_FLAG_PRAGMAS", +#endif +#if SQLITE_OMIT_FLOATING_POINT + "OMIT_FLOATING_POINT", +#endif +#if SQLITE_OMIT_FOREIGN_KEY + "OMIT_FOREIGN_KEY", +#endif +#if SQLITE_OMIT_GET_TABLE + "OMIT_GET_TABLE", +#endif +#if SQLITE_OMIT_HEX_INTEGER + "OMIT_HEX_INTEGER", +#endif +#if SQLITE_OMIT_INCRBLOB + "OMIT_INCRBLOB", +#endif +#if SQLITE_OMIT_INTEGRITY_CHECK + "OMIT_INTEGRITY_CHECK", +#endif +#if SQLITE_OMIT_LIKE_OPTIMIZATION + "OMIT_LIKE_OPTIMIZATION", +#endif +#if SQLITE_OMIT_LOAD_EXTENSION + "OMIT_LOAD_EXTENSION", +#endif +#if SQLITE_OMIT_LOCALTIME + "OMIT_LOCALTIME", +#endif +#if SQLITE_OMIT_LOOKASIDE + "OMIT_LOOKASIDE", +#endif +#if SQLITE_OMIT_MEMORYDB + "OMIT_MEMORYDB", +#endif +#if SQLITE_OMIT_OR_OPTIMIZATION + "OMIT_OR_OPTIMIZATION", +#endif +#if SQLITE_OMIT_PAGER_PRAGMAS + "OMIT_PAGER_PRAGMAS", +#endif +#if SQLITE_OMIT_PARSER_TRACE + "OMIT_PARSER_TRACE", +#endif +#if SQLITE_OMIT_POPEN + "OMIT_POPEN", +#endif +#if SQLITE_OMIT_PRAGMA + "OMIT_PRAGMA", +#endif +#if SQLITE_OMIT_PROGRESS_CALLBACK + "OMIT_PROGRESS_CALLBACK", +#endif +#if SQLITE_OMIT_QUICKBALANCE + "OMIT_QUICKBALANCE", +#endif +#if SQLITE_OMIT_REINDEX + "OMIT_REINDEX", +#endif +#if SQLITE_OMIT_SCHEMA_PRAGMAS + "OMIT_SCHEMA_PRAGMAS", +#endif +#if SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS + "OMIT_SCHEMA_VERSION_PRAGMAS", +#endif +#if SQLITE_OMIT_SHARED_CACHE + "OMIT_SHARED_CACHE", +#endif +#if SQLITE_OMIT_SHUTDOWN_DIRECTORIES + "OMIT_SHUTDOWN_DIRECTORIES", +#endif +#if SQLITE_OMIT_SUBQUERY + "OMIT_SUBQUERY", +#endif +#if SQLITE_OMIT_TCL_VARIABLE + "OMIT_TCL_VARIABLE", +#endif +#if SQLITE_OMIT_TEMPDB + "OMIT_TEMPDB", +#endif +#if SQLITE_OMIT_TEST_CONTROL + "OMIT_TEST_CONTROL", +#endif +#if SQLITE_OMIT_TRACE + "OMIT_TRACE", +#endif +#if SQLITE_OMIT_TRIGGER + "OMIT_TRIGGER", +#endif +#if SQLITE_OMIT_TRUNCATE_OPTIMIZATION + "OMIT_TRUNCATE_OPTIMIZATION", +#endif +#if SQLITE_OMIT_UTF16 + "OMIT_UTF16", +#endif +#if SQLITE_OMIT_VACUUM + "OMIT_VACUUM", +#endif +#if SQLITE_OMIT_VIEW + "OMIT_VIEW", +#endif +#if SQLITE_OMIT_VIRTUALTABLE + "OMIT_VIRTUALTABLE", +#endif +#if SQLITE_OMIT_WAL + "OMIT_WAL", +#endif +#if SQLITE_OMIT_WSD + "OMIT_WSD", +#endif +#if SQLITE_OMIT_XFER_OPT + "OMIT_XFER_OPT", +#endif +#if SQLITE_PCACHE_SEPARATE_HEADER + "PCACHE_SEPARATE_HEADER", +#endif +#if SQLITE_PERFORMANCE_TRACE + "PERFORMANCE_TRACE", +#endif +#if SQLITE_POWERSAFE_OVERWRITE + "POWERSAFE_OVERWRITE", +#endif +#if SQLITE_PREFER_PROXY_LOCKING + "PREFER_PROXY_LOCKING", +#endif +#if SQLITE_PROXY_DEBUG + "PROXY_DEBUG", +#endif +#if SQLITE_REVERSE_UNORDERED_SELECTS + "REVERSE_UNORDERED_SELECTS", +#endif +#if SQLITE_RTREE_INT_ONLY + "RTREE_INT_ONLY", +#endif +#if SQLITE_SECURE_DELETE + "SECURE_DELETE", +#endif +#if SQLITE_SMALL_STACK + "SMALL_STACK", +#endif +#ifdef SQLITE_SORTER_PMASZ + "SORTER_PMASZ=" CTIMEOPT_VAL(SQLITE_SORTER_PMASZ), +#endif +#if SQLITE_SOUNDEX + "SOUNDEX", +#endif +#ifdef SQLITE_STAT4_SAMPLES + "STAT4_SAMPLES=" CTIMEOPT_VAL(SQLITE_STAT4_SAMPLES), +#endif +#ifdef SQLITE_STMTJRNL_SPILL + "STMTJRNL_SPILL=" CTIMEOPT_VAL(SQLITE_STMTJRNL_SPILL), +#endif +#if SQLITE_SUBSTR_COMPATIBILITY + "SUBSTR_COMPATIBILITY", +#endif +#if SQLITE_SYSTEM_MALLOC + "SYSTEM_MALLOC", +#endif +#if SQLITE_TCL + "TCL", +#endif +#ifdef SQLITE_TEMP_STORE + "TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE), +#endif +#if SQLITE_TEST + "TEST", +#endif +#if defined(SQLITE_THREADSAFE) + "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE), +#elif defined(THREADSAFE) + "THREADSAFE=" CTIMEOPT_VAL(THREADSAFE), +#else + "THREADSAFE=1", +#endif +#if SQLITE_UNLINK_AFTER_CLOSE + "UNLINK_AFTER_CLOSE", +#endif +#if SQLITE_UNTESTABLE + "UNTESTABLE", +#endif +#if SQLITE_USER_AUTHENTICATION + "USER_AUTHENTICATION", +#endif +#if SQLITE_USE_ALLOCA + "USE_ALLOCA", +#endif +#if SQLITE_USE_FCNTL_TRACE + "USE_FCNTL_TRACE", +#endif +#if SQLITE_USE_URI + "USE_URI", +#endif +#if SQLITE_VDBE_COVERAGE + "VDBE_COVERAGE", +#endif +#if SQLITE_WIN32_MALLOC + "WIN32_MALLOC", +#endif +#if SQLITE_ZERO_MALLOC + "ZERO_MALLOC", +#endif +/* +** END CODE GENERATED BY tool/mkctime.tcl +*/ +}; + +SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt){ + *pnOpt = sizeof(sqlite3azCompileOpt) / sizeof(sqlite3azCompileOpt[0]); + return (const char**)sqlite3azCompileOpt; +} + +#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ + +/************** End of ctime.c ***********************************************/ /************** Begin file sqliteInt.h ***************************************/ /* ** 2001 September 15 @@ -204,12 +956,29 @@ # define _LARGEFILE_SOURCE 1 #endif -/* What version of GCC is being used. 0 means GCC is not being used */ -#ifdef __GNUC__ +/* The GCC_VERSION and MSVC_VERSION macros are used to +** conditionally include optimizations for each of these compilers. A +** value of 0 means that compiler is not being used. The +** SQLITE_DISABLE_INTRINSIC macro means do not use any compiler-specific +** optimizations, and hence set all compiler macros to 0 +** +** There was once also a CLANG_VERSION macro. However, we learn that the +** version numbers in clang are for "marketing" only and are inconsistent +** and unreliable. Fortunately, all versions of clang also recognize the +** gcc version numbers and have reasonable settings for gcc version numbers, +** so the GCC_VERSION macro will be set to a correct non-zero value even +** when compiling with clang. +*/ +#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC) # define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__) #else # define GCC_VERSION 0 #endif +#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC) +# define MSVC_VERSION _MSC_VER +#else +# define MSVC_VERSION 0 +#endif /* Needed for various definitions... */ #if defined(__GNUC__) && !defined(_GNU_SOURCE) @@ -259,7 +1028,7 @@ /************** Include sqlite3.h in the middle of sqliteInt.h ***************/ /************** Begin file sqlite3.h *****************************************/ /* -** 2001 September 15 +** 2001-09-15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: @@ -374,20 +1143,20 @@ extern "C" { ** system. ^The SQLITE_SOURCE_ID macro evaluates to ** a string which identifies a particular check-in of SQLite ** within its configuration management system. ^The SQLITE_SOURCE_ID -** string contains the date and time of the check-in (UTC) and an SHA1 -** hash of the entire source tree. +** string contains the date and time of the check-in (UTC) and a SHA1 +** or SHA3-256 hash of the entire source tree. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.15.2" -#define SQLITE_VERSION_NUMBER 3015002 -#define SQLITE_SOURCE_ID "2016-11-28 19:13:37 bbd85d235f7037c6a033a9690534391ffeacecc8" +#define SQLITE_VERSION "3.20.1" +#define SQLITE_VERSION_NUMBER 3020001 +#define SQLITE_SOURCE_ID "2017-08-24 16:21:36 8d3a7ea6c5690d6b7c3767558f4f01b511c55463e3f9e64506801fe9b74dce34" /* ** CAPI3REF: Run-Time Library Version Numbers -** KEYWORDS: sqlite3_version, sqlite3_sourceid +** KEYWORDS: sqlite3_version sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros @@ -519,7 +1288,11 @@ typedef struct sqlite3 sqlite3; */ #ifdef SQLITE_INT64_TYPE typedef SQLITE_INT64_TYPE sqlite_int64; - typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; +# ifdef SQLITE_UINT64_TYPE + typedef SQLITE_UINT64_TYPE sqlite_uint64; +# else + typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; +# endif #elif defined(_MSC_VER) || defined(__BORLANDC__) typedef __int64 sqlite_int64; typedef unsigned __int64 sqlite_uint64; @@ -673,7 +1446,7 @@ SQLITE_API int sqlite3_exec( */ #define SQLITE_OK 0 /* Successful result */ /* beginning-of-error-codes */ -#define SQLITE_ERROR 1 /* SQL error or missing database */ +#define SQLITE_ERROR 1 /* Generic error */ #define SQLITE_INTERNAL 2 /* Internal logic error in SQLite */ #define SQLITE_PERM 3 /* Access permission denied */ #define SQLITE_ABORT 4 /* Callback routine requested an abort */ @@ -688,7 +1461,7 @@ SQLITE_API int sqlite3_exec( #define SQLITE_FULL 13 /* Insertion failed because database is full */ #define SQLITE_CANTOPEN 14 /* Unable to open the database file */ #define SQLITE_PROTOCOL 15 /* Database lock protocol error */ -#define SQLITE_EMPTY 16 /* Database is empty */ +#define SQLITE_EMPTY 16 /* Not used */ #define SQLITE_SCHEMA 17 /* The database schema changed */ #define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ #define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ @@ -696,7 +1469,7 @@ SQLITE_API int sqlite3_exec( #define SQLITE_MISUSE 21 /* Library used incorrectly */ #define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ #define SQLITE_AUTH 23 /* Authorization denied */ -#define SQLITE_FORMAT 24 /* Auxiliary database format error */ +#define SQLITE_FORMAT 24 /* Not used */ #define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */ #define SQLITE_NOTADB 26 /* File opened that is not a database file */ #define SQLITE_NOTICE 27 /* Notifications from sqlite3_log() */ @@ -832,7 +1605,7 @@ SQLITE_API int sqlite3_exec( ** file that were written at the application level might have changed ** and that adjacent bytes, even bytes within the same sector are ** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN -** flag indicate that a file cannot be deleted when open. The +** flag indicates that a file cannot be deleted when open. The ** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on ** read-only media and cannot be changed even by processes with ** elevated privileges. @@ -982,6 +1755,9 @@ struct sqlite3_file { **
  • [SQLITE_IOCAP_ATOMIC64K] **
  • [SQLITE_IOCAP_SAFE_APPEND] **
  • [SQLITE_IOCAP_SEQUENTIAL] +**
  • [SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN] +**
  • [SQLITE_IOCAP_POWERSAFE_OVERWRITE] +**
  • [SQLITE_IOCAP_IMMUTABLE] ** ** ** The SQLITE_IOCAP_ATOMIC property means that all writes of @@ -1110,7 +1886,7 @@ struct sqlite3_io_methods { ** opcode allows these two values (10 retries and 25 milliseconds of delay) ** to be adjusted. The values are changed for all database connections ** within the same process. The argument is a pointer to an array of two -** integers where the first integer i the new retry count and the second +** integers where the first integer is the new retry count and the second ** integer is the delay. If either integer is negative, then the setting ** is not changed but instead the prior value of that setting is written ** into the array entry, allowing the current retry settings to be @@ -1295,6 +2071,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_VFS_POINTER 27 #define SQLITE_FCNTL_JOURNAL_POINTER 28 #define SQLITE_FCNTL_WIN32_GET_HANDLE 29 +#define SQLITE_FCNTL_PDB 30 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE @@ -2247,6 +3024,29 @@ struct sqlite3_mem_methods { ** until after the database connection closes. ** ** +**
    SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE
    +**
    Usually, when a database in wal mode is closed or detached from a +** database handle, SQLite checks if this will mean that there are now no +** connections at all to the database. If so, it performs a checkpoint +** operation before closing the connection. This option may be used to +** override this behaviour. The first parameter passed to this operation +** is an integer - non-zero to disable checkpoints-on-close, or zero (the +** default) to enable them. The second parameter is a pointer to an integer +** into which is written 0 or 1 to indicate whether checkpoints-on-close +** have been disabled - 0 if they are not disabled, 1 if they are. +**
    +** +**
    SQLITE_DBCONFIG_ENABLE_QPSG
    +**
    ^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates +** the [query planner stability guarantee] (QPSG). When the QPSG is active, +** a single SQL query statement will always use the same algorithm regardless +** of values of [bound parameters].)^ The QPSG disables some query optimizations +** that look at the values of bound parameters, which can make some queries +** slower. But the QPSG has the advantage of more predictable behavior. With +** the QPSG active, SQLite will always use the same query plan in the field as +** was used during testing in the lab. +**
    +** ** */ #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ @@ -2255,6 +3055,8 @@ struct sqlite3_mem_methods { #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */ +#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */ +#define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */ /* @@ -2279,20 +3081,30 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff); ** the table has a column of type [INTEGER PRIMARY KEY] then that column ** is another alias for the rowid. ** -** ^The sqlite3_last_insert_rowid(D) interface returns the [rowid] of the -** most recent successful [INSERT] into a rowid table or [virtual table] -** on database connection D. -** ^Inserts into [WITHOUT ROWID] tables are not recorded. -** ^If no successful [INSERT]s into rowid tables -** have ever occurred on the database connection D, -** then sqlite3_last_insert_rowid(D) returns zero. +** ^The sqlite3_last_insert_rowid(D) interface usually returns the [rowid] of +** the most recent successful [INSERT] into a rowid table or [virtual table] +** on database connection D. ^Inserts into [WITHOUT ROWID] tables are not +** recorded. ^If no successful [INSERT]s into rowid tables have ever occurred +** on the database connection D, then sqlite3_last_insert_rowid(D) returns +** zero. ** -** ^(If an [INSERT] occurs within a trigger or within a [virtual table] -** method, then this routine will return the [rowid] of the inserted -** row as long as the trigger or virtual table method is running. -** But once the trigger or virtual table method ends, the value returned -** by this routine reverts to what it was before the trigger or virtual -** table method began.)^ +** As well as being set automatically as rows are inserted into database +** tables, the value returned by this function may be set explicitly by +** [sqlite3_set_last_insert_rowid()] +** +** Some virtual table implementations may INSERT rows into rowid tables as +** part of committing a transaction (e.g. to flush data accumulated in memory +** to disk). In this case subsequent calls to this function return the rowid +** associated with these internal INSERT operations, which leads to +** unintuitive results. Virtual table implementations that do write to rowid +** tables in this way can avoid this problem by restoring the original +** rowid value using [sqlite3_set_last_insert_rowid()] before returning +** control to the user. +** +** ^(If an [INSERT] occurs within a trigger then this routine will +** return the [rowid] of the inserted row as long as the trigger is +** running. Once the trigger program ends, the value returned +** by this routine reverts to what it was before the trigger was fired.)^ ** ** ^An [INSERT] that fails due to a constraint violation is not a ** successful [INSERT] and does not change the value returned by this @@ -2319,6 +3131,16 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff); */ SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); +/* +** CAPI3REF: Set the Last Insert Rowid value. +** METHOD: sqlite3 +** +** The sqlite3_set_last_insert_rowid(D, R) method allows the application to +** set the value returned by calling sqlite3_last_insert_rowid(D) to R +** without inserting a row into the database. +*/ +SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); + /* ** CAPI3REF: Count The Number Of Rows Modified ** METHOD: sqlite3 @@ -2430,9 +3252,6 @@ SQLITE_API int sqlite3_total_changes(sqlite3*); ** ^A call to sqlite3_interrupt(D) that occurs when there are no running ** SQL statements is a no-op and has no effect on SQL statements ** that are started after the sqlite3_interrupt() call returns. -** -** If the database connection closes while [sqlite3_interrupt()] -** is running then bad things will likely happen. */ SQLITE_API void sqlite3_interrupt(sqlite3*); @@ -2895,12 +3714,14 @@ SQLITE_API void sqlite3_randomness(int N, void *P); /* ** CAPI3REF: Compile-Time Authorization Callbacks ** METHOD: sqlite3 +** KEYWORDS: {authorizer callback} ** ** ^This routine registers an authorizer callback with a particular ** [database connection], supplied in the first argument. ** ^The authorizer callback is invoked as SQL statements are being compiled ** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], -** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. ^At various +** [sqlite3_prepare_v3()], [sqlite3_prepare16()], [sqlite3_prepare16_v2()], +** and [sqlite3_prepare16_v3()]. ^At various ** points during the compilation process, as logic is being created ** to perform various actions, the authorizer callback is invoked to ** see if those actions are allowed. ^The authorizer callback should @@ -2922,8 +3743,10 @@ SQLITE_API void sqlite3_randomness(int N, void *P); ** parameter to the sqlite3_set_authorizer() interface. ^The second parameter ** to the callback is an integer [SQLITE_COPY | action code] that specifies ** the particular action to be authorized. ^The third through sixth parameters -** to the callback are zero-terminated strings that contain additional -** details about the action to be authorized. +** to the callback are either NULL pointers or zero-terminated strings +** that contain additional details about the action to be authorized. +** Applications must always be prepared to encounter a NULL pointer in any +** of the third through the sixth parameters of the authorization callback. ** ** ^If the action code is [SQLITE_READ] ** and the callback returns [SQLITE_IGNORE] then the @@ -2932,6 +3755,10 @@ SQLITE_API void sqlite3_randomness(int N, void *P); ** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE] ** return can be used to deny an untrusted user access to individual ** columns of a table. +** ^When a table is referenced by a [SELECT] but no column values are +** extracted from that table (for example in a query like +** "SELECT count(*) FROM tab") then the [SQLITE_READ] authorizer callback +** is invoked once for that table with a column name that is an empty string. ** ^If the action code is [SQLITE_DELETE] and the callback returns ** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the ** [truncate optimization] is disabled and all rows are deleted individually. @@ -3643,9 +4470,9 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** ** [[SQLITE_LIMIT_VDBE_OP]] ^(
    SQLITE_LIMIT_VDBE_OP
    **
    The maximum number of instructions in a virtual machine program -** used to implement an SQL statement. This limit is not currently -** enforced, though that might be added in some future release of -** SQLite.
    )^ +** used to implement an SQL statement. If [sqlite3_prepare_v2()] or +** the equivalent tries to allocate space for more than this many opcodes +** in a single prepared statement, an SQLITE_NOMEM error is returned.)^ ** ** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(
    SQLITE_LIMIT_FUNCTION_ARG
    **
    The maximum number of arguments on a function.
    )^ @@ -3683,23 +4510,59 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); #define SQLITE_LIMIT_TRIGGER_DEPTH 10 #define SQLITE_LIMIT_WORKER_THREADS 11 +/* +** CAPI3REF: Prepare Flags +** +** These constants define various flags that can be passed into +** "prepFlags" parameter of the [sqlite3_prepare_v3()] and +** [sqlite3_prepare16_v3()] interfaces. +** +** New flags may be added in future releases of SQLite. +** +**
    +** [[SQLITE_PREPARE_PERSISTENT]] ^(
    SQLITE_PREPARE_PERSISTENT
    +**
    The SQLITE_PREPARE_PERSISTENT flag is a hint to the query planner +** that the prepared statement will be retained for a long time and +** probably reused many times.)^ ^Without this flag, [sqlite3_prepare_v3()] +** and [sqlite3_prepare16_v3()] assume that the prepared statement will +** be used just once or at most a few times and then destroyed using +** [sqlite3_finalize()] relatively soon. The current implementation acts +** on this hint by avoiding the use of [lookaside memory] so as not to +** deplete the limited store of lookaside memory. Future versions of +** SQLite may act on this hint differently. +**
    +*/ +#define SQLITE_PREPARE_PERSISTENT 0x01 + /* ** CAPI3REF: Compiling An SQL Statement ** KEYWORDS: {SQL statement compiler} ** METHOD: sqlite3 ** CONSTRUCTOR: sqlite3_stmt ** -** To execute an SQL query, it must first be compiled into a byte-code -** program using one of these routines. +** To execute an SQL statement, it must first be compiled into a byte-code +** program using one of these routines. Or, in other words, these routines +** are constructors for the [prepared statement] object. +** +** The preferred routine to use is [sqlite3_prepare_v2()]. The +** [sqlite3_prepare()] interface is legacy and should be avoided. +** [sqlite3_prepare_v3()] has an extra "prepFlags" option that is used +** for special purposes. +** +** The use of the UTF-8 interfaces is preferred, as SQLite currently +** does all parsing using UTF-8. The UTF-16 interfaces are provided +** as a convenience. The UTF-16 interfaces work by converting the +** input text into UTF-8, then invoking the corresponding UTF-8 interface. ** ** The first argument, "db", is a [database connection] obtained from a ** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or ** [sqlite3_open16()]. The database connection must not have been closed. ** ** The second argument, "zSql", is the statement to be compiled, encoded -** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2() -** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2() -** use UTF-16. +** as either UTF-8 or UTF-16. The sqlite3_prepare(), sqlite3_prepare_v2(), +** and sqlite3_prepare_v3() +** interfaces use UTF-8, and sqlite3_prepare16(), sqlite3_prepare16_v2(), +** and sqlite3_prepare16_v3() use UTF-16. ** ** ^If the nByte argument is negative, then zSql is read up to the ** first zero terminator. ^If nByte is positive, then it is the @@ -3726,10 +4589,11 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** ^On success, the sqlite3_prepare() family of routines return [SQLITE_OK]; ** otherwise an [error code] is returned. ** -** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are -** recommended for all new programs. The two older interfaces are retained -** for backwards compatibility, but their use is discouraged. -** ^In the "v2" interfaces, the prepared statement +** The sqlite3_prepare_v2(), sqlite3_prepare_v3(), sqlite3_prepare16_v2(), +** and sqlite3_prepare16_v3() interfaces are recommended for all new programs. +** The older interfaces (sqlite3_prepare() and sqlite3_prepare16()) +** are retained for backwards compatibility, but their use is discouraged. +** ^In the "vX" interfaces, the prepared statement ** that is returned (the [sqlite3_stmt] object) contains a copy of the ** original SQL text. This causes the [sqlite3_step()] interface to ** behave differently in three ways: @@ -3762,6 +4626,12 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** or [GLOB] operator or if the parameter is compared to an indexed column ** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled. **
  • +** +**

    ^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having +** the extra prepFlags parameter, which is a bit array consisting of zero or +** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags. ^The +** sqlite3_prepare_v2() interface works exactly the same as +** sqlite3_prepare_v3() with a zero prepFlags parameter. ** */ SQLITE_API int sqlite3_prepare( @@ -3778,6 +4648,14 @@ SQLITE_API int sqlite3_prepare_v2( sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const char **pzTail /* OUT: Pointer to unused portion of zSql */ ); +SQLITE_API int sqlite3_prepare_v3( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); SQLITE_API int sqlite3_prepare16( sqlite3 *db, /* Database handle */ const void *zSql, /* SQL statement, UTF-16 encoded */ @@ -3792,6 +4670,14 @@ SQLITE_API int sqlite3_prepare16_v2( sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const void **pzTail /* OUT: Pointer to unused portion of zSql */ ); +SQLITE_API int sqlite3_prepare16_v3( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); /* ** CAPI3REF: Retrieving Statement SQL @@ -3799,7 +4685,8 @@ SQLITE_API int sqlite3_prepare16_v2( ** ** ^The sqlite3_sql(P) interface returns a pointer to a copy of the UTF-8 ** SQL text used to create [prepared statement] P if P was -** created by either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()]. +** created by [sqlite3_prepare_v2()], [sqlite3_prepare_v3()], +** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()]. ** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8 ** string containing the SQL text of prepared statement P with ** [bound parameters] expanded. @@ -3856,6 +4743,10 @@ SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt); ** sqlite3_stmt_readonly() to return true since, while those statements ** change the configuration of a database connection, they do not make ** changes to the content of the database files on disk. +** ^The sqlite3_stmt_readonly() interface returns true for [BEGIN] since +** [BEGIN] merely sets internal flags, but the [BEGIN|BEGIN IMMEDIATE] and +** [BEGIN|BEGIN EXCLUSIVE] commands do touch the database and so +** sqlite3_stmt_readonly() returns false for those commands. */ SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); @@ -3919,7 +4810,7 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*); ** The [sqlite3_value_blob | sqlite3_value_type()] family of ** interfaces require protected sqlite3_value objects. */ -typedef struct Mem sqlite3_value; +typedef struct sqlite3_value sqlite3_value; /* ** CAPI3REF: SQL Function Context Object @@ -4021,6 +4912,15 @@ typedef struct sqlite3_context sqlite3_context; ** [sqlite3_blob_open | incremental BLOB I/O] routines. ** ^A negative value for the zeroblob results in a zero-length BLOB. ** +** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in +** [prepared statement] S to have an SQL value of NULL, but to also be +** associated with the pointer P of type T. ^D is either a NULL pointer or +** a pointer to a destructor function for P. ^SQLite will invoke the +** destructor D with a single argument of P when it is finished using +** P. The T parameter should be a static string, preferably a string +** literal. The sqlite3_bind_pointer() routine is part of the +** [pointer passing interface] added for SQLite 3.20.0. +** ** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer ** for the [prepared statement] or with a prepared statement for which ** [sqlite3_step()] has been called more recently than [sqlite3_reset()], @@ -4054,6 +4954,7 @@ SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*) SQLITE_API int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, void(*)(void*), unsigned char encoding); SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +SQLITE_API int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*,void(*)(void*)); SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64); @@ -4097,8 +4998,8 @@ SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*); ** ^If the value N is out of range or if the N-th parameter is ** nameless, then NULL is returned. ^The returned string is ** always in UTF-8 encoding even if the named parameter was -** originally specified as UTF-16 in [sqlite3_prepare16()] or -** [sqlite3_prepare16_v2()]. +** originally specified as UTF-16 in [sqlite3_prepare16()], +** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()]. ** ** See also: [sqlite3_bind_blob|sqlite3_bind()], ** [sqlite3_bind_parameter_count()], and @@ -4115,7 +5016,8 @@ SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); ** parameter to [sqlite3_bind_blob|sqlite3_bind()]. ^A zero ** is returned if no matching parameter is found. ^The parameter ** name must be given in UTF-8 even if the original statement -** was prepared from UTF-16 text using [sqlite3_prepare16_v2()]. +** was prepared from UTF-16 text using [sqlite3_prepare16_v2()] or +** [sqlite3_prepare16_v3()]. ** ** See also: [sqlite3_bind_blob|sqlite3_bind()], ** [sqlite3_bind_parameter_count()], and @@ -4138,8 +5040,12 @@ SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*); ** METHOD: sqlite3_stmt ** ** ^Return the number of columns in the result set returned by the -** [prepared statement]. ^This routine returns 0 if pStmt is an SQL -** statement that does not return data (for example an [UPDATE]). +** [prepared statement]. ^If this routine returns 0, that means the +** [prepared statement] returns no data (for example an [UPDATE]). +** ^However, just because this routine returns a positive number does not +** mean that one or more rows of data will be returned. ^A SELECT statement +** will always have a positive sqlite3_column_count() but depending on the +** WHERE clause constraints and the table content, it might return no rows. ** ** See also: [sqlite3_data_count()] */ @@ -4265,16 +5171,18 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); ** CAPI3REF: Evaluate An SQL Statement ** METHOD: sqlite3_stmt ** -** After a [prepared statement] has been prepared using either -** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy +** After a [prepared statement] has been prepared using any of +** [sqlite3_prepare_v2()], [sqlite3_prepare_v3()], [sqlite3_prepare16_v2()], +** or [sqlite3_prepare16_v3()] or one of the legacy ** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function ** must be called one or more times to evaluate the statement. ** ** The details of the behavior of the sqlite3_step() interface depend -** on whether the statement was prepared using the newer "v2" interface -** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy -** interface [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the -** new "v2" interface is recommended for new applications but the legacy +** on whether the statement was prepared using the newer "vX" interfaces +** [sqlite3_prepare_v3()], [sqlite3_prepare_v2()], [sqlite3_prepare16_v3()], +** [sqlite3_prepare16_v2()] or the older legacy +** interfaces [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the +** new "vX" interface is recommended for new applications but the legacy ** interface will continue to be supported. ** ** ^In the legacy interface, the return value will be either [SQLITE_BUSY], @@ -4320,7 +5228,7 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); ** other than [SQLITE_ROW] before any subsequent invocation of ** sqlite3_step(). Failure to reset the prepared statement using ** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from -** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1], +** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1]), ** sqlite3_step() began ** calling [sqlite3_reset()] automatically in this circumstance rather ** than returning [SQLITE_MISUSE]. This is not considered a compatibility @@ -4335,10 +5243,11 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); ** specific [error codes] that better describes the error. ** We admit that this is a goofy design. The problem has been fixed ** with the "v2" interface. If you prepare all of your SQL statements -** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead +** using [sqlite3_prepare_v3()] or [sqlite3_prepare_v2()] +** or [sqlite3_prepare16_v2()] or [sqlite3_prepare16_v3()] instead ** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces, ** then the more specific [error codes] are returned directly -** by sqlite3_step(). The use of the "v2" interface is recommended. +** by sqlite3_step(). The use of the "vX" interfaces is recommended. */ SQLITE_API int sqlite3_step(sqlite3_stmt*); @@ -4400,6 +5309,28 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** KEYWORDS: {column access functions} ** METHOD: sqlite3_stmt ** +** Summary: +**

    +**
    sqlite3_column_blobBLOB result +**
    sqlite3_column_doubleREAL result +**
    sqlite3_column_int32-bit INTEGER result +**
    sqlite3_column_int6464-bit INTEGER result +**
    sqlite3_column_textUTF-8 TEXT result +**
    sqlite3_column_text16UTF-16 TEXT result +**
    sqlite3_column_valueThe result as an +** [sqlite3_value|unprotected sqlite3_value] object. +**
        +**
    sqlite3_column_bytesSize of a BLOB +** or a UTF-8 TEXT result in bytes +**
    sqlite3_column_bytes16   +** →  Size of UTF-16 +** TEXT in bytes +**
    sqlite3_column_typeDefault +** datatype of the result +**
    +** +** Details: +** ** ^These routines return information about a single column of the current ** result row of a query. ^In every case the first argument is a pointer ** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*] @@ -4421,16 +5352,29 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** are called from a different thread while any of these routines ** are pending, then the results are undefined. ** +** The first six interfaces (_blob, _double, _int, _int64, _text, and _text16) +** each return the value of a result column in a specific data format. If +** the result column is not initially in the requested format (for example, +** if the query returns an integer but the sqlite3_column_text() interface +** is used to extract the value) then an automatic type conversion is performed. +** ** ^The sqlite3_column_type() routine returns the ** [SQLITE_INTEGER | datatype code] for the initial data type ** of the result column. ^The returned value is one of [SQLITE_INTEGER], -** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. The value -** returned by sqlite3_column_type() is only meaningful if no type -** conversions have occurred as described below. After a type conversion, -** the value returned by sqlite3_column_type() is undefined. Future +** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. +** The return value of sqlite3_column_type() can be used to decide which +** of the first six interface should be used to extract the column value. +** The value returned by sqlite3_column_type() is only meaningful if no +** automatic type conversions have occurred for the value in question. +** After a type conversion, the result of calling sqlite3_column_type() +** is undefined, though harmless. Future ** versions of SQLite may change the behavior of sqlite3_column_type() ** following a type conversion. ** +** If the result is a BLOB or a TEXT string, then the sqlite3_column_bytes() +** or sqlite3_column_bytes16() interfaces can be used to determine the size +** of that BLOB or string. +** ** ^If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() ** routine returns the number of bytes in that BLOB or string. ** ^If the result is a UTF-16 string, then sqlite3_column_bytes() converts @@ -4467,9 +5411,13 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** [sqlite3_column_value()] is used in any other way, including calls ** to routines like [sqlite3_value_int()], [sqlite3_value_text()], ** or [sqlite3_value_bytes()], the behavior is not threadsafe. +** Hence, the sqlite3_column_value() interface +** is normally only useful within the implementation of +** [application-defined SQL functions] or [virtual tables], not within +** top-level application code. ** -** These routines attempt to convert the value where appropriate. ^For -** example, if the internal representation is FLOAT and a text result +** The these routines may attempt to convert the datatype of the result. +** ^For example, if the internal representation is FLOAT and a text result ** is requested, [sqlite3_snprintf()] is used internally to perform the ** conversion automatically. ^(The following table details the conversions ** that are applied: @@ -4541,7 +5489,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** ^The pointers returned are valid until a type conversion occurs as ** described above, or until [sqlite3_step()] or [sqlite3_reset()] or ** [sqlite3_finalize()] is called. ^The memory space used to hold strings -** and BLOBs is freed automatically. Do not pass the pointers returned +** and BLOBs is freed automatically. Do not pass the pointers returned ** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into ** [sqlite3_free()]. ** @@ -4552,15 +5500,15 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** [SQLITE_NOMEM].)^ */ SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); -SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol); -SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol); SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol); SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); -SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol); SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol); /* ** CAPI3REF: Destroy A Prepared Statement Object @@ -4794,21 +5742,40 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6 ** CAPI3REF: Obtaining SQL Values ** METHOD: sqlite3_value ** -** The C-language implementation of SQL functions and aggregates uses -** this set of interface routines to access the parameter values on -** the function or aggregate. +** Summary: +**
    +**
    sqlite3_value_blobBLOB value +**
    sqlite3_value_doubleREAL value +**
    sqlite3_value_int32-bit INTEGER value +**
    sqlite3_value_int6464-bit INTEGER value +**
    sqlite3_value_pointerPointer value +**
    sqlite3_value_textUTF-8 TEXT value +**
    sqlite3_value_text16UTF-16 TEXT value in +** the native byteorder +**
    sqlite3_value_text16beUTF-16be TEXT value +**
    sqlite3_value_text16leUTF-16le TEXT value +**
        +**
    sqlite3_value_bytesSize of a BLOB +** or a UTF-8 TEXT in bytes +**
    sqlite3_value_bytes16   +** →  Size of UTF-16 +** TEXT in bytes +**
    sqlite3_value_typeDefault +** datatype of the value +**
    sqlite3_value_numeric_type   +** →  Best numeric datatype of the value +**
    ** -** The xFunc (for scalar functions) or xStep (for aggregates) parameters -** to [sqlite3_create_function()] and [sqlite3_create_function16()] -** define callbacks that implement the SQL functions and aggregates. -** The 3rd parameter to these callbacks is an array of pointers to -** [protected sqlite3_value] objects. There is one [sqlite3_value] object for -** each parameter to the SQL function. These routines are used to -** extract values from the [sqlite3_value] objects. +** Details: +** +** These routines extract type, size, and content information from +** [protected sqlite3_value] objects. Protected sqlite3_value objects +** are used to pass parameter information into implementation of +** [application-defined SQL functions] and [virtual tables]. ** ** These routines work only with [protected sqlite3_value] objects. ** Any attempt to use these routines on an [unprotected sqlite3_value] -** object results in undefined behavior. +** is not threadsafe. ** ** ^These routines work just like the corresponding [column access functions] ** except that these routines take a single [protected sqlite3_value] object @@ -4819,6 +5786,24 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6 ** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces ** extract UTF-16 strings as big-endian and little-endian respectively. ** +** ^If [sqlite3_value] object V was initialized +** using [sqlite3_bind_pointer(S,I,P,X,D)] or [sqlite3_result_pointer(C,P,X,D)] +** and if X and Y are strings that compare equal according to strcmp(X,Y), +** then sqlite3_value_pointer(V,Y) will return the pointer P. ^Otherwise, +** sqlite3_value_pointer(V,Y) returns a NULL. The sqlite3_bind_pointer() +** routine is part of the [pointer passing interface] added for SQLite 3.20.0. +** +** ^(The sqlite3_value_type(V) interface returns the +** [SQLITE_INTEGER | datatype code] for the initial datatype of the +** [sqlite3_value] object V. The returned value is one of [SQLITE_INTEGER], +** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].)^ +** Other interfaces might change the datatype for an sqlite3_value object. +** For example, if the datatype is initially SQLITE_INTEGER and +** sqlite3_value_text(V) is called to extract a text value for that +** integer, then subsequent calls to sqlite3_value_type(V) might return +** SQLITE_TEXT. Whether or not a persistent internal datatype conversion +** occurs is undefined and may change from one release of SQLite to the next. +** ** ^(The sqlite3_value_numeric_type() interface attempts to apply ** numeric affinity to the value. This means that an attempt is ** made to convert the value to an integer or floating point. If @@ -4837,15 +5822,16 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6 ** the SQL function that supplied the [sqlite3_value*] parameters. */ SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); -SQLITE_API int sqlite3_value_bytes(sqlite3_value*); -SQLITE_API int sqlite3_value_bytes16(sqlite3_value*); SQLITE_API double sqlite3_value_double(sqlite3_value*); SQLITE_API int sqlite3_value_int(sqlite3_value*); SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*); +SQLITE_API void *sqlite3_value_pointer(sqlite3_value*, const char*); SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*); SQLITE_API const void *sqlite3_value_text16(sqlite3_value*); SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*); SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*); +SQLITE_API int sqlite3_value_bytes(sqlite3_value*); +SQLITE_API int sqlite3_value_bytes16(sqlite3_value*); SQLITE_API int sqlite3_value_type(sqlite3_value*); SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); @@ -4858,10 +5844,6 @@ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); ** information can be used to pass a limited amount of context from ** one SQL function to another. Use the [sqlite3_result_subtype()] ** routine to set the subtype for the return value of an SQL function. -** -** SQLite makes no use of subtype itself. It merely passes the subtype -** from the result of one [application-defined SQL function] into the -** input of another. */ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); @@ -4969,10 +5951,11 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** the compiled regular expression can be reused on multiple ** invocations of the same function. ** -** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata -** associated by the sqlite3_set_auxdata() function with the Nth argument -** value to the application-defined function. ^If there is no metadata -** associated with the function argument, this sqlite3_get_auxdata() interface +** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata +** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument +** value to the application-defined function. ^N is zero for the left-most +** function argument. ^If there is no metadata +** associated with the function argument, the sqlite3_get_auxdata(C,N) interface ** returns a NULL pointer. ** ** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th @@ -5003,6 +5986,10 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** function parameters that are compile-time constants, including literal ** values and [parameters] and expressions composed from the same.)^ ** +** The value of the N parameter to these interfaces should be non-negative. +** Future enhancements may make use of negative N values to define new +** kinds of function caching behavior. +** ** These routines must be called from the same thread in which ** the SQL function is running. */ @@ -5126,7 +6113,7 @@ typedef void (*sqlite3_destructor_type)(void*); ** when it has finished using that result. ** ^If the 4th parameter to the sqlite3_result_text* interfaces ** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT -** then SQLite makes a copy of the result into space obtained from +** then SQLite makes a copy of the result into space obtained ** from [sqlite3_malloc()] before it returns. ** ** ^The sqlite3_result_value() interface sets the result of @@ -5139,6 +6126,17 @@ typedef void (*sqlite3_destructor_type)(void*); ** [unprotected sqlite3_value] object is required, so either ** kind of [sqlite3_value] object can be used with this interface. ** +** ^The sqlite3_result_pointer(C,P,T,D) interface sets the result to an +** SQL NULL value, just like [sqlite3_result_null(C)], except that it +** also associates the host-language pointer P or type T with that +** NULL value such that the pointer can be retrieved within an +** [application-defined SQL function] using [sqlite3_value_pointer()]. +** ^If the D parameter is not NULL, then it is a pointer to a destructor +** for the P parameter. ^SQLite invokes D with P as its only argument +** when SQLite is finished with P. The T parameter should be a static +** string and preferably a string literal. The sqlite3_result_pointer() +** routine is part of the [pointer passing interface] added for SQLite 3.20.0. +** ** If these routines are called from within the different thread ** than the one containing the application-defined function that received ** the [sqlite3_context] pointer, the results are undefined. @@ -5162,6 +6160,7 @@ SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(* SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*); +SQLITE_API void sqlite3_result_pointer(sqlite3_context*, void*,const char*,void(*)(void*)); SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n); SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n); @@ -5648,7 +6647,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); ** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified. ** ** ^In the current implementation, the update hook -** is not invoked when duplication rows are deleted because of an +** is not invoked when conflicting rows are deleted because of an ** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook ** invoked when rows are deleted using the [truncate optimization]. ** The exceptions defined in this paragraph might change in a future @@ -5821,7 +6820,9 @@ SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N); ** ^If the column-name parameter to sqlite3_table_column_metadata() is a ** NULL pointer, then this routine simply checks for the existence of the ** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it -** does not. +** does not. If the table name parameter T in a call to +** sqlite3_table_column_metadata(X,D,T,C,...) is NULL then the result is +** undefined behavior. ** ** ^The column is identified by the second, third and fourth parameters to ** this function. ^(The second parameter is either the name of the database @@ -6430,6 +7431,12 @@ typedef struct sqlite3_blob sqlite3_blob; ** [database connection] error code and message accessible via ** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. ** +** A BLOB referenced by sqlite3_blob_open() may be read using the +** [sqlite3_blob_read()] interface and modified by using +** [sqlite3_blob_write()]. The [BLOB handle] can be moved to a +** different row of the same table using the [sqlite3_blob_reopen()] +** interface. However, the column, table, or database of a [BLOB handle] +** cannot be changed after the [BLOB handle] is opened. ** ** ^(If the row that a BLOB handle points to is modified by an ** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects @@ -6453,6 +7460,10 @@ typedef struct sqlite3_blob sqlite3_blob; ** ** To avoid a resource leak, every open [BLOB handle] should eventually ** be released by a call to [sqlite3_blob_close()]. +** +** See also: [sqlite3_blob_close()], +** [sqlite3_blob_reopen()], [sqlite3_blob_read()], +** [sqlite3_blob_bytes()], [sqlite3_blob_write()]. */ SQLITE_API int sqlite3_blob_open( sqlite3*, @@ -6468,11 +7479,11 @@ SQLITE_API int sqlite3_blob_open( ** CAPI3REF: Move a BLOB Handle to a New Row ** METHOD: sqlite3_blob ** -** ^This function is used to move an existing blob handle so that it points +** ^This function is used to move an existing [BLOB handle] so that it points ** to a different row of the same database table. ^The new row is identified ** by the rowid value passed as the second argument. Only the row can be ** changed. ^The database, table and column on which the blob handle is open -** remain the same. Moving an existing blob handle to a new row can be +** remain the same. Moving an existing [BLOB handle] to a new row is ** faster than closing the existing handle and opening a new one. ** ** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] - @@ -7324,6 +8335,24 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** used as a proxy for the total work done by the prepared statement. ** If the number of virtual machine operations exceeds 2147483647 ** then the value returned by this statement status code is undefined. +** +** [[SQLITE_STMTSTATUS_REPREPARE]]
    SQLITE_STMTSTATUS_REPREPARE
    +**
    ^This is the number of times that the prepare statement has been +** automatically regenerated due to schema changes or change to +** [bound parameters] that might affect the query plan. +** +** [[SQLITE_STMTSTATUS_RUN]]
    SQLITE_STMTSTATUS_RUN
    +**
    ^This is the number of times that the prepared statement has +** been run. A single "run" for the purposes of this counter is one +** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()]. +** The counter is incremented on the first [sqlite3_step()] call of each +** cycle. +** +** [[SQLITE_STMTSTATUS_MEMUSED]]
    SQLITE_STMTSTATUS_MEMUSED
    +**
    ^This is the approximate number of bytes of heap memory +** used to store the prepared statement. ^This value is not actually +** a counter, and so the resetFlg parameter to sqlite3_stmt_status() +** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED. **
    ** */ @@ -7331,6 +8360,9 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); #define SQLITE_STMTSTATUS_SORT 2 #define SQLITE_STMTSTATUS_AUTOINDEX 3 #define SQLITE_STMTSTATUS_VM_STEP 4 +#define SQLITE_STMTSTATUS_REPREPARE 5 +#define SQLITE_STMTSTATUS_RUN 6 +#define SQLITE_STMTSTATUS_MEMUSED 99 /* ** CAPI3REF: Custom Page Cache Object @@ -8401,7 +9433,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); ** ** ^The [sqlite3_preupdate_hook()] interface registers a callback function ** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation -** on a [rowid table]. +** on a database table. ** ^At most one preupdate hook may be registered at a time on a single ** [database connection]; each call to [sqlite3_preupdate_hook()] overrides ** the previous setting. @@ -8410,9 +9442,9 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); ** ^The third parameter to [sqlite3_preupdate_hook()] is passed through as ** the first parameter to callbacks. ** -** ^The preupdate hook only fires for changes to [rowid tables]; the preupdate -** hook is not invoked for changes to [virtual tables] or [WITHOUT ROWID] -** tables. +** ^The preupdate hook only fires for changes to real database tables; the +** preupdate hook is not invoked for changes to [virtual tables] or to +** system tables like sqlite_master or sqlite_stat1. ** ** ^The second parameter to the preupdate callback is a pointer to ** the [database connection] that registered the preupdate hook. @@ -8426,12 +9458,16 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); ** databases.)^ ** ^The fifth parameter to the preupdate callback is the name of the ** table that is being modified. -** ^The sixth parameter to the preupdate callback is the initial [rowid] of the -** row being changes for SQLITE_UPDATE and SQLITE_DELETE changes and is -** undefined for SQLITE_INSERT changes. -** ^The seventh parameter to the preupdate callback is the final [rowid] of -** the row being changed for SQLITE_UPDATE and SQLITE_INSERT changes and is -** undefined for SQLITE_DELETE changes. +** +** For an UPDATE or DELETE operation on a [rowid table], the sixth +** parameter passed to the preupdate callback is the initial [rowid] of the +** row being modified or deleted. For an INSERT operation on a rowid table, +** or any operation on a WITHOUT ROWID table, the value of the sixth +** parameter is undefined. For an INSERT or UPDATE on a rowid table the +** seventh parameter is the final rowid value of the row being inserted +** or updated. The value of the seventh parameter passed to the callback +** function is not defined for operations on WITHOUT ROWID tables, or for +** INSERT operations on rowid tables. ** ** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()], ** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces @@ -8471,7 +9507,8 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); ** ** See also: [sqlite3_update_hook()] */ -SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_preupdate_hook( +#if defined(SQLITE_ENABLE_PREUPDATE_HOOK) +SQLITE_API void *sqlite3_preupdate_hook( sqlite3 *db, void(*xPreUpdate)( void *pCtx, /* Copy of third arg to preupdate_hook() */ @@ -8484,10 +9521,11 @@ SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_preupdate_hook( ), void* ); -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **); -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_preupdate_count(sqlite3 *); -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_preupdate_depth(sqlite3 *); -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); +SQLITE_API int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **); +SQLITE_API int sqlite3_preupdate_count(sqlite3 *); +SQLITE_API int sqlite3_preupdate_depth(sqlite3 *); +SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); +#endif /* ** CAPI3REF: Low-level system error code @@ -8503,7 +9541,7 @@ SQLITE_API int sqlite3_system_errno(sqlite3*); /* ** CAPI3REF: Database Snapshot -** KEYWORDS: {snapshot} +** KEYWORDS: {snapshot} {sqlite3_snapshot} ** EXPERIMENTAL ** ** An instance of the snapshot object records the state of a [WAL mode] @@ -8527,7 +9565,9 @@ SQLITE_API int sqlite3_system_errno(sqlite3*); ** to an historical snapshot (if possible). The destructor for ** sqlite3_snapshot objects is [sqlite3_snapshot_free()]. */ -typedef struct sqlite3_snapshot sqlite3_snapshot; +typedef struct sqlite3_snapshot { + unsigned char hidden[48]; +} sqlite3_snapshot; /* ** CAPI3REF: Record A Database Snapshot @@ -8538,9 +9578,32 @@ typedef struct sqlite3_snapshot sqlite3_snapshot; ** schema S in database connection D. ^On success, the ** [sqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly ** created [sqlite3_snapshot] object into *P and returns SQLITE_OK. -** ^If schema S of [database connection] D is not a [WAL mode] database -** that is in a read transaction, then [sqlite3_snapshot_get(D,S,P)] -** leaves the *P value unchanged and returns an appropriate [error code]. +** If there is not already a read-transaction open on schema S when +** this function is called, one is opened automatically. +** +** The following must be true for this function to succeed. If any of +** the following statements are false when sqlite3_snapshot_get() is +** called, SQLITE_ERROR is returned. The final value of *P is undefined +** in this case. +** +** +** +** This function may also return SQLITE_NOMEM. If it is called with the +** database handle in autocommit mode but fails for some other reason, +** whether or not a read transaction is opened on schema S is undefined. ** ** The [sqlite3_snapshot] object returned from a successful call to ** [sqlite3_snapshot_get()] must be freed using [sqlite3_snapshot_free()] @@ -8633,6 +9696,28 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp( sqlite3_snapshot *p2 ); +/* +** CAPI3REF: Recover snapshots from a wal file +** EXPERIMENTAL +** +** If all connections disconnect from a database file but do not perform +** a checkpoint, the existing wal file is opened along with the database +** file the next time the database is opened. At this point it is only +** possible to successfully call sqlite3_snapshot_open() to open the most +** recent snapshot of the database (the one at the head of the wal file), +** even though the wal file may contain other valid snapshots for which +** clients have sqlite3_snapshot handles. +** +** This function attempts to scan the wal file associated with database zDb +** of database handle db and make all valid snapshots available to +** sqlite3_snapshot_open(). It is an error if there is already a read +** transaction open on the database, or if the database is not a wal mode +** database. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); + /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. @@ -8818,7 +9903,7 @@ typedef struct sqlite3_changeset_iter sqlite3_changeset_iter; ** attached database. It is not an error if database zDb is not attached ** to the database when the session object is created. */ -int sqlite3session_create( +SQLITE_API int sqlite3session_create( sqlite3 *db, /* Database handle */ const char *zDb, /* Name of db (e.g. "main") */ sqlite3_session **ppSession /* OUT: New session object */ @@ -8836,7 +9921,7 @@ int sqlite3session_create( ** are attached is closed. Refer to the documentation for ** [sqlite3session_create()] for details. */ -void sqlite3session_delete(sqlite3_session *pSession); +SQLITE_API void sqlite3session_delete(sqlite3_session *pSession); /* @@ -8856,7 +9941,7 @@ void sqlite3session_delete(sqlite3_session *pSession); ** The return value indicates the final state of the session object: 0 if ** the session is disabled, or 1 if it is enabled. */ -int sqlite3session_enable(sqlite3_session *pSession, int bEnable); +SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable); /* ** CAPI3REF: Set Or Clear the Indirect Change Flag @@ -8885,7 +9970,7 @@ int sqlite3session_enable(sqlite3_session *pSession, int bEnable); ** The return value indicates the final state of the indirect flag: 0 if ** it is clear, or 1 if it is set. */ -int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect); +SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect); /* ** CAPI3REF: Attach A Table To A Session Object @@ -8915,7 +10000,7 @@ int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect); ** SQLITE_OK is returned if the call completes without error. Or, if an error ** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned. */ -int sqlite3session_attach( +SQLITE_API int sqlite3session_attach( sqlite3_session *pSession, /* Session object */ const char *zTab /* Table name */ ); @@ -8929,7 +10014,7 @@ int sqlite3session_attach( ** If xFilter returns 0, changes is not tracked. Note that once a table is ** attached, xFilter will not be called again. */ -void sqlite3session_table_filter( +SQLITE_API void sqlite3session_table_filter( sqlite3_session *pSession, /* Session object */ int(*xFilter)( void *pCtx, /* Copy of third arg to _filter_table() */ @@ -9042,7 +10127,7 @@ void sqlite3session_table_filter( ** another field of the same row is updated while the session is enabled, the ** resulting changeset will contain an UPDATE change that updates both fields. */ -int sqlite3session_changeset( +SQLITE_API int sqlite3session_changeset( sqlite3_session *pSession, /* Session object */ int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ void **ppChangeset /* OUT: Buffer containing changeset */ @@ -9086,7 +10171,8 @@ int sqlite3session_changeset( ** the from-table, a DELETE record is added to the session object. ** **
  • For each row (primary key) that exists in both tables, but features -** different in each, an UPDATE record is added to the session. +** different non-PK values in each, an UPDATE record is added to the +** session. ** ** ** To clarify, if this function is called and then a changeset constructed @@ -9103,7 +10189,7 @@ int sqlite3session_changeset( ** message. It is the responsibility of the caller to free this buffer using ** sqlite3_free(). */ -int sqlite3session_diff( +SQLITE_API int sqlite3session_diff( sqlite3_session *pSession, const char *zFromDb, const char *zTbl, @@ -9139,7 +10225,7 @@ int sqlite3session_diff( ** a single table are grouped together, tables appear in the order in which ** they were attached to the session object). */ -int sqlite3session_patchset( +SQLITE_API int sqlite3session_patchset( sqlite3_session *pSession, /* Session object */ int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */ void **ppPatchset /* OUT: Buffer containing changeset */ @@ -9160,7 +10246,7 @@ int sqlite3session_patchset( ** guaranteed that a call to sqlite3session_changeset() will return a ** changeset containing zero changes. */ -int sqlite3session_isempty(sqlite3_session *pSession); +SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession); /* ** CAPI3REF: Create An Iterator To Traverse A Changeset @@ -9195,7 +10281,7 @@ int sqlite3session_isempty(sqlite3_session *pSession); ** the applies to table X, then one for table Y, and then later on visit ** another change for table X. */ -int sqlite3changeset_start( +SQLITE_API int sqlite3changeset_start( sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */ int nChangeset, /* Size of changeset blob in bytes */ void *pChangeset /* Pointer to blob containing changeset */ @@ -9224,7 +10310,7 @@ int sqlite3changeset_start( ** codes include SQLITE_CORRUPT (if the changeset buffer is corrupt) or ** SQLITE_NOMEM. */ -int sqlite3changeset_next(sqlite3_changeset_iter *pIter); +SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter); /* ** CAPI3REF: Obtain The Current Operation From A Changeset Iterator @@ -9252,7 +10338,7 @@ int sqlite3changeset_next(sqlite3_changeset_iter *pIter); ** SQLite error code is returned. The values of the output variables may not ** be trusted in this case. */ -int sqlite3changeset_op( +SQLITE_API int sqlite3changeset_op( sqlite3_changeset_iter *pIter, /* Iterator object */ const char **pzTab, /* OUT: Pointer to table name */ int *pnCol, /* OUT: Number of columns in table */ @@ -9285,7 +10371,7 @@ int sqlite3changeset_op( ** SQLITE_OK is returned and the output variables populated as described ** above. */ -int sqlite3changeset_pk( +SQLITE_API int sqlite3changeset_pk( sqlite3_changeset_iter *pIter, /* Iterator object */ unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */ int *pnCol /* OUT: Number of entries in output array */ @@ -9315,7 +10401,7 @@ int sqlite3changeset_pk( ** If some other error occurs (e.g. an OOM condition), an SQLite error code ** is returned and *ppValue is set to NULL. */ -int sqlite3changeset_old( +SQLITE_API int sqlite3changeset_old( sqlite3_changeset_iter *pIter, /* Changeset iterator */ int iVal, /* Column number */ sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */ @@ -9348,7 +10434,7 @@ int sqlite3changeset_old( ** If some other error occurs (e.g. an OOM condition), an SQLite error code ** is returned and *ppValue is set to NULL. */ -int sqlite3changeset_new( +SQLITE_API int sqlite3changeset_new( sqlite3_changeset_iter *pIter, /* Changeset iterator */ int iVal, /* Column number */ sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */ @@ -9375,7 +10461,7 @@ int sqlite3changeset_new( ** If some other error occurs (e.g. an OOM condition), an SQLite error code ** is returned and *ppValue is set to NULL. */ -int sqlite3changeset_conflict( +SQLITE_API int sqlite3changeset_conflict( sqlite3_changeset_iter *pIter, /* Changeset iterator */ int iVal, /* Column number */ sqlite3_value **ppValue /* OUT: Value from conflicting row */ @@ -9391,7 +10477,7 @@ int sqlite3changeset_conflict( ** ** In all other cases this function returns SQLITE_MISUSE. */ -int sqlite3changeset_fk_conflicts( +SQLITE_API int sqlite3changeset_fk_conflicts( sqlite3_changeset_iter *pIter, /* Changeset iterator */ int *pnOut /* OUT: Number of FK violations */ ); @@ -9424,7 +10510,7 @@ int sqlite3changeset_fk_conflicts( ** // An error has occurred ** } */ -int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter); +SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter); /* ** CAPI3REF: Invert A Changeset @@ -9454,7 +10540,7 @@ int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter); ** WARNING/TODO: This function currently assumes that the input is a valid ** changeset. If it is not, the results are undefined. */ -int sqlite3changeset_invert( +SQLITE_API int sqlite3changeset_invert( int nIn, const void *pIn, /* Input changeset */ int *pnOut, void **ppOut /* OUT: Inverse of input */ ); @@ -9483,7 +10569,7 @@ int sqlite3changeset_invert( ** ** Refer to the sqlite3_changegroup documentation below for details. */ -int sqlite3changeset_concat( +SQLITE_API int sqlite3changeset_concat( int nA, /* Number of bytes in buffer pA */ void *pA, /* Pointer to buffer containing changeset A */ int nB, /* Number of bytes in buffer pB */ @@ -9533,7 +10619,7 @@ typedef struct sqlite3_changegroup sqlite3_changegroup; ** sqlite3changegroup_output() functions, also available are the streaming ** versions sqlite3changegroup_add_strm() and sqlite3changegroup_output_strm(). */ -int sqlite3changegroup_new(sqlite3_changegroup **pp); +SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp); /* ** CAPI3REF: Add A Changeset To A Changegroup @@ -9610,7 +10696,7 @@ int sqlite3changegroup_new(sqlite3_changegroup **pp); ** ** If no error occurs, SQLITE_OK is returned. */ -int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); +SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); /* ** CAPI3REF: Obtain A Composite Changeset From A Changegroup @@ -9636,7 +10722,7 @@ int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); ** responsibility of the caller to eventually free the buffer using a ** call to sqlite3_free(). */ -int sqlite3changegroup_output( +SQLITE_API int sqlite3changegroup_output( sqlite3_changegroup*, int *pnData, /* OUT: Size of output buffer in bytes */ void **ppData /* OUT: Pointer to output buffer */ @@ -9645,7 +10731,7 @@ int sqlite3changegroup_output( /* ** CAPI3REF: Delete A Changegroup Object */ -void sqlite3changegroup_delete(sqlite3_changegroup*); +SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*); /* ** CAPI3REF: Apply A Changeset To A Database @@ -9671,7 +10757,7 @@ void sqlite3changegroup_delete(sqlite3_changegroup*); ** ** ** The SQLITE_IOCAP_ATOMIC property means that all writes of @@ -850,7 +857,7 @@ struct sqlite3_io_methods { ** opcode allows these two values (10 retries and 25 milliseconds of delay) ** to be adjusted. The values are changed for all database connections ** within the same process. The argument is a pointer to an array of two -** integers where the first integer i the new retry count and the second +** integers where the first integer is the new retry count and the second ** integer is the delay. If either integer is negative, then the setting ** is not changed but instead the prior value of that setting is written ** into the array entry, allowing the current retry settings to be @@ -1035,6 +1042,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_VFS_POINTER 27 #define SQLITE_FCNTL_JOURNAL_POINTER 28 #define SQLITE_FCNTL_WIN32_GET_HANDLE 29 +#define SQLITE_FCNTL_PDB 30 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE @@ -1987,6 +1995,29 @@ struct sqlite3_mem_methods { ** until after the database connection closes. ** ** +**
    SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE
    +**
    Usually, when a database in wal mode is closed or detached from a +** database handle, SQLite checks if this will mean that there are now no +** connections at all to the database. If so, it performs a checkpoint +** operation before closing the connection. This option may be used to +** override this behaviour. The first parameter passed to this operation +** is an integer - non-zero to disable checkpoints-on-close, or zero (the +** default) to enable them. The second parameter is a pointer to an integer +** into which is written 0 or 1 to indicate whether checkpoints-on-close +** have been disabled - 0 if they are not disabled, 1 if they are. +**
    +** +**
    SQLITE_DBCONFIG_ENABLE_QPSG
    +**
    ^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates +** the [query planner stability guarantee] (QPSG). When the QPSG is active, +** a single SQL query statement will always use the same algorithm regardless +** of values of [bound parameters].)^ The QPSG disables some query optimizations +** that look at the values of bound parameters, which can make some queries +** slower. But the QPSG has the advantage of more predictable behavior. With +** the QPSG active, SQLite will always use the same query plan in the field as +** was used during testing in the lab. +**
    +** ** */ #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ @@ -1995,6 +2026,8 @@ struct sqlite3_mem_methods { #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */ +#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */ +#define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */ /* @@ -2019,20 +2052,30 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff); ** the table has a column of type [INTEGER PRIMARY KEY] then that column ** is another alias for the rowid. ** -** ^The sqlite3_last_insert_rowid(D) interface returns the [rowid] of the -** most recent successful [INSERT] into a rowid table or [virtual table] -** on database connection D. -** ^Inserts into [WITHOUT ROWID] tables are not recorded. -** ^If no successful [INSERT]s into rowid tables -** have ever occurred on the database connection D, -** then sqlite3_last_insert_rowid(D) returns zero. +** ^The sqlite3_last_insert_rowid(D) interface usually returns the [rowid] of +** the most recent successful [INSERT] into a rowid table or [virtual table] +** on database connection D. ^Inserts into [WITHOUT ROWID] tables are not +** recorded. ^If no successful [INSERT]s into rowid tables have ever occurred +** on the database connection D, then sqlite3_last_insert_rowid(D) returns +** zero. ** -** ^(If an [INSERT] occurs within a trigger or within a [virtual table] -** method, then this routine will return the [rowid] of the inserted -** row as long as the trigger or virtual table method is running. -** But once the trigger or virtual table method ends, the value returned -** by this routine reverts to what it was before the trigger or virtual -** table method began.)^ +** As well as being set automatically as rows are inserted into database +** tables, the value returned by this function may be set explicitly by +** [sqlite3_set_last_insert_rowid()] +** +** Some virtual table implementations may INSERT rows into rowid tables as +** part of committing a transaction (e.g. to flush data accumulated in memory +** to disk). In this case subsequent calls to this function return the rowid +** associated with these internal INSERT operations, which leads to +** unintuitive results. Virtual table implementations that do write to rowid +** tables in this way can avoid this problem by restoring the original +** rowid value using [sqlite3_set_last_insert_rowid()] before returning +** control to the user. +** +** ^(If an [INSERT] occurs within a trigger then this routine will +** return the [rowid] of the inserted row as long as the trigger is +** running. Once the trigger program ends, the value returned +** by this routine reverts to what it was before the trigger was fired.)^ ** ** ^An [INSERT] that fails due to a constraint violation is not a ** successful [INSERT] and does not change the value returned by this @@ -2059,6 +2102,16 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff); */ SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); +/* +** CAPI3REF: Set the Last Insert Rowid value. +** METHOD: sqlite3 +** +** The sqlite3_set_last_insert_rowid(D, R) method allows the application to +** set the value returned by calling sqlite3_last_insert_rowid(D) to R +** without inserting a row into the database. +*/ +SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); + /* ** CAPI3REF: Count The Number Of Rows Modified ** METHOD: sqlite3 @@ -2170,9 +2223,6 @@ SQLITE_API int sqlite3_total_changes(sqlite3*); ** ^A call to sqlite3_interrupt(D) that occurs when there are no running ** SQL statements is a no-op and has no effect on SQL statements ** that are started after the sqlite3_interrupt() call returns. -** -** If the database connection closes while [sqlite3_interrupt()] -** is running then bad things will likely happen. */ SQLITE_API void sqlite3_interrupt(sqlite3*); @@ -2635,12 +2685,14 @@ SQLITE_API void sqlite3_randomness(int N, void *P); /* ** CAPI3REF: Compile-Time Authorization Callbacks ** METHOD: sqlite3 +** KEYWORDS: {authorizer callback} ** ** ^This routine registers an authorizer callback with a particular ** [database connection], supplied in the first argument. ** ^The authorizer callback is invoked as SQL statements are being compiled ** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], -** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. ^At various +** [sqlite3_prepare_v3()], [sqlite3_prepare16()], [sqlite3_prepare16_v2()], +** and [sqlite3_prepare16_v3()]. ^At various ** points during the compilation process, as logic is being created ** to perform various actions, the authorizer callback is invoked to ** see if those actions are allowed. ^The authorizer callback should @@ -2662,8 +2714,10 @@ SQLITE_API void sqlite3_randomness(int N, void *P); ** parameter to the sqlite3_set_authorizer() interface. ^The second parameter ** to the callback is an integer [SQLITE_COPY | action code] that specifies ** the particular action to be authorized. ^The third through sixth parameters -** to the callback are zero-terminated strings that contain additional -** details about the action to be authorized. +** to the callback are either NULL pointers or zero-terminated strings +** that contain additional details about the action to be authorized. +** Applications must always be prepared to encounter a NULL pointer in any +** of the third through the sixth parameters of the authorization callback. ** ** ^If the action code is [SQLITE_READ] ** and the callback returns [SQLITE_IGNORE] then the @@ -2672,6 +2726,10 @@ SQLITE_API void sqlite3_randomness(int N, void *P); ** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE] ** return can be used to deny an untrusted user access to individual ** columns of a table. +** ^When a table is referenced by a [SELECT] but no column values are +** extracted from that table (for example in a query like +** "SELECT count(*) FROM tab") then the [SQLITE_READ] authorizer callback +** is invoked once for that table with a column name that is an empty string. ** ^If the action code is [SQLITE_DELETE] and the callback returns ** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the ** [truncate optimization] is disabled and all rows are deleted individually. @@ -3383,9 +3441,9 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** ** [[SQLITE_LIMIT_VDBE_OP]] ^(
    SQLITE_LIMIT_VDBE_OP
    **
    The maximum number of instructions in a virtual machine program -** used to implement an SQL statement. This limit is not currently -** enforced, though that might be added in some future release of -** SQLite.
    )^ +** used to implement an SQL statement. If [sqlite3_prepare_v2()] or +** the equivalent tries to allocate space for more than this many opcodes +** in a single prepared statement, an SQLITE_NOMEM error is returned.)^ ** ** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(
    SQLITE_LIMIT_FUNCTION_ARG
    **
    The maximum number of arguments on a function.
    )^ @@ -3423,23 +3481,59 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); #define SQLITE_LIMIT_TRIGGER_DEPTH 10 #define SQLITE_LIMIT_WORKER_THREADS 11 +/* +** CAPI3REF: Prepare Flags +** +** These constants define various flags that can be passed into +** "prepFlags" parameter of the [sqlite3_prepare_v3()] and +** [sqlite3_prepare16_v3()] interfaces. +** +** New flags may be added in future releases of SQLite. +** +**
    +** [[SQLITE_PREPARE_PERSISTENT]] ^(
    SQLITE_PREPARE_PERSISTENT
    +**
    The SQLITE_PREPARE_PERSISTENT flag is a hint to the query planner +** that the prepared statement will be retained for a long time and +** probably reused many times.)^ ^Without this flag, [sqlite3_prepare_v3()] +** and [sqlite3_prepare16_v3()] assume that the prepared statement will +** be used just once or at most a few times and then destroyed using +** [sqlite3_finalize()] relatively soon. The current implementation acts +** on this hint by avoiding the use of [lookaside memory] so as not to +** deplete the limited store of lookaside memory. Future versions of +** SQLite may act on this hint differently. +**
    +*/ +#define SQLITE_PREPARE_PERSISTENT 0x01 + /* ** CAPI3REF: Compiling An SQL Statement ** KEYWORDS: {SQL statement compiler} ** METHOD: sqlite3 ** CONSTRUCTOR: sqlite3_stmt ** -** To execute an SQL query, it must first be compiled into a byte-code -** program using one of these routines. +** To execute an SQL statement, it must first be compiled into a byte-code +** program using one of these routines. Or, in other words, these routines +** are constructors for the [prepared statement] object. +** +** The preferred routine to use is [sqlite3_prepare_v2()]. The +** [sqlite3_prepare()] interface is legacy and should be avoided. +** [sqlite3_prepare_v3()] has an extra "prepFlags" option that is used +** for special purposes. +** +** The use of the UTF-8 interfaces is preferred, as SQLite currently +** does all parsing using UTF-8. The UTF-16 interfaces are provided +** as a convenience. The UTF-16 interfaces work by converting the +** input text into UTF-8, then invoking the corresponding UTF-8 interface. ** ** The first argument, "db", is a [database connection] obtained from a ** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or ** [sqlite3_open16()]. The database connection must not have been closed. ** ** The second argument, "zSql", is the statement to be compiled, encoded -** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2() -** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2() -** use UTF-16. +** as either UTF-8 or UTF-16. The sqlite3_prepare(), sqlite3_prepare_v2(), +** and sqlite3_prepare_v3() +** interfaces use UTF-8, and sqlite3_prepare16(), sqlite3_prepare16_v2(), +** and sqlite3_prepare16_v3() use UTF-16. ** ** ^If the nByte argument is negative, then zSql is read up to the ** first zero terminator. ^If nByte is positive, then it is the @@ -3466,10 +3560,11 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** ^On success, the sqlite3_prepare() family of routines return [SQLITE_OK]; ** otherwise an [error code] is returned. ** -** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are -** recommended for all new programs. The two older interfaces are retained -** for backwards compatibility, but their use is discouraged. -** ^In the "v2" interfaces, the prepared statement +** The sqlite3_prepare_v2(), sqlite3_prepare_v3(), sqlite3_prepare16_v2(), +** and sqlite3_prepare16_v3() interfaces are recommended for all new programs. +** The older interfaces (sqlite3_prepare() and sqlite3_prepare16()) +** are retained for backwards compatibility, but their use is discouraged. +** ^In the "vX" interfaces, the prepared statement ** that is returned (the [sqlite3_stmt] object) contains a copy of the ** original SQL text. This causes the [sqlite3_step()] interface to ** behave differently in three ways: @@ -3502,6 +3597,12 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** or [GLOB] operator or if the parameter is compared to an indexed column ** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled. **
  • +** +**

    ^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having +** the extra prepFlags parameter, which is a bit array consisting of zero or +** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags. ^The +** sqlite3_prepare_v2() interface works exactly the same as +** sqlite3_prepare_v3() with a zero prepFlags parameter. ** */ SQLITE_API int sqlite3_prepare( @@ -3518,6 +3619,14 @@ SQLITE_API int sqlite3_prepare_v2( sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const char **pzTail /* OUT: Pointer to unused portion of zSql */ ); +SQLITE_API int sqlite3_prepare_v3( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); SQLITE_API int sqlite3_prepare16( sqlite3 *db, /* Database handle */ const void *zSql, /* SQL statement, UTF-16 encoded */ @@ -3532,6 +3641,14 @@ SQLITE_API int sqlite3_prepare16_v2( sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const void **pzTail /* OUT: Pointer to unused portion of zSql */ ); +SQLITE_API int sqlite3_prepare16_v3( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); /* ** CAPI3REF: Retrieving Statement SQL @@ -3539,7 +3656,8 @@ SQLITE_API int sqlite3_prepare16_v2( ** ** ^The sqlite3_sql(P) interface returns a pointer to a copy of the UTF-8 ** SQL text used to create [prepared statement] P if P was -** created by either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()]. +** created by [sqlite3_prepare_v2()], [sqlite3_prepare_v3()], +** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()]. ** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8 ** string containing the SQL text of prepared statement P with ** [bound parameters] expanded. @@ -3596,6 +3714,10 @@ SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt); ** sqlite3_stmt_readonly() to return true since, while those statements ** change the configuration of a database connection, they do not make ** changes to the content of the database files on disk. +** ^The sqlite3_stmt_readonly() interface returns true for [BEGIN] since +** [BEGIN] merely sets internal flags, but the [BEGIN|BEGIN IMMEDIATE] and +** [BEGIN|BEGIN EXCLUSIVE] commands do touch the database and so +** sqlite3_stmt_readonly() returns false for those commands. */ SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); @@ -3659,7 +3781,7 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*); ** The [sqlite3_value_blob | sqlite3_value_type()] family of ** interfaces require protected sqlite3_value objects. */ -typedef struct Mem sqlite3_value; +typedef struct sqlite3_value sqlite3_value; /* ** CAPI3REF: SQL Function Context Object @@ -3761,6 +3883,15 @@ typedef struct sqlite3_context sqlite3_context; ** [sqlite3_blob_open | incremental BLOB I/O] routines. ** ^A negative value for the zeroblob results in a zero-length BLOB. ** +** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in +** [prepared statement] S to have an SQL value of NULL, but to also be +** associated with the pointer P of type T. ^D is either a NULL pointer or +** a pointer to a destructor function for P. ^SQLite will invoke the +** destructor D with a single argument of P when it is finished using +** P. The T parameter should be a static string, preferably a string +** literal. The sqlite3_bind_pointer() routine is part of the +** [pointer passing interface] added for SQLite 3.20.0. +** ** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer ** for the [prepared statement] or with a prepared statement for which ** [sqlite3_step()] has been called more recently than [sqlite3_reset()], @@ -3794,6 +3925,7 @@ SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*) SQLITE_API int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, void(*)(void*), unsigned char encoding); SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +SQLITE_API int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*,void(*)(void*)); SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64); @@ -3837,8 +3969,8 @@ SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*); ** ^If the value N is out of range or if the N-th parameter is ** nameless, then NULL is returned. ^The returned string is ** always in UTF-8 encoding even if the named parameter was -** originally specified as UTF-16 in [sqlite3_prepare16()] or -** [sqlite3_prepare16_v2()]. +** originally specified as UTF-16 in [sqlite3_prepare16()], +** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()]. ** ** See also: [sqlite3_bind_blob|sqlite3_bind()], ** [sqlite3_bind_parameter_count()], and @@ -3855,7 +3987,8 @@ SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); ** parameter to [sqlite3_bind_blob|sqlite3_bind()]. ^A zero ** is returned if no matching parameter is found. ^The parameter ** name must be given in UTF-8 even if the original statement -** was prepared from UTF-16 text using [sqlite3_prepare16_v2()]. +** was prepared from UTF-16 text using [sqlite3_prepare16_v2()] or +** [sqlite3_prepare16_v3()]. ** ** See also: [sqlite3_bind_blob|sqlite3_bind()], ** [sqlite3_bind_parameter_count()], and @@ -3878,8 +4011,12 @@ SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*); ** METHOD: sqlite3_stmt ** ** ^Return the number of columns in the result set returned by the -** [prepared statement]. ^This routine returns 0 if pStmt is an SQL -** statement that does not return data (for example an [UPDATE]). +** [prepared statement]. ^If this routine returns 0, that means the +** [prepared statement] returns no data (for example an [UPDATE]). +** ^However, just because this routine returns a positive number does not +** mean that one or more rows of data will be returned. ^A SELECT statement +** will always have a positive sqlite3_column_count() but depending on the +** WHERE clause constraints and the table content, it might return no rows. ** ** See also: [sqlite3_data_count()] */ @@ -4005,16 +4142,18 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); ** CAPI3REF: Evaluate An SQL Statement ** METHOD: sqlite3_stmt ** -** After a [prepared statement] has been prepared using either -** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy +** After a [prepared statement] has been prepared using any of +** [sqlite3_prepare_v2()], [sqlite3_prepare_v3()], [sqlite3_prepare16_v2()], +** or [sqlite3_prepare16_v3()] or one of the legacy ** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function ** must be called one or more times to evaluate the statement. ** ** The details of the behavior of the sqlite3_step() interface depend -** on whether the statement was prepared using the newer "v2" interface -** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy -** interface [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the -** new "v2" interface is recommended for new applications but the legacy +** on whether the statement was prepared using the newer "vX" interfaces +** [sqlite3_prepare_v3()], [sqlite3_prepare_v2()], [sqlite3_prepare16_v3()], +** [sqlite3_prepare16_v2()] or the older legacy +** interfaces [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the +** new "vX" interface is recommended for new applications but the legacy ** interface will continue to be supported. ** ** ^In the legacy interface, the return value will be either [SQLITE_BUSY], @@ -4060,7 +4199,7 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); ** other than [SQLITE_ROW] before any subsequent invocation of ** sqlite3_step(). Failure to reset the prepared statement using ** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from -** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1], +** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1]), ** sqlite3_step() began ** calling [sqlite3_reset()] automatically in this circumstance rather ** than returning [SQLITE_MISUSE]. This is not considered a compatibility @@ -4075,10 +4214,11 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); ** specific [error codes] that better describes the error. ** We admit that this is a goofy design. The problem has been fixed ** with the "v2" interface. If you prepare all of your SQL statements -** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead +** using [sqlite3_prepare_v3()] or [sqlite3_prepare_v2()] +** or [sqlite3_prepare16_v2()] or [sqlite3_prepare16_v3()] instead ** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces, ** then the more specific [error codes] are returned directly -** by sqlite3_step(). The use of the "v2" interface is recommended. +** by sqlite3_step(). The use of the "vX" interfaces is recommended. */ SQLITE_API int sqlite3_step(sqlite3_stmt*); @@ -4140,6 +4280,28 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** KEYWORDS: {column access functions} ** METHOD: sqlite3_stmt ** +** Summary: +**

    +**
    sqlite3_column_blobBLOB result +**
    sqlite3_column_doubleREAL result +**
    sqlite3_column_int32-bit INTEGER result +**
    sqlite3_column_int6464-bit INTEGER result +**
    sqlite3_column_textUTF-8 TEXT result +**
    sqlite3_column_text16UTF-16 TEXT result +**
    sqlite3_column_valueThe result as an +** [sqlite3_value|unprotected sqlite3_value] object. +**
        +**
    sqlite3_column_bytesSize of a BLOB +** or a UTF-8 TEXT result in bytes +**
    sqlite3_column_bytes16   +** →  Size of UTF-16 +** TEXT in bytes +**
    sqlite3_column_typeDefault +** datatype of the result +**
    +** +** Details: +** ** ^These routines return information about a single column of the current ** result row of a query. ^In every case the first argument is a pointer ** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*] @@ -4161,16 +4323,29 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** are called from a different thread while any of these routines ** are pending, then the results are undefined. ** +** The first six interfaces (_blob, _double, _int, _int64, _text, and _text16) +** each return the value of a result column in a specific data format. If +** the result column is not initially in the requested format (for example, +** if the query returns an integer but the sqlite3_column_text() interface +** is used to extract the value) then an automatic type conversion is performed. +** ** ^The sqlite3_column_type() routine returns the ** [SQLITE_INTEGER | datatype code] for the initial data type ** of the result column. ^The returned value is one of [SQLITE_INTEGER], -** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. The value -** returned by sqlite3_column_type() is only meaningful if no type -** conversions have occurred as described below. After a type conversion, -** the value returned by sqlite3_column_type() is undefined. Future +** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. +** The return value of sqlite3_column_type() can be used to decide which +** of the first six interface should be used to extract the column value. +** The value returned by sqlite3_column_type() is only meaningful if no +** automatic type conversions have occurred for the value in question. +** After a type conversion, the result of calling sqlite3_column_type() +** is undefined, though harmless. Future ** versions of SQLite may change the behavior of sqlite3_column_type() ** following a type conversion. ** +** If the result is a BLOB or a TEXT string, then the sqlite3_column_bytes() +** or sqlite3_column_bytes16() interfaces can be used to determine the size +** of that BLOB or string. +** ** ^If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() ** routine returns the number of bytes in that BLOB or string. ** ^If the result is a UTF-16 string, then sqlite3_column_bytes() converts @@ -4207,9 +4382,13 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** [sqlite3_column_value()] is used in any other way, including calls ** to routines like [sqlite3_value_int()], [sqlite3_value_text()], ** or [sqlite3_value_bytes()], the behavior is not threadsafe. +** Hence, the sqlite3_column_value() interface +** is normally only useful within the implementation of +** [application-defined SQL functions] or [virtual tables], not within +** top-level application code. ** -** These routines attempt to convert the value where appropriate. ^For -** example, if the internal representation is FLOAT and a text result +** The these routines may attempt to convert the datatype of the result. +** ^For example, if the internal representation is FLOAT and a text result ** is requested, [sqlite3_snprintf()] is used internally to perform the ** conversion automatically. ^(The following table details the conversions ** that are applied: @@ -4281,7 +4460,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** ^The pointers returned are valid until a type conversion occurs as ** described above, or until [sqlite3_step()] or [sqlite3_reset()] or ** [sqlite3_finalize()] is called. ^The memory space used to hold strings -** and BLOBs is freed automatically. Do not pass the pointers returned +** and BLOBs is freed automatically. Do not pass the pointers returned ** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into ** [sqlite3_free()]. ** @@ -4292,15 +4471,15 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** [SQLITE_NOMEM].)^ */ SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); -SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol); -SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol); SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol); SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); -SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol); SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol); /* ** CAPI3REF: Destroy A Prepared Statement Object @@ -4534,21 +4713,40 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6 ** CAPI3REF: Obtaining SQL Values ** METHOD: sqlite3_value ** -** The C-language implementation of SQL functions and aggregates uses -** this set of interface routines to access the parameter values on -** the function or aggregate. +** Summary: +**
    +**
    sqlite3_value_blobBLOB value +**
    sqlite3_value_doubleREAL value +**
    sqlite3_value_int32-bit INTEGER value +**
    sqlite3_value_int6464-bit INTEGER value +**
    sqlite3_value_pointerPointer value +**
    sqlite3_value_textUTF-8 TEXT value +**
    sqlite3_value_text16UTF-16 TEXT value in +** the native byteorder +**
    sqlite3_value_text16beUTF-16be TEXT value +**
    sqlite3_value_text16leUTF-16le TEXT value +**
        +**
    sqlite3_value_bytesSize of a BLOB +** or a UTF-8 TEXT in bytes +**
    sqlite3_value_bytes16   +** →  Size of UTF-16 +** TEXT in bytes +**
    sqlite3_value_typeDefault +** datatype of the value +**
    sqlite3_value_numeric_type   +** →  Best numeric datatype of the value +**
    ** -** The xFunc (for scalar functions) or xStep (for aggregates) parameters -** to [sqlite3_create_function()] and [sqlite3_create_function16()] -** define callbacks that implement the SQL functions and aggregates. -** The 3rd parameter to these callbacks is an array of pointers to -** [protected sqlite3_value] objects. There is one [sqlite3_value] object for -** each parameter to the SQL function. These routines are used to -** extract values from the [sqlite3_value] objects. +** Details: +** +** These routines extract type, size, and content information from +** [protected sqlite3_value] objects. Protected sqlite3_value objects +** are used to pass parameter information into implementation of +** [application-defined SQL functions] and [virtual tables]. ** ** These routines work only with [protected sqlite3_value] objects. ** Any attempt to use these routines on an [unprotected sqlite3_value] -** object results in undefined behavior. +** is not threadsafe. ** ** ^These routines work just like the corresponding [column access functions] ** except that these routines take a single [protected sqlite3_value] object @@ -4559,6 +4757,24 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6 ** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces ** extract UTF-16 strings as big-endian and little-endian respectively. ** +** ^If [sqlite3_value] object V was initialized +** using [sqlite3_bind_pointer(S,I,P,X,D)] or [sqlite3_result_pointer(C,P,X,D)] +** and if X and Y are strings that compare equal according to strcmp(X,Y), +** then sqlite3_value_pointer(V,Y) will return the pointer P. ^Otherwise, +** sqlite3_value_pointer(V,Y) returns a NULL. The sqlite3_bind_pointer() +** routine is part of the [pointer passing interface] added for SQLite 3.20.0. +** +** ^(The sqlite3_value_type(V) interface returns the +** [SQLITE_INTEGER | datatype code] for the initial datatype of the +** [sqlite3_value] object V. The returned value is one of [SQLITE_INTEGER], +** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].)^ +** Other interfaces might change the datatype for an sqlite3_value object. +** For example, if the datatype is initially SQLITE_INTEGER and +** sqlite3_value_text(V) is called to extract a text value for that +** integer, then subsequent calls to sqlite3_value_type(V) might return +** SQLITE_TEXT. Whether or not a persistent internal datatype conversion +** occurs is undefined and may change from one release of SQLite to the next. +** ** ^(The sqlite3_value_numeric_type() interface attempts to apply ** numeric affinity to the value. This means that an attempt is ** made to convert the value to an integer or floating point. If @@ -4577,15 +4793,16 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6 ** the SQL function that supplied the [sqlite3_value*] parameters. */ SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); -SQLITE_API int sqlite3_value_bytes(sqlite3_value*); -SQLITE_API int sqlite3_value_bytes16(sqlite3_value*); SQLITE_API double sqlite3_value_double(sqlite3_value*); SQLITE_API int sqlite3_value_int(sqlite3_value*); SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*); +SQLITE_API void *sqlite3_value_pointer(sqlite3_value*, const char*); SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*); SQLITE_API const void *sqlite3_value_text16(sqlite3_value*); SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*); SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*); +SQLITE_API int sqlite3_value_bytes(sqlite3_value*); +SQLITE_API int sqlite3_value_bytes16(sqlite3_value*); SQLITE_API int sqlite3_value_type(sqlite3_value*); SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); @@ -4598,10 +4815,6 @@ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); ** information can be used to pass a limited amount of context from ** one SQL function to another. Use the [sqlite3_result_subtype()] ** routine to set the subtype for the return value of an SQL function. -** -** SQLite makes no use of subtype itself. It merely passes the subtype -** from the result of one [application-defined SQL function] into the -** input of another. */ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); @@ -4709,10 +4922,11 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** the compiled regular expression can be reused on multiple ** invocations of the same function. ** -** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata -** associated by the sqlite3_set_auxdata() function with the Nth argument -** value to the application-defined function. ^If there is no metadata -** associated with the function argument, this sqlite3_get_auxdata() interface +** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata +** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument +** value to the application-defined function. ^N is zero for the left-most +** function argument. ^If there is no metadata +** associated with the function argument, the sqlite3_get_auxdata(C,N) interface ** returns a NULL pointer. ** ** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th @@ -4743,6 +4957,10 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** function parameters that are compile-time constants, including literal ** values and [parameters] and expressions composed from the same.)^ ** +** The value of the N parameter to these interfaces should be non-negative. +** Future enhancements may make use of negative N values to define new +** kinds of function caching behavior. +** ** These routines must be called from the same thread in which ** the SQL function is running. */ @@ -4866,7 +5084,7 @@ typedef void (*sqlite3_destructor_type)(void*); ** when it has finished using that result. ** ^If the 4th parameter to the sqlite3_result_text* interfaces ** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT -** then SQLite makes a copy of the result into space obtained from +** then SQLite makes a copy of the result into space obtained ** from [sqlite3_malloc()] before it returns. ** ** ^The sqlite3_result_value() interface sets the result of @@ -4879,6 +5097,17 @@ typedef void (*sqlite3_destructor_type)(void*); ** [unprotected sqlite3_value] object is required, so either ** kind of [sqlite3_value] object can be used with this interface. ** +** ^The sqlite3_result_pointer(C,P,T,D) interface sets the result to an +** SQL NULL value, just like [sqlite3_result_null(C)], except that it +** also associates the host-language pointer P or type T with that +** NULL value such that the pointer can be retrieved within an +** [application-defined SQL function] using [sqlite3_value_pointer()]. +** ^If the D parameter is not NULL, then it is a pointer to a destructor +** for the P parameter. ^SQLite invokes D with P as its only argument +** when SQLite is finished with P. The T parameter should be a static +** string and preferably a string literal. The sqlite3_result_pointer() +** routine is part of the [pointer passing interface] added for SQLite 3.20.0. +** ** If these routines are called from within the different thread ** than the one containing the application-defined function that received ** the [sqlite3_context] pointer, the results are undefined. @@ -4902,6 +5131,7 @@ SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(* SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*); +SQLITE_API void sqlite3_result_pointer(sqlite3_context*, void*,const char*,void(*)(void*)); SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n); SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n); @@ -5388,7 +5618,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); ** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified. ** ** ^In the current implementation, the update hook -** is not invoked when duplication rows are deleted because of an +** is not invoked when conflicting rows are deleted because of an ** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook ** invoked when rows are deleted using the [truncate optimization]. ** The exceptions defined in this paragraph might change in a future @@ -5561,7 +5791,9 @@ SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N); ** ^If the column-name parameter to sqlite3_table_column_metadata() is a ** NULL pointer, then this routine simply checks for the existence of the ** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it -** does not. +** does not. If the table name parameter T in a call to +** sqlite3_table_column_metadata(X,D,T,C,...) is NULL then the result is +** undefined behavior. ** ** ^The column is identified by the second, third and fourth parameters to ** this function. ^(The second parameter is either the name of the database @@ -6170,6 +6402,12 @@ typedef struct sqlite3_blob sqlite3_blob; ** [database connection] error code and message accessible via ** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. ** +** A BLOB referenced by sqlite3_blob_open() may be read using the +** [sqlite3_blob_read()] interface and modified by using +** [sqlite3_blob_write()]. The [BLOB handle] can be moved to a +** different row of the same table using the [sqlite3_blob_reopen()] +** interface. However, the column, table, or database of a [BLOB handle] +** cannot be changed after the [BLOB handle] is opened. ** ** ^(If the row that a BLOB handle points to is modified by an ** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects @@ -6193,6 +6431,10 @@ typedef struct sqlite3_blob sqlite3_blob; ** ** To avoid a resource leak, every open [BLOB handle] should eventually ** be released by a call to [sqlite3_blob_close()]. +** +** See also: [sqlite3_blob_close()], +** [sqlite3_blob_reopen()], [sqlite3_blob_read()], +** [sqlite3_blob_bytes()], [sqlite3_blob_write()]. */ SQLITE_API int sqlite3_blob_open( sqlite3*, @@ -6208,11 +6450,11 @@ SQLITE_API int sqlite3_blob_open( ** CAPI3REF: Move a BLOB Handle to a New Row ** METHOD: sqlite3_blob ** -** ^This function is used to move an existing blob handle so that it points +** ^This function is used to move an existing [BLOB handle] so that it points ** to a different row of the same database table. ^The new row is identified ** by the rowid value passed as the second argument. Only the row can be ** changed. ^The database, table and column on which the blob handle is open -** remain the same. Moving an existing blob handle to a new row can be +** remain the same. Moving an existing [BLOB handle] to a new row is ** faster than closing the existing handle and opening a new one. ** ** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] - @@ -7064,6 +7306,24 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** used as a proxy for the total work done by the prepared statement. ** If the number of virtual machine operations exceeds 2147483647 ** then the value returned by this statement status code is undefined. +** +** [[SQLITE_STMTSTATUS_REPREPARE]]
    SQLITE_STMTSTATUS_REPREPARE
    +**
    ^This is the number of times that the prepare statement has been +** automatically regenerated due to schema changes or change to +** [bound parameters] that might affect the query plan. +** +** [[SQLITE_STMTSTATUS_RUN]]
    SQLITE_STMTSTATUS_RUN
    +**
    ^This is the number of times that the prepared statement has +** been run. A single "run" for the purposes of this counter is one +** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()]. +** The counter is incremented on the first [sqlite3_step()] call of each +** cycle. +** +** [[SQLITE_STMTSTATUS_MEMUSED]]
    SQLITE_STMTSTATUS_MEMUSED
    +**
    ^This is the approximate number of bytes of heap memory +** used to store the prepared statement. ^This value is not actually +** a counter, and so the resetFlg parameter to sqlite3_stmt_status() +** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED. **
    ** */ @@ -7071,6 +7331,9 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); #define SQLITE_STMTSTATUS_SORT 2 #define SQLITE_STMTSTATUS_AUTOINDEX 3 #define SQLITE_STMTSTATUS_VM_STEP 4 +#define SQLITE_STMTSTATUS_REPREPARE 5 +#define SQLITE_STMTSTATUS_RUN 6 +#define SQLITE_STMTSTATUS_MEMUSED 99 /* ** CAPI3REF: Custom Page Cache Object @@ -8141,7 +8404,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); ** ** ^The [sqlite3_preupdate_hook()] interface registers a callback function ** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation -** on a [rowid table]. +** on a database table. ** ^At most one preupdate hook may be registered at a time on a single ** [database connection]; each call to [sqlite3_preupdate_hook()] overrides ** the previous setting. @@ -8150,9 +8413,9 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); ** ^The third parameter to [sqlite3_preupdate_hook()] is passed through as ** the first parameter to callbacks. ** -** ^The preupdate hook only fires for changes to [rowid tables]; the preupdate -** hook is not invoked for changes to [virtual tables] or [WITHOUT ROWID] -** tables. +** ^The preupdate hook only fires for changes to real database tables; the +** preupdate hook is not invoked for changes to [virtual tables] or to +** system tables like sqlite_master or sqlite_stat1. ** ** ^The second parameter to the preupdate callback is a pointer to ** the [database connection] that registered the preupdate hook. @@ -8166,12 +8429,16 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); ** databases.)^ ** ^The fifth parameter to the preupdate callback is the name of the ** table that is being modified. -** ^The sixth parameter to the preupdate callback is the initial [rowid] of the -** row being changes for SQLITE_UPDATE and SQLITE_DELETE changes and is -** undefined for SQLITE_INSERT changes. -** ^The seventh parameter to the preupdate callback is the final [rowid] of -** the row being changed for SQLITE_UPDATE and SQLITE_INSERT changes and is -** undefined for SQLITE_DELETE changes. +** +** For an UPDATE or DELETE operation on a [rowid table], the sixth +** parameter passed to the preupdate callback is the initial [rowid] of the +** row being modified or deleted. For an INSERT operation on a rowid table, +** or any operation on a WITHOUT ROWID table, the value of the sixth +** parameter is undefined. For an INSERT or UPDATE on a rowid table the +** seventh parameter is the final rowid value of the row being inserted +** or updated. The value of the seventh parameter passed to the callback +** function is not defined for operations on WITHOUT ROWID tables, or for +** INSERT operations on rowid tables. ** ** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()], ** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces @@ -8211,7 +8478,8 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); ** ** See also: [sqlite3_update_hook()] */ -SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_preupdate_hook( +#if defined(SQLITE_ENABLE_PREUPDATE_HOOK) +SQLITE_API void *sqlite3_preupdate_hook( sqlite3 *db, void(*xPreUpdate)( void *pCtx, /* Copy of third arg to preupdate_hook() */ @@ -8224,10 +8492,11 @@ SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_preupdate_hook( ), void* ); -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **); -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_preupdate_count(sqlite3 *); -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_preupdate_depth(sqlite3 *); -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); +SQLITE_API int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **); +SQLITE_API int sqlite3_preupdate_count(sqlite3 *); +SQLITE_API int sqlite3_preupdate_depth(sqlite3 *); +SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); +#endif /* ** CAPI3REF: Low-level system error code @@ -8243,7 +8512,7 @@ SQLITE_API int sqlite3_system_errno(sqlite3*); /* ** CAPI3REF: Database Snapshot -** KEYWORDS: {snapshot} +** KEYWORDS: {snapshot} {sqlite3_snapshot} ** EXPERIMENTAL ** ** An instance of the snapshot object records the state of a [WAL mode] @@ -8267,7 +8536,9 @@ SQLITE_API int sqlite3_system_errno(sqlite3*); ** to an historical snapshot (if possible). The destructor for ** sqlite3_snapshot objects is [sqlite3_snapshot_free()]. */ -typedef struct sqlite3_snapshot sqlite3_snapshot; +typedef struct sqlite3_snapshot { + unsigned char hidden[48]; +} sqlite3_snapshot; /* ** CAPI3REF: Record A Database Snapshot @@ -8278,9 +8549,32 @@ typedef struct sqlite3_snapshot sqlite3_snapshot; ** schema S in database connection D. ^On success, the ** [sqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly ** created [sqlite3_snapshot] object into *P and returns SQLITE_OK. -** ^If schema S of [database connection] D is not a [WAL mode] database -** that is in a read transaction, then [sqlite3_snapshot_get(D,S,P)] -** leaves the *P value unchanged and returns an appropriate [error code]. +** If there is not already a read-transaction open on schema S when +** this function is called, one is opened automatically. +** +** The following must be true for this function to succeed. If any of +** the following statements are false when sqlite3_snapshot_get() is +** called, SQLITE_ERROR is returned. The final value of *P is undefined +** in this case. +** +** +** +** This function may also return SQLITE_NOMEM. If it is called with the +** database handle in autocommit mode but fails for some other reason, +** whether or not a read transaction is opened on schema S is undefined. ** ** The [sqlite3_snapshot] object returned from a successful call to ** [sqlite3_snapshot_get()] must be freed using [sqlite3_snapshot_free()] @@ -8373,6 +8667,28 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp( sqlite3_snapshot *p2 ); +/* +** CAPI3REF: Recover snapshots from a wal file +** EXPERIMENTAL +** +** If all connections disconnect from a database file but do not perform +** a checkpoint, the existing wal file is opened along with the database +** file the next time the database is opened. At this point it is only +** possible to successfully call sqlite3_snapshot_open() to open the most +** recent snapshot of the database (the one at the head of the wal file), +** even though the wal file may contain other valid snapshots for which +** clients have sqlite3_snapshot handles. +** +** This function attempts to scan the wal file associated with database zDb +** of database handle db and make all valid snapshots available to +** sqlite3_snapshot_open(). It is an error if there is already a read +** transaction open on the database, or if the database is not a wal mode +** database. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); + /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. @@ -8558,7 +8874,7 @@ typedef struct sqlite3_changeset_iter sqlite3_changeset_iter; ** attached database. It is not an error if database zDb is not attached ** to the database when the session object is created. */ -int sqlite3session_create( +SQLITE_API int sqlite3session_create( sqlite3 *db, /* Database handle */ const char *zDb, /* Name of db (e.g. "main") */ sqlite3_session **ppSession /* OUT: New session object */ @@ -8576,7 +8892,7 @@ int sqlite3session_create( ** are attached is closed. Refer to the documentation for ** [sqlite3session_create()] for details. */ -void sqlite3session_delete(sqlite3_session *pSession); +SQLITE_API void sqlite3session_delete(sqlite3_session *pSession); /* @@ -8596,7 +8912,7 @@ void sqlite3session_delete(sqlite3_session *pSession); ** The return value indicates the final state of the session object: 0 if ** the session is disabled, or 1 if it is enabled. */ -int sqlite3session_enable(sqlite3_session *pSession, int bEnable); +SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable); /* ** CAPI3REF: Set Or Clear the Indirect Change Flag @@ -8625,7 +8941,7 @@ int sqlite3session_enable(sqlite3_session *pSession, int bEnable); ** The return value indicates the final state of the indirect flag: 0 if ** it is clear, or 1 if it is set. */ -int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect); +SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect); /* ** CAPI3REF: Attach A Table To A Session Object @@ -8655,7 +8971,7 @@ int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect); ** SQLITE_OK is returned if the call completes without error. Or, if an error ** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned. */ -int sqlite3session_attach( +SQLITE_API int sqlite3session_attach( sqlite3_session *pSession, /* Session object */ const char *zTab /* Table name */ ); @@ -8669,7 +8985,7 @@ int sqlite3session_attach( ** If xFilter returns 0, changes is not tracked. Note that once a table is ** attached, xFilter will not be called again. */ -void sqlite3session_table_filter( +SQLITE_API void sqlite3session_table_filter( sqlite3_session *pSession, /* Session object */ int(*xFilter)( void *pCtx, /* Copy of third arg to _filter_table() */ @@ -8782,7 +9098,7 @@ void sqlite3session_table_filter( ** another field of the same row is updated while the session is enabled, the ** resulting changeset will contain an UPDATE change that updates both fields. */ -int sqlite3session_changeset( +SQLITE_API int sqlite3session_changeset( sqlite3_session *pSession, /* Session object */ int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ void **ppChangeset /* OUT: Buffer containing changeset */ @@ -8826,7 +9142,8 @@ int sqlite3session_changeset( ** the from-table, a DELETE record is added to the session object. ** **
  • For each row (primary key) that exists in both tables, but features -** different in each, an UPDATE record is added to the session. +** different non-PK values in each, an UPDATE record is added to the +** session. ** ** ** To clarify, if this function is called and then a changeset constructed @@ -8843,7 +9160,7 @@ int sqlite3session_changeset( ** message. It is the responsibility of the caller to free this buffer using ** sqlite3_free(). */ -int sqlite3session_diff( +SQLITE_API int sqlite3session_diff( sqlite3_session *pSession, const char *zFromDb, const char *zTbl, @@ -8879,7 +9196,7 @@ int sqlite3session_diff( ** a single table are grouped together, tables appear in the order in which ** they were attached to the session object). */ -int sqlite3session_patchset( +SQLITE_API int sqlite3session_patchset( sqlite3_session *pSession, /* Session object */ int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */ void **ppPatchset /* OUT: Buffer containing changeset */ @@ -8900,7 +9217,7 @@ int sqlite3session_patchset( ** guaranteed that a call to sqlite3session_changeset() will return a ** changeset containing zero changes. */ -int sqlite3session_isempty(sqlite3_session *pSession); +SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession); /* ** CAPI3REF: Create An Iterator To Traverse A Changeset @@ -8935,7 +9252,7 @@ int sqlite3session_isempty(sqlite3_session *pSession); ** the applies to table X, then one for table Y, and then later on visit ** another change for table X. */ -int sqlite3changeset_start( +SQLITE_API int sqlite3changeset_start( sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */ int nChangeset, /* Size of changeset blob in bytes */ void *pChangeset /* Pointer to blob containing changeset */ @@ -8964,7 +9281,7 @@ int sqlite3changeset_start( ** codes include SQLITE_CORRUPT (if the changeset buffer is corrupt) or ** SQLITE_NOMEM. */ -int sqlite3changeset_next(sqlite3_changeset_iter *pIter); +SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter); /* ** CAPI3REF: Obtain The Current Operation From A Changeset Iterator @@ -8992,7 +9309,7 @@ int sqlite3changeset_next(sqlite3_changeset_iter *pIter); ** SQLite error code is returned. The values of the output variables may not ** be trusted in this case. */ -int sqlite3changeset_op( +SQLITE_API int sqlite3changeset_op( sqlite3_changeset_iter *pIter, /* Iterator object */ const char **pzTab, /* OUT: Pointer to table name */ int *pnCol, /* OUT: Number of columns in table */ @@ -9025,7 +9342,7 @@ int sqlite3changeset_op( ** SQLITE_OK is returned and the output variables populated as described ** above. */ -int sqlite3changeset_pk( +SQLITE_API int sqlite3changeset_pk( sqlite3_changeset_iter *pIter, /* Iterator object */ unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */ int *pnCol /* OUT: Number of entries in output array */ @@ -9055,7 +9372,7 @@ int sqlite3changeset_pk( ** If some other error occurs (e.g. an OOM condition), an SQLite error code ** is returned and *ppValue is set to NULL. */ -int sqlite3changeset_old( +SQLITE_API int sqlite3changeset_old( sqlite3_changeset_iter *pIter, /* Changeset iterator */ int iVal, /* Column number */ sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */ @@ -9088,7 +9405,7 @@ int sqlite3changeset_old( ** If some other error occurs (e.g. an OOM condition), an SQLite error code ** is returned and *ppValue is set to NULL. */ -int sqlite3changeset_new( +SQLITE_API int sqlite3changeset_new( sqlite3_changeset_iter *pIter, /* Changeset iterator */ int iVal, /* Column number */ sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */ @@ -9115,7 +9432,7 @@ int sqlite3changeset_new( ** If some other error occurs (e.g. an OOM condition), an SQLite error code ** is returned and *ppValue is set to NULL. */ -int sqlite3changeset_conflict( +SQLITE_API int sqlite3changeset_conflict( sqlite3_changeset_iter *pIter, /* Changeset iterator */ int iVal, /* Column number */ sqlite3_value **ppValue /* OUT: Value from conflicting row */ @@ -9131,7 +9448,7 @@ int sqlite3changeset_conflict( ** ** In all other cases this function returns SQLITE_MISUSE. */ -int sqlite3changeset_fk_conflicts( +SQLITE_API int sqlite3changeset_fk_conflicts( sqlite3_changeset_iter *pIter, /* Changeset iterator */ int *pnOut /* OUT: Number of FK violations */ ); @@ -9164,7 +9481,7 @@ int sqlite3changeset_fk_conflicts( ** // An error has occurred ** } */ -int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter); +SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter); /* ** CAPI3REF: Invert A Changeset @@ -9194,7 +9511,7 @@ int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter); ** WARNING/TODO: This function currently assumes that the input is a valid ** changeset. If it is not, the results are undefined. */ -int sqlite3changeset_invert( +SQLITE_API int sqlite3changeset_invert( int nIn, const void *pIn, /* Input changeset */ int *pnOut, void **ppOut /* OUT: Inverse of input */ ); @@ -9223,7 +9540,7 @@ int sqlite3changeset_invert( ** ** Refer to the sqlite3_changegroup documentation below for details. */ -int sqlite3changeset_concat( +SQLITE_API int sqlite3changeset_concat( int nA, /* Number of bytes in buffer pA */ void *pA, /* Pointer to buffer containing changeset A */ int nB, /* Number of bytes in buffer pB */ @@ -9273,7 +9590,7 @@ typedef struct sqlite3_changegroup sqlite3_changegroup; ** sqlite3changegroup_output() functions, also available are the streaming ** versions sqlite3changegroup_add_strm() and sqlite3changegroup_output_strm(). */ -int sqlite3changegroup_new(sqlite3_changegroup **pp); +SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp); /* ** CAPI3REF: Add A Changeset To A Changegroup @@ -9350,7 +9667,7 @@ int sqlite3changegroup_new(sqlite3_changegroup **pp); ** ** If no error occurs, SQLITE_OK is returned. */ -int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); +SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); /* ** CAPI3REF: Obtain A Composite Changeset From A Changegroup @@ -9376,7 +9693,7 @@ int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); ** responsibility of the caller to eventually free the buffer using a ** call to sqlite3_free(). */ -int sqlite3changegroup_output( +SQLITE_API int sqlite3changegroup_output( sqlite3_changegroup*, int *pnData, /* OUT: Size of output buffer in bytes */ void **ppData /* OUT: Pointer to output buffer */ @@ -9385,7 +9702,7 @@ int sqlite3changegroup_output( /* ** CAPI3REF: Delete A Changegroup Object */ -void sqlite3changegroup_delete(sqlite3_changegroup*); +SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*); /* ** CAPI3REF: Apply A Changeset To A Database @@ -9411,7 +9728,7 @@ void sqlite3changegroup_delete(sqlite3_changegroup*); **