25 Commits

Author SHA1 Message Date
951155f1b6 build: Use this apksigner workaround for reproducible builds: https://gitlab.com/fdroid/fdroiddata/-/issues/3299. 2025-07-02 20:35:51 -04:00
1b678175ef build: Missed a number. Let's build a 0.0.32.1 with the version bumps and release it on F-Droid to see that we can. 2025-07-02 19:34:33 -04:00
8eb1f40eec build: Only build docs once, and use the right number of jobs. 2025-07-02 19:12:08 -04:00
235887b3bf android: Bump android versions in the gitea action, too. 2025-07-02 18:59:29 -04:00
0b3d66dd48 android: Google says: 'App must target Android 15 (API level 35) or higher'. Bump SDK versions while I'm in here. 2025-07-02 18:53:04 -04:00
beb9ef3754 ssb: Add a missing 'Encrypt' label. 2025-07-02 18:30:35 -04:00
9f6a480736 ssb: Nudge around some space around the compose widget. 2025-07-02 18:29:02 -04:00
b3bac2927d ssb: Shorten the timed query output. 2025-07-02 18:21:40 -04:00
ef389f2ba2 ssb: The unread line can be used to make everything above read. 2025-07-02 18:19:34 -04:00
ef21dc6ae8 ssb: Use img title=, not alt= for more browser support. 2025-07-02 12:49:14 -04:00
6e55b6b49e ssb: Show sync/stay connected options on the sidebar when relevant. 2025-07-02 12:41:03 -04:00
db115ef1bd cleanup: Just assessing how much we need OpenSSL and noticed cruft. 2025-07-01 18:42:43 -04:00
678838dbd5 update: OpenSSL 3.5.1. 2025-07-01 18:32:19 -04:00
586f87625d ssb: Revise the message queries slightly to not include votes where it might just be noisy. 2025-07-01 12:50:02 -04:00
1542370f9b ssb: Let's try not tracking vote unread status. It's useful that the channel is there, but it's too noisy for me to want to mark it as read. 2025-07-01 12:41:25 -04:00
1f7d5968c7 update: CodeMirror. 2025-06-29 17:21:26 -04:00
39e51f7790 update: sqlite 3.50.2. 2025-06-29 17:20:50 -04:00
052663efbe ssb: Proof of concept to try to stay connected to a handful of peers. 2025-06-28 13:47:58 -04:00
8f84ff2611 ssb: Collapse contact group users to only icons. 2025-06-27 12:46:15 -04:00
37e1c5d97b core: Use crypto_generichash. We don't need to roll our own FNV32a. 2025-06-25 21:10:05 -04:00
cef526bcf3 ssb: Fix the tab cycling order. 2025-06-25 20:23:01 -04:00
6af36cafa9 ssb: Wait, I don't think we need to close any connections here. 2025-06-25 20:10:22 -04:00
fca859d93d ssb: Are we inadvertantly closing connections when an inner tunnel request ends? 2025-06-25 20:00:44 -04:00
2178300d8d welcome: +PeachCloud. 2025-06-25 18:49:43 -04:00
636bdcce6b build: Start work on 0.0.33. nix => 0.0.32. 2025-06-25 18:34:59 -04:00
34 changed files with 466 additions and 330 deletions

@ -48,7 +48,7 @@ jobs:
- name: Build documentation - name: Build documentation
run: | run: |
mkdir -p out/html/ ~/.ssh/ mkdir -p out/html/ ~/.ssh/
make docs make -j`nproc` docs
echo 'pildefriends ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKD3Kde5vDO0TrMBDK0IGGeNGe/XinWAZkSQ/rXxwUjt' >> ~/.ssh/known_hosts echo 'pildefriends ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKD3Kde5vDO0TrMBDK0IGGeNGe/XinWAZkSQ/rXxwUjt' >> ~/.ssh/known_hosts
rsync -avP --delete -e "ssh -i /opt/keys/ssh.ed25519" out/html/ tfdocs@pildefriends:docs/html/ rsync -avP --delete -e "ssh -i /opt/keys/ssh.ed25519" out/html/ tfdocs@pildefriends:docs/html/
- name: Setup JDK - name: Setup JDK
@ -59,11 +59,11 @@ jobs:
- name: Setup Android SDK - name: Setup Android SDK
uses: android-actions/setup-android@v3 uses: android-actions/setup-android@v3
with: with:
packages: 'tools platform-tools build-tools;34.0.0 platforms;android-34 ndk;26.3.11579264' packages: 'tools platform-tools build-tools;35.0.0 platforms;android-35 ndk;27.2.12479018'
- name: Docker build - name: Docker build
run: DOCKER_BUILDKIT=1 docker build . run: DOCKER_BUILDKIT=1 docker build .
- name: Build - name: Build
run: ANDROID_SDK=$HOME/.android/sdk make -j`nproc` all dist docs run: ANDROID_SDK=$HOME/.android/sdk make -j`nproc` all dist
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:

@ -16,14 +16,14 @@ MAKEFLAGS += --no-builtin-rules
## LD := Linker. ## LD := Linker.
## ANDROID_SDK := Path to the Android SDK. ## ANDROID_SDK := Path to the Android SDK.
VERSION_CODE := 38 VERSION_CODE := 39
VERSION_CODE_IOS := 14 VERSION_CODE_IOS := 15
VERSION_NUMBER := 0.0.32 VERSION_NUMBER := 0.0.32.1
VERSION_NAME := This program kills fascists. VERSION_NAME := This program kills fascists.
IPHONEOS_VERSION_MIN=14.0 IPHONEOS_VERSION_MIN=14.0
SQLITE_URL := https://www.sqlite.org/2025/sqlite-amalgamation-3500100.zip SQLITE_URL := https://www.sqlite.org/2025/sqlite-amalgamation-3500200.zip
BUNDLETOOL_URL := https://github.com/google/bundletool/releases/download/1.17.0/bundletool-all-1.17.0.jar BUNDLETOOL_URL := https://github.com/google/bundletool/releases/download/1.17.0/bundletool-all-1.17.0.jar
APPIMAGETOOL_URL := https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage APPIMAGETOOL_URL := https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
APPIMAGETOOL_MD5 := e989fadfc4d685fd3d6aeeb9b525d74d out/appimagetool APPIMAGETOOL_MD5 := e989fadfc4d685fd3d6aeeb9b525d74d out/appimagetool
@ -106,10 +106,10 @@ LDFLAGS += \
-Wno-aggressive-loop-optimizations -Wno-aggressive-loop-optimizations
ANDROID_MIN_SDK_VERSION := 24 ANDROID_MIN_SDK_VERSION := 24
ANDROID_TARGET_SDK_VERSION := 34 ANDROID_TARGET_SDK_VERSION := 35
ANDROID_BUILD_TOOLS := $(ANDROID_SDK)/build-tools/34.0.0 ANDROID_BUILD_TOOLS := $(ANDROID_SDK)/build-tools/35.0.0
ANDROID_PLATFORM := $(ANDROID_SDK)/platforms/android-$(ANDROID_TARGET_SDK_VERSION) ANDROID_PLATFORM := $(ANDROID_SDK)/platforms/android-$(ANDROID_TARGET_SDK_VERSION)
ANDROID_NDK ?= $(ANDROID_SDK)/ndk/26.3.11579264 ANDROID_NDK ?= $(ANDROID_SDK)/ndk/27.2.12479018
ANDROID_ARMV7A_TARGETS := \ ANDROID_ARMV7A_TARGETS := \
out/androiddebug-armv7a/tildefriends \ out/androiddebug-armv7a/tildefriends \
@ -650,6 +650,7 @@ SODIUM_SOURCES := \
deps/libsodium/src/libsodium/crypto_core/hsalsa20/ref2/core_hsalsa20_ref2.c \ deps/libsodium/src/libsodium/crypto_core/hsalsa20/ref2/core_hsalsa20_ref2.c \
deps/libsodium/src/libsodium/crypto_core/salsa/ref/core_salsa_ref.c \ deps/libsodium/src/libsodium/crypto_core/salsa/ref/core_salsa_ref.c \
deps/libsodium/src/libsodium/crypto_core/softaes/softaes.c \ deps/libsodium/src/libsodium/crypto_core/softaes/softaes.c \
deps/libsodium/src/libsodium/crypto_generichash/crypto_generichash.c \
deps/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-ref.c \ deps/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-ref.c \
deps/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-ref.c \ deps/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-ref.c \
deps/libsodium/src/libsodium/crypto_generichash/blake2b/ref/generichash_blake2b.c \ deps/libsodium/src/libsodium/crypto_generichash/blake2b/ref/generichash_blake2b.c \
@ -1054,7 +1055,7 @@ out/TildeFriends.aab: out/apk/classes.dex $(filter-out %debug%, $(ANDROID_TARGET
@$(ANDROID_NDK)/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip --only-keep-debug out/androidrelease-x86_64/tildefriends -o out/aab/staging/BUNDLE-METADATA/com.android.tools.build.debugsymbols/x86_64/libtildefriends.so.sym @$(ANDROID_NDK)/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip --only-keep-debug out/androidrelease-x86_64/tildefriends -o out/aab/staging/BUNDLE-METADATA/com.android.tools.build.debugsymbols/x86_64/libtildefriends.so.sym
@$(ANDROID_NDK)/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip --only-keep-debug out/androidrelease-x86/tildefriends -o out/aab/staging/BUNDLE-METADATA/com.android.tools.build.debugsymbols/x86/libtildefriends.so.sym @$(ANDROID_NDK)/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip --only-keep-debug out/androidrelease-x86/tildefriends -o out/aab/staging/BUNDLE-METADATA/com.android.tools.build.debugsymbols/x86/libtildefriends.so.sym
@cd out/aab/staging; zip -u ../../../$@ BUNDLE-METADATA/com.android.tools.build.debugsymbols/arm64-v8a/libtildefriends.so.sym BUNDLE-METADATA/com.android.tools.build.debugsymbols/armeabi-v7a/libtildefriends.so.sym BUNDLE-METADATA/com.android.tools.build.debugsymbols/x86_64/libtildefriends.so.sym BUNDLE-METADATA/com.android.tools.build.debugsymbols/x86/libtildefriends.so.sym; cd ../../../ @cd out/aab/staging; zip -u ../../../$@ BUNDLE-METADATA/com.android.tools.build.debugsymbols/arm64-v8a/libtildefriends.so.sym BUNDLE-METADATA/com.android.tools.build.debugsymbols/armeabi-v7a/libtildefriends.so.sym BUNDLE-METADATA/com.android.tools.build.debugsymbols/x86_64/libtildefriends.so.sym BUNDLE-METADATA/com.android.tools.build.debugsymbols/x86/libtildefriends.so.sym; cd ../../../
@$(ANDROID_BUILD_TOOLS)/apksigner sign -ks .keys/android.jks --ks-key-alias androidKey -ks-pass pass:android --min-sdk-version=$(ANDROID_MIN_SDK_VERSION) $@ @$(ANDROID_BUILD_TOOLS)/apksigner sign -ks .keys/android.jks --ks-key-alias androidKey -ks-pass pass:android --min-sdk-version=$(ANDROID_MIN_SDK_VERSION) --alignment-preserved $@
aab: out/TildeFriends.aab ## Build an Android App Bundle. aab: out/TildeFriends.aab ## Build an Android App Bundle.
.PHONY: aab .PHONY: aab
@ -1116,12 +1117,12 @@ out/apk/TildeFriends-%.fdroid.unsigned.apk:
out/%.apk: out/apk/%.unsigned.apk out/%.apk: out/apk/%.unsigned.apk
@echo "[apksigner] $(notdir $@)" @echo "[apksigner] $(notdir $@)"
@$(ANDROID_BUILD_TOOLS)/apksigner sign --ks .keys/android.jks --ks-key-alias androidKey --ks-pass pass:android --key-pass pass:android --min-sdk-version $(ANDROID_MIN_SDK_VERSION) --out $@ $< @$(ANDROID_BUILD_TOOLS)/apksigner sign --ks .keys/android.jks --ks-key-alias androidKey --ks-pass pass:android --key-pass pass:android --min-sdk-version $(ANDROID_MIN_SDK_VERSION) --out $@ --alignment-preserved $<
out/%.zopfli.apk: out/%.apk out/%.zopfli.apk: out/%.apk
@echo "[zopfli] $(notdir $@)" @echo "[zopfli] $(notdir $@)"
$(ANDROID_BUILD_TOOLS)/zipalign -f -z 4 $< $@.zopfli $(ANDROID_BUILD_TOOLS)/zipalign -f -z 4 $< $@.zopfli
@$(ANDROID_BUILD_TOOLS)/apksigner sign --ks .keys/android.jks --ks-key-alias androidKey --ks-pass pass:android --key-pass pass:android --min-sdk-version $(ANDROID_MIN_SDK_VERSION) --out $@ $@.zopfli @$(ANDROID_BUILD_TOOLS)/apksigner sign --ks .keys/android.jks --ks-key-alias androidKey --ks-pass pass:android --key-pass pass:android --min-sdk-version $(ANDROID_MIN_SDK_VERSION) --out $@ --alignment-preserved $@.zopfli
release-apk: out/TildeFriends-arm-release.zopfli.apk out/TildeFriends-x86-release.zopfli.apk ## Build an Android release APK. release-apk: out/TildeFriends-arm-release.zopfli.apk out/TildeFriends-x86-release.zopfli.apk ## Build an Android release APK.
.PHONY: release-apk .PHONY: release-apk

@ -1,5 +1,5 @@
{ {
"type": "tildefriends-app", "type": "tildefriends-app",
"emoji": "🦀", "emoji": "🦀",
"previous": "&Rn4Eg5ev5qhrYRnwxPB0DiEwO7VdGMDGp7tL/W7bRZo=.sha256" "previous": "&Ym1vefMN4CV4UIgLuV+zu52qj58WwIScctt4v5YIHmQ=.sha256"
} }

@ -23,6 +23,8 @@ class TfElement extends LitElement {
url: {type: String}, url: {type: String},
private_messages: {type: Array}, private_messages: {type: Array},
recent_reactions: {type: Array}, recent_reactions: {type: Array},
is_administrator: {type: Boolean},
stay_connected: {type: Boolean},
}; };
} }
@ -73,6 +75,10 @@ class TfElement extends LitElement {
async initial_load() { async initial_load() {
let whoami = await tfrpc.rpc.getActiveIdentity(); let whoami = await tfrpc.rpc.getActiveIdentity();
let ids = (await tfrpc.rpc.getIdentities()) || []; let ids = (await tfrpc.rpc.getIdentities()) || [];
this.is_administrator = await tfrpc.rpc.isAdministrator();
this.stay_connected =
this.is_administrator &&
(await tfrpc.rpc.globalSettingsGet('stay_connected'));
this.url = await tfrpc.rpc.url(); this.url = await tfrpc.rpc.url();
this.whoami = whoami ?? (ids.length ? ids[0] : undefined); this.whoami = whoami ?? (ids.length ? ids[0] : undefined);
this.guest = !this.whoami?.length; this.guest = !this.whoami?.length;
@ -131,8 +137,8 @@ class TfElement extends LitElement {
let channel_names = [ let channel_names = [
'', '',
'@', '@',
'🔐',
'👍', '👍',
'🔐',
...this.channels.map((x) => '#' + x), ...this.channels.map((x) => '#' + x),
]; ];
let index = channel_names.indexOf(this.hash.substring(1)); let index = channel_names.indexOf(this.hash.substring(1));
@ -354,7 +360,7 @@ class TfElement extends LitElement {
let start = new Date(); let start = new Date();
let result = await tfrpc.rpc.query(sql, args); let result = await tfrpc.rpc.query(sql, args);
let end = new Date(); let end = new Date();
console.log((end - start) / 1000, sql); console.log((end - start) / 1000, sql.replaceAll(/\s+/g, ' ').trim());
return result; return result;
} }
@ -416,16 +422,6 @@ class TfElement extends LitElement {
`, `,
k_args k_args
), ),
this.query_timed(
`
SELECT '👍' AS channel, MAX(messages.rowid) AS rowid FROM messages
JOIN json_each(?2) AS following ON messages.author = following.value
WHERE
messages.content ->> 'type' = 'vote' AND
messages.author != ?4
`,
k_args
),
]) ])
).flat(); ).flat();
let latest = {}; let latest = {};
@ -605,9 +601,13 @@ class TfElement extends LitElement {
.channels_latest=${this.channels_latest} .channels_latest=${this.channels_latest}
.channels_unread=${this.channels_unread} .channels_unread=${this.channels_unread}
@channelsetunread=${this.channel_set_unread} @channelsetunread=${this.channel_set_unread}
@refresh=${this.refresh}
@toggle_stay_connected=${this.toggle_stay_connected}
.connections=${this.connections} .connections=${this.connections}
.private_messages=${this.private_messages} .private_messages=${this.private_messages}
.recent_reactions=${this.recent_reactions} .recent_reactions=${this.recent_reactions}
?is_administrator=${this.is_administrator}
?stay_connected=${this.stay_connected}
></tf-tab-news> ></tf-tab-news>
`; `;
} else if (this.tab === 'connections') { } else if (this.tab === 'connections') {
@ -658,6 +658,18 @@ class TfElement extends LitElement {
tfrpc.rpc.sync(); tfrpc.rpc.sync();
} }
async toggle_stay_connected() {
let stay_connected = await tfrpc.rpc.globalSettingsGet('stay_connected');
let new_stay_connected = !this.stay_connected;
try {
if (new_stay_connected != stay_connected) {
await tfrpc.rpc.globalSettingsSet('stay_connected', new_stay_connected);
}
} finally {
this.stay_connected = await tfrpc.rpc.globalSettingsGet('stay_connected');
}
}
render() { render() {
let self = this; let self = this;
@ -680,14 +692,26 @@ class TfElement extends LitElement {
class="w3-bar w3-theme-l1" class="w3-bar w3-theme-l1"
style="position: static; top: 0; z-index: 10" style="position: static; top: 0; z-index: 10"
> >
<button ${this.is_administrator
class=${'w3-bar-item w3-button w3-circle w3-ripple' + ? html`
(this.connections?.some((x) => x.flags.one_shot) ? ' w3-spin' : '')} <button
style="width: 1.5em; height: 1.5em; padding: 8px" class=${'w3-bar-item w3-button w3-circle w3-ripple' +
@click=${this.refresh} (this.connections?.some((x) => x.flags.one_shot)
> ? ' w3-spin'
: '')}
</button> style="width: 1.5em; height: 1.5em; padding: 8px"
@click=${this.refresh}
>
</button>
<button
class="w3-bar-item w3-button w3-ripple"
@click=${this.toggle_stay_connected}
>
${this.stay_connected ? '🔗' : '⛓️‍💥'}
</button>
`
: undefined}
${Object.entries(k_tabs).map( ${Object.entries(k_tabs).map(
([k, v]) => html` ([k, v]) => html`
<button <button

@ -581,7 +581,7 @@ class TfComposeElement extends LitElement {
class="w3-button w3-bar-item w3-theme-d1" class="w3-button w3-bar-item w3-theme-d1"
@click=${() => this.set_encrypt([])} @click=${() => this.set_encrypt([])}
> >
🔐 🔐 Encrypt
</button>`; </button>`;
let result = html` let result = html`
<style> <style>
@ -602,7 +602,7 @@ class TfComposeElement extends LitElement {
: undefined} : undefined}
${this.render_encrypt()} ${this.render_encrypt()}
</header> </header>
<div class="w3-container w3-padding-small"> <div class="w3-container" style="padding: 0 0 16px 0">
<div class="w3-half"> <div class="w3-half">
<span <span
class="w3-input w3-theme-d1 w3-border" class="w3-input w3-theme-d1 w3-border"
@ -623,7 +623,7 @@ class TfComposeElement extends LitElement {
${Object.values(draft.mentions || {}).map((x) => ${Object.values(draft.mentions || {}).map((x) =>
self.render_mention(x) self.render_mention(x)
)} )}
<footer class="w3-container"> <footer>
${this.render_attach_app()} ${this.render_content_warning()} ${this.render_attach_app()} ${this.render_content_warning()}
${this.render_new_thread()} ${this.render_new_thread()}
<button <button

@ -686,7 +686,11 @@ class TfMessageElement extends LitElement {
${x.action} ${x.action}
${x.users.map( ${x.users.map(
(y) => html` (y) => html`
<tf-user id=${y} .users=${this.users}></tf-user> <tf-user
id=${y}
.users=${this.users}
icon_only="true"
></tf-user>
` `
)} )}
</div> </div>

@ -233,7 +233,19 @@ class TfNewsElement extends LitElement {
<div <div
style="border-bottom: 1px solid #f00; flex: 1; align-self: center; height: 1px" style="border-bottom: 1px solid #f00; flex: 1; align-self: center; height: 1px"
></div> ></div>
<div style="color: #f00; padding: 8px">unread</div> <button
style="color: #f00; padding: 8px"
class="w3-button"
@click=${() =>
this.dispatchEvent(
new Event('mark_all_read', {
bubbles: true,
composed: true,
})
)}
>
unread
</button>
<div <div
style="border-bottom: 1px solid #f00; flex: 1; align-self: center; height: 1px" style="border-bottom: 1px solid #f00; flex: 1; align-self: center; height: 1px"
></div> ></div>

@ -174,13 +174,13 @@ class TfTabNewsFeedElement extends LitElement {
SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
FROM messages FROM messages
JOIN json_each(?) AS following ON messages.author = following.value JOIN json_each(?) AS following ON messages.author = following.value
WHERE messages.content ->> 'channel' = ?4 WHERE messages.content ->> 'channel' = ?4 AND messages.content ->> 'type' != 'vote'
UNION UNION
SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
FROM messages_refs FROM messages_refs
JOIN messages ON messages.id = messages_refs.message JOIN messages ON messages.id = messages_refs.message
JOIN json_each(?1) AS following ON messages.author = following.value JOIN json_each(?1) AS following ON messages.author = following.value
WHERE messages_refs.ref = '#' || ?4 WHERE messages_refs.ref = '#' || ?4 AND messages.content ->> 'type' != 'vote'
) )
SELECT TRUE AS is_primary, all_news.* FROM all_news SELECT TRUE AS is_primary, all_news.* FROM all_news
WHERE (?2 IS NULL OR all_news.timestamp >= ?2) AND all_news.timestamp < ?3 WHERE (?2 IS NULL OR all_news.timestamp >= ?2) AND all_news.timestamp < ?3
@ -235,18 +235,12 @@ class TfTabNewsFeedElement extends LitElement {
let t0 = new Date(); let t0 = new Date();
let initial_messages = await tfrpc.rpc.query( let initial_messages = await tfrpc.rpc.query(
` `
WITH SELECT TRUE AS is_primary, messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
all_news AS ( FROM messages
SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature JOIN json_each(?) AS following ON messages.author = following.value
FROM messages WHERE messages.timestamp < ?3 AND (?2 IS NULL OR messages.timestamp >= ?2) AND
JOIN json_each(?) AS following ON messages.author = following.value messages.content ->> 'type' != 'vote'
), ORDER BY timestamp DESC LIMIT 20
news AS (
SELECT * FROM all_news
WHERE all_news.timestamp < ?3 AND (?2 IS NULL OR all_news.timestamp >= ?2)
ORDER BY timestamp DESC LIMIT 20
)
SELECT TRUE AS is_primary, news.* FROM news
`, `,
[JSON.stringify(this.following), start_time, end_time] [JSON.stringify(this.following), start_time, end_time]
); );
@ -492,6 +486,7 @@ class TfTabNewsFeedElement extends LitElement {
channel=${this.channel()} channel=${this.channel()}
channel_unread=${this.channels_unread?.[this.channel()]} channel_unread=${this.channels_unread?.[this.channel()]}
.recent_reactions=${this.recent_reactions} .recent_reactions=${this.recent_reactions}
@mark_all_read=${this.mark_all_read}
></tf-news> ></tf-news>
${more} ${more}
`); `);

@ -26,6 +26,8 @@ class TfTabNewsElement extends LitElement {
private_messages: {type: Array}, private_messages: {type: Array},
recent_reactions: {type: Array}, recent_reactions: {type: Array},
peer_exchange: {type: Boolean}, peer_exchange: {type: Boolean},
is_administrator: {type: Boolean},
stay_connected: {type: Boolean},
}; };
} }
@ -174,10 +176,6 @@ class TfTabNewsElement extends LitElement {
.map((x) => x[0]); .map((x) => x[0]);
} }
refresh() {
tfrpc.rpc.sync();
}
async enable_peer_exchange() { async enable_peer_exchange() {
await tfrpc.rpc.globalSettingsSet('peer_exchange', true); await tfrpc.rpc.globalSettingsSet('peer_exchange', true);
await this.check_peer_exchange(); await this.check_peer_exchange();
@ -196,6 +194,32 @@ class TfTabNewsElement extends LitElement {
> >
&times; &times;
</div> </div>
${this.is_administrator
? html`
<button
class="w3-bar-item w3-button"
@click=${() =>
this.dispatchEvent(
new Event('refresh', {bubbles: true, composed: true})
)}
>
<span style="width: 1.5em; height: 1.5em; padding: 8px">↻</span>
Sync now
</button>
<button
class="w3-bar-item w3-button w3-ripple"
@click=${() =>
this.dispatchEvent(
new Event('toggle_stay_connected', {
bubbles: true,
composed: true,
})
)}
>
${this.stay_connected ? '🔗 Online mode' : '⛓️‍💥 Passive mode'}
</button>
`
: undefined}
${this.hash.startsWith('##') && ${this.hash.startsWith('##') &&
this.channels.indexOf(this.hash.substring(2)) == -1 this.channels.indexOf(this.hash.substring(2)) == -1
? html` ? html`
@ -266,7 +290,10 @@ class TfTabNewsElement extends LitElement {
(this.connections?.some((x) => x.flags.one_shot) (this.connections?.some((x) => x.flags.one_shot)
? ' w3-spin' ? ' w3-spin'
: '')} : '')}
@click=${this.refresh} @click=${() =>
this.dispatchEvent(
new Event('refresh', {bubbles: true, composed: true})
)}
> >
↻ Sync now ↻ Sync now
</button> </button>

@ -7,6 +7,7 @@ class TfUserElement extends LitElement {
return { return {
id: {type: String}, id: {type: String},
fallback_name: {type: String}, fallback_name: {type: String},
icon_only: {type: Boolean},
users: {type: Object}, users: {type: Object},
}; };
} }
@ -17,6 +18,7 @@ class TfUserElement extends LitElement {
super(); super();
this.id = null; this.id = null;
this.fallback_name = null; this.fallback_name = null;
this.icon_only = false;
this.users = {}; this.users = {};
} }
@ -32,9 +34,10 @@ class TfUserElement extends LitElement {
>😎</span >😎</span
>`; >`;
let name = this.users?.[this.id]?.name; let name = this.users?.[this.id]?.name;
name = html`<a target="_top" href=${'#' + this.id} let name_string = name ?? this.fallback_name ?? this.id;
>${name ?? this.fallback_name ?? this.id}</a name = this.icon_only
>`; ? undefined
: html`<a target="_top" href=${'#' + this.id}>${name_string}</a>`;
if (user) { if (user) {
let image_link = user.image; let image_link = user.image;
@ -48,6 +51,7 @@ class TfUserElement extends LitElement {
class=${'w3-theme-l4 ' + shape} class=${'w3-theme-l4 ' + shape}
style="width: 2em; height: 2em; vertical-align: middle; object-fit: cover" style="width: 2em; height: 2em; vertical-align: middle; object-fit: cover"
src="/${image_link}/view" src="/${image_link}/view"
title=${name_string + ' (' + this.id + ')'}
/>`; />`;
} }
} }

@ -50,9 +50,9 @@ function image(node, entering) {
'</div>' '</div>'
); );
if (this.options.safe && potentiallyUnsafe(node.destination)) { if (this.options.safe && potentiallyUnsafe(node.destination)) {
this.lit('<img src="" alt="'); this.lit('<img src="" title="');
} else { } else {
this.lit('<img src="' + this.esc(node.destination) + '" alt="'); this.lit('<img src="' + this.esc(node.destination) + '" title="');
} }
} }
this.disableTags += 1; this.disableTags += 1;

@ -1,5 +1,5 @@
{ {
"type": "tildefriends-app", "type": "tildefriends-app",
"emoji": "👋", "emoji": "👋",
"previous": "&fY3YUKPuH/wqOgKPVNJu1vWEHCXf5fToL2qiVXMRmxc=.sha256" "previous": "&3puDxDNnf6C+YXpFysYLgxFMAy54/AO9V7Xpja6qO/k=.sha256"
} }

@ -76,7 +76,8 @@
<h2>First-time user checklist:</h2> <h2>First-time user checklist:</h2>
<ol type="1" style="text-align: left"> <ol type="1" style="text-align: left">
<li> <li>
<a href="https://dev.tildefriends.net/cory/tildefriends/releases" <a
href="https://dev.tildefriends.net/cory/tildefriends/releases/latest"
>Download</a >Download</a
> >
Tilde Friends or use Tilde Friends or use
@ -84,7 +85,7 @@
>https://www.tildefriends.net/</a >https://www.tildefriends.net/</a
>. >.
<div class="w3-cell-row"> <div class="w3-cell-row">
<div class="w3-container w3-cell"> <div class="w3-container w3-cell w3-mobile">
<h3>Mobile</h3> <h3>Mobile</h3>
<p> <p>
<a <a
@ -113,7 +114,7 @@
</p> </p>
<p>Just launch the app.</p> <p>Just launch the app.</p>
</div> </div>
<div class="w3-container w3-cell"> <div class="w3-container w3-cell w3-mobile">
<h3>Web</h3> <h3>Web</h3>
<p> <p>
<a <a
@ -128,8 +129,19 @@
> >
to take it for a spin right away. to take it for a spin right away.
</p> </p>
<h3>PeachCloud</h3>
<p>
Tilde Friends is also a part of 🍑☁️<a
href="https://peach-docs.commoninternet.net/"
>PeachCloud</a
>, which is available on
<a href="https://apps.yunohost.org/app/peachpub"
>YunoHost</a
>
for accessible self-hosting.
</p>
</div> </div>
<div class="w3-container w3-cell"> <div class="w3-container w3-cell w3-mobile">
<h3>Desktop</h3> <h3>Desktop</h3>
<p> <p>
<a <a

@ -25,14 +25,14 @@
}: }:
pkgs.stdenv.mkDerivation rec { pkgs.stdenv.mkDerivation rec {
pname = "tildefriends"; pname = "tildefriends";
version = "0.0.31"; version = "0.0.32";
src = pkgs.fetchFromGitea { src = pkgs.fetchFromGitea {
domain = "dev.tildefriends.net"; domain = "dev.tildefriends.net";
owner = "cory"; owner = "cory";
repo = "tildefriends"; repo = "tildefriends";
rev = "v${version}"; rev = "v${version}";
hash = "sha256-c2ZKVNikI5jN5GQuvp7S53qqnRZniSrJMF1FUZdVNPI="; hash = "sha256-Dk0NOEQIg2LeENySK0+MgpZEtfsClGq6dZL+eOOpE0U=";
fetchSubmodules = true; fetchSubmodules = true;
}; };

File diff suppressed because one or more lines are too long

178
deps/codemirror_src/package-lock.json generated vendored

@ -92,9 +92,9 @@
} }
}, },
"node_modules/@codemirror/language": { "node_modules/@codemirror/language": {
"version": "6.11.1", "version": "6.11.2",
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.1.tgz", "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.2.tgz",
"integrity": "sha512-5kS1U7emOGV84vxC+ruBty5sUgcD0te6dyupyRVG2zaSjhTDM73LhVKUtVwiqSe6QwmEoA4SCiU8AKPFyumAWQ==", "integrity": "sha512-p44TsNArL4IVXDTbapUmEkAlvWs2CFQbcfc0ymDsis1kH2wh0gcY96AS29c/vp2d0y2Tquk1EDSaawpzilUiAw==",
"dependencies": { "dependencies": {
"@codemirror/state": "^6.0.0", "@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.23.0", "@codemirror/view": "^6.23.0",
@ -144,9 +144,9 @@
} }
}, },
"node_modules/@codemirror/view": { "node_modules/@codemirror/view": {
"version": "6.37.2", "version": "6.38.0",
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.37.2.tgz", "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.38.0.tgz",
"integrity": "sha512-XD3LdgQpxQs5jhOOZ2HRVT+Rj59O4Suc7g2ULvZ+Yi8eCkickrkZ5JFuoDhs2ST1mNI5zSsNYgR3NGa4OUrbnw==", "integrity": "sha512-yvSchUwHOdupXkd7xJ0ob36jdsSR/I+/C+VbY0ffBiL5NiSTEBDfB1ZGWbbIlDd5xgdUkody+lukAdOxYrOBeg==",
"dependencies": { "dependencies": {
"@codemirror/state": "^6.5.0", "@codemirror/state": "^6.5.0",
"crelt": "^1.0.6", "crelt": "^1.0.6",
@ -345,9 +345,9 @@
} }
}, },
"node_modules/@rollup/rollup-android-arm-eabi": { "node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.44.0", "version": "4.44.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.44.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.44.1.tgz",
"integrity": "sha512-xEiEE5oDW6tK4jXCAyliuntGR+amEMO7HLtdSshVuhFnKTYoeYMyXQK7pLouAJJj5KHdwdn87bfHAR2nSdNAUA==", "integrity": "sha512-JAcBr1+fgqx20m7Fwe1DxPUl/hPkee6jA6Pl7n1v2EFiktAHenTaXl5aIFjUIEsfn9w3HE4gK1lEgNGMzBDs1w==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -357,9 +357,9 @@
] ]
}, },
"node_modules/@rollup/rollup-android-arm64": { "node_modules/@rollup/rollup-android-arm64": {
"version": "4.44.0", "version": "4.44.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.44.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.44.1.tgz",
"integrity": "sha512-uNSk/TgvMbskcHxXYHzqwiyBlJ/lGcv8DaUfcnNwict8ba9GTTNxfn3/FAoFZYgkaXXAdrAA+SLyKplyi349Jw==", "integrity": "sha512-RurZetXqTu4p+G0ChbnkwBuAtwAbIwJkycw1n6GvlGlBuS4u5qlr5opix8cBAYFJgaY05TWtM+LaoFggUmbZEQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -369,9 +369,9 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-arm64": { "node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.44.0", "version": "4.44.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.44.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.44.1.tgz",
"integrity": "sha512-VGF3wy0Eq1gcEIkSCr8Ke03CWT+Pm2yveKLaDvq51pPpZza3JX/ClxXOCmTYYq3us5MvEuNRTaeyFThCKRQhOA==", "integrity": "sha512-fM/xPesi7g2M7chk37LOnmnSTHLG/v2ggWqKj3CCA1rMA4mm5KVBT1fNoswbo1JhPuNNZrVwpTvlCVggv8A2zg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -381,9 +381,9 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-x64": { "node_modules/@rollup/rollup-darwin-x64": {
"version": "4.44.0", "version": "4.44.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.44.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.44.1.tgz",
"integrity": "sha512-fBkyrDhwquRvrTxSGH/qqt3/T0w5Rg0L7ZIDypvBPc1/gzjJle6acCpZ36blwuwcKD/u6oCE/sRWlUAcxLWQbQ==", "integrity": "sha512-gDnWk57urJrkrHQ2WVx9TSVTH7lSlU7E3AFqiko+bgjlh78aJ88/3nycMax52VIVjIm3ObXnDL2H00e/xzoipw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -393,9 +393,9 @@
] ]
}, },
"node_modules/@rollup/rollup-freebsd-arm64": { "node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.44.0", "version": "4.44.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.44.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.44.1.tgz",
"integrity": "sha512-u5AZzdQJYJXByB8giQ+r4VyfZP+walV+xHWdaFx/1VxsOn6eWJhK2Vl2eElvDJFKQBo/hcYIBg/jaKS8ZmKeNQ==", "integrity": "sha512-wnFQmJ/zPThM5zEGcnDcCJeYJgtSLjh1d//WuHzhf6zT3Md1BvvhJnWoy+HECKu2bMxaIcfWiu3bJgx6z4g2XA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -405,9 +405,9 @@
] ]
}, },
"node_modules/@rollup/rollup-freebsd-x64": { "node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.44.0", "version": "4.44.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.44.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.44.1.tgz",
"integrity": "sha512-qC0kS48c/s3EtdArkimctY7h3nHicQeEUdjJzYVJYR3ct3kWSafmn6jkNCA8InbUdge6PVx6keqjk5lVGJf99g==", "integrity": "sha512-uBmIxoJ4493YATvU2c0upGz87f99e3wop7TJgOA/bXMFd2SvKCI7xkxY/5k50bv7J6dw1SXT4MQBQSLn8Bb/Uw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -417,9 +417,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm-gnueabihf": { "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.44.0", "version": "4.44.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.44.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.44.1.tgz",
"integrity": "sha512-x+e/Z9H0RAWckn4V2OZZl6EmV0L2diuX3QB0uM1r6BvhUIv6xBPL5mrAX2E3e8N8rEHVPwFfz/ETUbV4oW9+lQ==", "integrity": "sha512-n0edDmSHlXFhrlmTK7XBuwKlG5MbS7yleS1cQ9nn4kIeW+dJH+ExqNgQ0RrFRew8Y+0V/x6C5IjsHrJmiHtkxQ==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -429,9 +429,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm-musleabihf": { "node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.44.0", "version": "4.44.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.44.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.44.1.tgz",
"integrity": "sha512-1exwiBFf4PU/8HvI8s80icyCcnAIB86MCBdst51fwFmH5dyeoWVPVgmQPcKrMtBQ0W5pAs7jBCWuRXgEpRzSCg==", "integrity": "sha512-8WVUPy3FtAsKSpyk21kV52HCxB+me6YkbkFHATzC2Yd3yuqHwy2lbFL4alJOLXKljoRw08Zk8/xEj89cLQ/4Nw==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -441,9 +441,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-gnu": { "node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.44.0", "version": "4.44.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.44.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.44.1.tgz",
"integrity": "sha512-ZTR2mxBHb4tK4wGf9b8SYg0Y6KQPjGpR4UWwTFdnmjB4qRtoATZ5dWn3KsDwGa5Z2ZBOE7K52L36J9LueKBdOQ==", "integrity": "sha512-yuktAOaeOgorWDeFJggjuCkMGeITfqvPgkIXhDqsfKX8J3jGyxdDZgBV/2kj/2DyPaLiX6bPdjJDTu9RB8lUPQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -453,9 +453,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-musl": { "node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.44.0", "version": "4.44.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.44.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.44.1.tgz",
"integrity": "sha512-GFWfAhVhWGd4r6UxmnKRTBwP1qmModHtd5gkraeW2G490BpFOZkFtem8yuX2NyafIP/mGpRJgTJ2PwohQkUY/Q==", "integrity": "sha512-W+GBM4ifET1Plw8pdVaecwUgxmiH23CfAUj32u8knq0JPFyK4weRy6H7ooxYFD19YxBulL0Ktsflg5XS7+7u9g==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -465,9 +465,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-loongarch64-gnu": { "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
"version": "4.44.0", "version": "4.44.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.44.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.44.1.tgz",
"integrity": "sha512-xw+FTGcov/ejdusVOqKgMGW3c4+AgqrfvzWEVXcNP6zq2ue+lsYUgJ+5Rtn/OTJf7e2CbgTFvzLW2j0YAtj0Gg==", "integrity": "sha512-1zqnUEMWp9WrGVuVak6jWTl4fEtrVKfZY7CvcBmUUpxAJ7WcSowPSAWIKa/0o5mBL/Ij50SIf9tuirGx63Ovew==",
"cpu": [ "cpu": [
"loong64" "loong64"
], ],
@ -477,9 +477,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": { "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
"version": "4.44.0", "version": "4.44.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.44.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.44.1.tgz",
"integrity": "sha512-bKGibTr9IdF0zr21kMvkZT4K6NV+jjRnBoVMt2uNMG0BYWm3qOVmYnXKzx7UhwrviKnmK46IKMByMgvpdQlyJQ==", "integrity": "sha512-Rl3JKaRu0LHIx7ExBAAnf0JcOQetQffaw34T8vLlg9b1IhzcBgaIdnvEbbsZq9uZp3uAH+JkHd20Nwn0h9zPjA==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@ -489,9 +489,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-riscv64-gnu": { "node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.44.0", "version": "4.44.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.44.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.44.1.tgz",
"integrity": "sha512-vV3cL48U5kDaKZtXrti12YRa7TyxgKAIDoYdqSIOMOFBXqFj2XbChHAtXquEn2+n78ciFgr4KIqEbydEGPxXgA==", "integrity": "sha512-j5akelU3snyL6K3N/iX7otLBIl347fGwmd95U5gS/7z6T4ftK288jKq3A5lcFKcx7wwzb5rgNvAg3ZbV4BqUSw==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@ -501,9 +501,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-riscv64-musl": { "node_modules/@rollup/rollup-linux-riscv64-musl": {
"version": "4.44.0", "version": "4.44.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.44.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.44.1.tgz",
"integrity": "sha512-TDKO8KlHJuvTEdfw5YYFBjhFts2TR0VpZsnLLSYmB7AaohJhM8ctDSdDnUGq77hUh4m/djRafw+9zQpkOanE2Q==", "integrity": "sha512-ppn5llVGgrZw7yxbIm8TTvtj1EoPgYUAbfw0uDjIOzzoqlZlZrLJ/KuiE7uf5EpTpCTrNt1EdtzF0naMm0wGYg==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@ -513,9 +513,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-s390x-gnu": { "node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.44.0", "version": "4.44.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.44.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.44.1.tgz",
"integrity": "sha512-8541GEyktXaw4lvnGp9m84KENcxInhAt6vPWJ9RodsB/iGjHoMB2Pp5MVBCiKIRxrxzJhGCxmNzdu+oDQ7kwRA==", "integrity": "sha512-Hu6hEdix0oxtUma99jSP7xbvjkUM/ycke/AQQ4EC5g7jNRLLIwjcNwaUy95ZKBJJwg1ZowsclNnjYqzN4zwkAw==",
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
@ -525,9 +525,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-gnu": { "node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.44.0", "version": "4.44.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.44.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.44.1.tgz",
"integrity": "sha512-iUVJc3c0o8l9Sa/qlDL2Z9UP92UZZW1+EmQ4xfjTc1akr0iUFZNfxrXJ/R1T90h/ILm9iXEY6+iPrmYB3pXKjw==", "integrity": "sha512-EtnsrmZGomz9WxK1bR5079zee3+7a+AdFlghyd6VbAjgRJDbTANJ9dcPIPAi76uG05micpEL+gPGmAKYTschQw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -537,9 +537,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-musl": { "node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.44.0", "version": "4.44.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.44.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.44.1.tgz",
"integrity": "sha512-PQUobbhLTQT5yz/SPg116VJBgz+XOtXt8D1ck+sfJJhuEsMj2jSej5yTdp8CvWBSceu+WW+ibVL6dm0ptG5fcA==", "integrity": "sha512-iAS4p+J1az6Usn0f8xhgL4PaU878KEtutP4hqw52I4IO6AGoyOkHCxcc4bqufv1tQLdDWFx8lR9YlwxKuv3/3g==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -549,9 +549,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-arm64-msvc": { "node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.44.0", "version": "4.44.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.44.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.44.1.tgz",
"integrity": "sha512-M0CpcHf8TWn+4oTxJfh7LQuTuaYeXGbk0eageVjQCKzYLsajWS/lFC94qlRqOlyC2KvRT90ZrfXULYmukeIy7w==", "integrity": "sha512-NtSJVKcXwcqozOl+FwI41OH3OApDyLk3kqTJgx8+gp6On9ZEt5mYhIsKNPGuaZr3p9T6NWPKGU/03Vw4CNU9qg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -561,9 +561,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-ia32-msvc": { "node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.44.0", "version": "4.44.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.44.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.44.1.tgz",
"integrity": "sha512-3XJ0NQtMAXTWFW8FqZKcw3gOQwBtVWP/u8TpHP3CRPXD7Pd6s8lLdH3sHWh8vqKCyyiI8xW5ltJScQmBU9j7WA==", "integrity": "sha512-JYA3qvCOLXSsnTR3oiyGws1Dm0YTuxAAeaYGVlGpUsHqloPcFjPg+X0Fj2qODGLNwQOAcCiQmHub/V007kiH5A==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@ -573,9 +573,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-x64-msvc": { "node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.44.0", "version": "4.44.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.44.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.44.1.tgz",
"integrity": "sha512-Q2Mgwt+D8hd5FIPUuPDsvPR7Bguza6yTkJxspDGkZj7tBRn2y4KSWYuIXpftFSjBra76TbKerCV7rgFPQrn+wQ==", "integrity": "sha512-J8o22LuF0kTe7m+8PvW9wk3/bRq5+mRo5Dqo6+vXb7otCm3TPhYOJqOaQtGU9YMWQSL3krMnoOxMr0+9E6F3Ug==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -746,9 +746,9 @@
} }
}, },
"node_modules/rollup": { "node_modules/rollup": {
"version": "4.44.0", "version": "4.44.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.44.0.tgz", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.44.1.tgz",
"integrity": "sha512-qHcdEzLCiktQIfwBq420pn2dP+30uzqYxv9ETm91wdt2R9AFcWfjNAmje4NWlnCIQ5RMTzVf0ZyisOKqHR6RwA==", "integrity": "sha512-x8H8aPvD+xbl0Do8oez5f5o8eMS3trfCghc4HhLAnCkj7Vl0d1JWGs0UF/D886zLW2rOj2QymV/JcSSsw+XDNg==",
"dependencies": { "dependencies": {
"@types/estree": "1.0.8" "@types/estree": "1.0.8"
}, },
@ -760,26 +760,26 @@
"npm": ">=8.0.0" "npm": ">=8.0.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.44.0", "@rollup/rollup-android-arm-eabi": "4.44.1",
"@rollup/rollup-android-arm64": "4.44.0", "@rollup/rollup-android-arm64": "4.44.1",
"@rollup/rollup-darwin-arm64": "4.44.0", "@rollup/rollup-darwin-arm64": "4.44.1",
"@rollup/rollup-darwin-x64": "4.44.0", "@rollup/rollup-darwin-x64": "4.44.1",
"@rollup/rollup-freebsd-arm64": "4.44.0", "@rollup/rollup-freebsd-arm64": "4.44.1",
"@rollup/rollup-freebsd-x64": "4.44.0", "@rollup/rollup-freebsd-x64": "4.44.1",
"@rollup/rollup-linux-arm-gnueabihf": "4.44.0", "@rollup/rollup-linux-arm-gnueabihf": "4.44.1",
"@rollup/rollup-linux-arm-musleabihf": "4.44.0", "@rollup/rollup-linux-arm-musleabihf": "4.44.1",
"@rollup/rollup-linux-arm64-gnu": "4.44.0", "@rollup/rollup-linux-arm64-gnu": "4.44.1",
"@rollup/rollup-linux-arm64-musl": "4.44.0", "@rollup/rollup-linux-arm64-musl": "4.44.1",
"@rollup/rollup-linux-loongarch64-gnu": "4.44.0", "@rollup/rollup-linux-loongarch64-gnu": "4.44.1",
"@rollup/rollup-linux-powerpc64le-gnu": "4.44.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.44.1",
"@rollup/rollup-linux-riscv64-gnu": "4.44.0", "@rollup/rollup-linux-riscv64-gnu": "4.44.1",
"@rollup/rollup-linux-riscv64-musl": "4.44.0", "@rollup/rollup-linux-riscv64-musl": "4.44.1",
"@rollup/rollup-linux-s390x-gnu": "4.44.0", "@rollup/rollup-linux-s390x-gnu": "4.44.1",
"@rollup/rollup-linux-x64-gnu": "4.44.0", "@rollup/rollup-linux-x64-gnu": "4.44.1",
"@rollup/rollup-linux-x64-musl": "4.44.0", "@rollup/rollup-linux-x64-musl": "4.44.1",
"@rollup/rollup-win32-arm64-msvc": "4.44.0", "@rollup/rollup-win32-arm64-msvc": "4.44.1",
"@rollup/rollup-win32-ia32-msvc": "4.44.0", "@rollup/rollup-win32-ia32-msvc": "4.44.1",
"@rollup/rollup-win32-x64-msvc": "4.44.0", "@rollup/rollup-win32-x64-msvc": "4.44.1",
"fsevents": "~2.3.2" "fsevents": "~2.3.2"
} }
}, },

15
deps/sqlite/shell.c vendored

@ -8027,13 +8027,14 @@ SQLITE_EXTENSION_INIT1
# include <dirent.h> # include <dirent.h>
# include <utime.h> # include <utime.h>
# include <sys/time.h> # include <sys/time.h>
# define STRUCT_STAT struct stat
#else #else
# include "windows.h" # include "windows.h"
# include <io.h> # include <io.h>
# include <direct.h> # include <direct.h>
/* # include "test_windirent.h" */ /* # include "test_windirent.h" */
# define dirent DIRENT # define dirent DIRENT
# define stat _stat # define STRUCT_STAT struct _stat
# define chmod(path,mode) fileio_chmod(path,mode) # define chmod(path,mode) fileio_chmod(path,mode)
# define mkdir(path,mode) fileio_mkdir(path) # define mkdir(path,mode) fileio_mkdir(path)
#endif #endif
@ -8224,7 +8225,7 @@ LPWSTR utf8_to_utf16(const char *z){
*/ */
static void statTimesToUtc( static void statTimesToUtc(
const char *zPath, const char *zPath,
struct stat *pStatBuf STRUCT_STAT *pStatBuf
){ ){
HANDLE hFindFile; HANDLE hFindFile;
WIN32_FIND_DATAW fd; WIN32_FIND_DATAW fd;
@ -8252,7 +8253,7 @@ static void statTimesToUtc(
*/ */
static int fileStat( static int fileStat(
const char *zPath, const char *zPath,
struct stat *pStatBuf STRUCT_STAT *pStatBuf
){ ){
#if defined(_WIN32) #if defined(_WIN32)
sqlite3_int64 sz = strlen(zPath); sqlite3_int64 sz = strlen(zPath);
@ -8276,7 +8277,7 @@ static int fileStat(
*/ */
static int fileLinkStat( static int fileLinkStat(
const char *zPath, const char *zPath,
struct stat *pStatBuf STRUCT_STAT *pStatBuf
){ ){
#if defined(_WIN32) #if defined(_WIN32)
return fileStat(zPath, pStatBuf); return fileStat(zPath, pStatBuf);
@ -8309,7 +8310,7 @@ static int makeDirectory(
int i = 1; int i = 1;
while( rc==SQLITE_OK ){ while( rc==SQLITE_OK ){
struct stat sStat; STRUCT_STAT sStat;
int rc2; int rc2;
for(; zCopy[i]!='/' && i<nCopy; i++); for(; zCopy[i]!='/' && i<nCopy; i++);
@ -8359,7 +8360,7 @@ static int writeFile(
** be an error though - if there is already a directory at the same ** be an error though - if there is already a directory at the same
** path and either the permissions already match or can be changed ** path and either the permissions already match or can be changed
** to do so using chmod(), it is not an error. */ ** to do so using chmod(), it is not an error. */
struct stat sStat; STRUCT_STAT sStat;
if( errno!=EEXIST if( errno!=EEXIST
|| 0!=fileStat(zFile, &sStat) || 0!=fileStat(zFile, &sStat)
|| !S_ISDIR(sStat.st_mode) || !S_ISDIR(sStat.st_mode)
@ -8561,7 +8562,7 @@ struct fsdir_cursor {
const char *zBase; const char *zBase;
int nBase; int nBase;
struct stat sStat; /* Current lstat() results */ STRUCT_STAT sStat; /* Current lstat() results */
char *zPath; /* Path to current entry */ char *zPath; /* Path to current entry */
sqlite3_int64 iRowid; /* Current rowid */ sqlite3_int64 iRowid; /* Current rowid */
}; };

199
deps/sqlite/sqlite3.c vendored

@ -1,6 +1,6 @@
/****************************************************************************** /******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite ** This file is an amalgamation of many separate C source files from SQLite
** version 3.50.1. By combining all the individual C code files into this ** version 3.50.2. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a single translation ** 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 ** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements ** possible if the files were compiled separately. Performance improvements
@ -18,7 +18,7 @@
** separate file. This file contains only code for the core SQLite library. ** separate file. This file contains only code for the core SQLite library.
** **
** The content in this amalgamation comes from Fossil check-in ** The content in this amalgamation comes from Fossil check-in
** b77dc5e0f596d2140d9ac682b2893ff65d3a with changes in files: ** 2af157d77fb1304a74176eaee7fbc7c7e932 with changes in files:
** **
** **
*/ */
@ -465,9 +465,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()]. ** [sqlite_version()] and [sqlite_source_id()].
*/ */
#define SQLITE_VERSION "3.50.1" #define SQLITE_VERSION "3.50.2"
#define SQLITE_VERSION_NUMBER 3050001 #define SQLITE_VERSION_NUMBER 3050002
#define SQLITE_SOURCE_ID "2025-06-06 14:52:32 b77dc5e0f596d2140d9ac682b2893ff65d3a4140aa86067a3efebe29dc914c95" #define SQLITE_SOURCE_ID "2025-06-28 14:00:48 2af157d77fb1304a74176eaee7fbc7c7e932d946bf25325e9c26c91db19e3079"
/* /*
** CAPI3REF: Run-Time Library Version Numbers ** CAPI3REF: Run-Time Library Version Numbers
@ -4398,7 +4398,7 @@ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*);
** **
** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of
** database filename D with corresponding journal file J and WAL file W and ** database filename D with corresponding journal file J and WAL file W and
** with N URI parameters key/values pairs in the array P. The result from ** an array P of N URI Key/Value pairs. The result from
** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that ** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that
** is safe to pass to routines like: ** is safe to pass to routines like:
** <ul> ** <ul>
@ -5079,7 +5079,7 @@ typedef struct sqlite3_context sqlite3_context;
** METHOD: sqlite3_stmt ** METHOD: sqlite3_stmt
** **
** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, ** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants,
** literals may be replaced by a [parameter] that matches one of following ** literals may be replaced by a [parameter] that matches one of the following
** templates: ** templates:
** **
** <ul> ** <ul>
@ -5124,7 +5124,7 @@ typedef struct sqlite3_context sqlite3_context;
** **
** [[byte-order determination rules]] ^The byte-order of ** [[byte-order determination rules]] ^The byte-order of
** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF)
** found in first character, which is removed, or in the absence of a BOM ** found in the first character, which is removed, or in the absence of a BOM
** the byte order is the native byte order of the host ** the byte order is the native byte order of the host
** machine for sqlite3_bind_text16() or the byte order specified in ** machine for sqlite3_bind_text16() or the byte order specified in
** the 6th parameter for sqlite3_bind_text64().)^ ** the 6th parameter for sqlite3_bind_text64().)^
@ -5144,7 +5144,7 @@ typedef struct sqlite3_context sqlite3_context;
** or sqlite3_bind_text16() or sqlite3_bind_text64() then ** or sqlite3_bind_text16() or sqlite3_bind_text64() then
** that parameter must be the byte offset ** that parameter must be the byte offset
** where the NUL terminator would occur assuming the string were NUL ** where the NUL terminator would occur assuming the string were NUL
** terminated. If any NUL characters occurs at byte offsets less than ** terminated. If any NUL characters occur at byte offsets less than
** the value of the fourth parameter then the resulting string value will ** the value of the fourth parameter then the resulting string value will
** contain embedded NULs. The result of expressions involving strings ** contain embedded NULs. The result of expressions involving strings
** with embedded NULs is undefined. ** with embedded NULs is undefined.
@ -5356,7 +5356,7 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
** METHOD: sqlite3_stmt ** METHOD: sqlite3_stmt
** **
** ^These routines provide a means to determine the database, table, and ** ^These routines provide a means to determine the database, table, and
** table column that is the origin of a particular result column in ** table column that is the origin of a particular result column in a
** [SELECT] statement. ** [SELECT] statement.
** ^The name of the database or table or column can be returned as ** ^The name of the database or table or column can be returned as
** either a UTF-8 or UTF-16 string. ^The _database_ routines return ** either a UTF-8 or UTF-16 string. ^The _database_ routines return
@ -5925,8 +5925,8 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
** **
** For best security, the [SQLITE_DIRECTONLY] flag is recommended for ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for
** all application-defined SQL functions that do not need to be ** all application-defined SQL functions that do not need to be
** used inside of triggers, view, CHECK constraints, or other elements of ** used inside of triggers, views, CHECK constraints, or other elements of
** the database schema. This flags is especially recommended for SQL ** the database schema. This flag is especially recommended for SQL
** functions that have side effects or reveal internal application state. ** functions that have side effects or reveal internal application state.
** Without this flag, an attacker might be able to modify the schema of ** Without this flag, an attacker might be able to modify the schema of
** a database file to include invocations of the function with parameters ** a database file to include invocations of the function with parameters
@ -5957,7 +5957,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
** [user-defined window functions|available here]. ** [user-defined window functions|available here].
** **
** ^(If the final parameter to sqlite3_create_function_v2() or ** ^(If the final parameter to sqlite3_create_function_v2() or
** sqlite3_create_window_function() is not NULL, then it is destructor for ** sqlite3_create_window_function() is not NULL, then it is the destructor for
** the application data pointer. The destructor is invoked when the function ** the application data pointer. The destructor is invoked when the function
** is deleted, either by being overloaded or when the database connection ** is deleted, either by being overloaded or when the database connection
** closes.)^ ^The destructor is also invoked if the call to ** closes.)^ ^The destructor is also invoked if the call to
@ -6357,7 +6357,7 @@ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*);
** METHOD: sqlite3_value ** METHOD: sqlite3_value
** **
** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value] ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
** object D and returns a pointer to that copy. ^The [sqlite3_value] returned ** object V and returns a pointer to that copy. ^The [sqlite3_value] returned
** is a [protected sqlite3_value] object even if the input is not. ** is a [protected sqlite3_value] object even if the input is not.
** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
** memory allocation fails. ^If V is a [pointer value], then the result ** memory allocation fails. ^If V is a [pointer value], then the result
@ -6395,7 +6395,7 @@ SQLITE_API void sqlite3_value_free(sqlite3_value*);
** allocation error occurs. ** allocation error occurs.
** **
** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is ** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is
** determined by the N parameter on first successful call. Changing the ** determined by the N parameter on the first successful call. Changing the
** value of N in any subsequent call to sqlite3_aggregate_context() within ** value of N in any subsequent call to sqlite3_aggregate_context() within
** the same aggregate function instance will not resize the memory ** the same aggregate function instance will not resize the memory
** allocation.)^ Within the xFinal callback, it is customary to set ** allocation.)^ Within the xFinal callback, it is customary to set
@ -6557,7 +6557,7 @@ SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(voi
** **
** Security Warning: These interfaces should not be exposed in scripting ** Security Warning: These interfaces should not be exposed in scripting
** languages or in other circumstances where it might be possible for an ** languages or in other circumstances where it might be possible for an
** an attacker to invoke them. Any agent that can invoke these interfaces ** attacker to invoke them. Any agent that can invoke these interfaces
** can probably also take control of the process. ** can probably also take control of the process.
** **
** Database connection client data is only available for SQLite ** Database connection client data is only available for SQLite
@ -6671,7 +6671,7 @@ typedef void (*sqlite3_destructor_type)(void*);
** pointed to by the 2nd parameter are taken as the application-defined ** pointed to by the 2nd parameter are taken as the application-defined
** function result. If the 3rd parameter is non-negative, then it ** function result. If the 3rd parameter is non-negative, then it
** must be the byte offset into the string where the NUL terminator would ** must be the byte offset into the string where the NUL terminator would
** appear if the string where NUL terminated. If any NUL characters occur ** appear if the string were NUL terminated. If any NUL characters occur
** in the string at a byte offset that is less than the value of the 3rd ** in the string at a byte offset that is less than the value of the 3rd
** parameter, then the resulting string will contain embedded NULs and the ** parameter, then the resulting string will contain embedded NULs and the
** result of expressions operating on strings with embedded NULs is undefined. ** result of expressions operating on strings with embedded NULs is undefined.
@ -6729,7 +6729,7 @@ typedef void (*sqlite3_destructor_type)(void*);
** string and preferably a string literal. The sqlite3_result_pointer() ** string and preferably a string literal. The sqlite3_result_pointer()
** routine is part of the [pointer passing interface] added for SQLite 3.20.0. ** routine is part of the [pointer passing interface] added for SQLite 3.20.0.
** **
** If these routines are called from within the different thread ** If these routines are called from within a different thread
** than the one containing the application-defined function that received ** than the one containing the application-defined function that received
** the [sqlite3_context] pointer, the results are undefined. ** the [sqlite3_context] pointer, the results are undefined.
*/ */
@ -7135,7 +7135,7 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
** METHOD: sqlite3 ** METHOD: sqlite3
** **
** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name ** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name
** for the N-th database on database connection D, or a NULL pointer of N is ** for the N-th database on database connection D, or a NULL pointer if N is
** out of range. An N value of 0 means the main database file. An N of 1 is ** out of range. An N value of 0 means the main database file. An N of 1 is
** the "temp" schema. Larger values of N correspond to various ATTACH-ed ** the "temp" schema. Larger values of N correspond to various ATTACH-ed
** databases. ** databases.
@ -7230,7 +7230,7 @@ SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema);
** <dd>The SQLITE_TXN_READ state means that the database is currently ** <dd>The SQLITE_TXN_READ state means that the database is currently
** in a read transaction. Content has been read from the database file ** in a read transaction. Content has been read from the database file
** but nothing in the database file has changed. The transaction state ** but nothing in the database file has changed. The transaction state
** will advanced to SQLITE_TXN_WRITE if any changes occur and there are ** will be advanced to SQLITE_TXN_WRITE if any changes occur and there are
** no other conflicting concurrent write transactions. The transaction ** no other conflicting concurrent write transactions. The transaction
** state will revert to SQLITE_TXN_NONE following a [ROLLBACK] or ** state will revert to SQLITE_TXN_NONE following a [ROLLBACK] or
** [COMMIT].</dd> ** [COMMIT].</dd>
@ -7239,7 +7239,7 @@ SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema);
** <dd>The SQLITE_TXN_WRITE state means that the database is currently ** <dd>The SQLITE_TXN_WRITE state means that the database is currently
** in a write transaction. Content has been written to the database file ** in a write transaction. Content has been written to the database file
** but has not yet committed. The transaction state will change to ** but has not yet committed. The transaction state will change to
** to SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].</dd> ** SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].</dd>
*/ */
#define SQLITE_TXN_NONE 0 #define SQLITE_TXN_NONE 0
#define SQLITE_TXN_READ 1 #define SQLITE_TXN_READ 1
@ -7520,7 +7520,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*);
** CAPI3REF: Impose A Limit On Heap Size ** CAPI3REF: Impose A Limit On Heap Size
** **
** These interfaces impose limits on the amount of heap memory that will be ** These interfaces impose limits on the amount of heap memory that will be
** by all database connections within a single process. ** used by all database connections within a single process.
** **
** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the ** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the
** soft limit on the amount of heap memory that may be allocated by SQLite. ** soft limit on the amount of heap memory that may be allocated by SQLite.
@ -7578,7 +7578,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*);
** </ul>)^ ** </ul>)^
** **
** The circumstances under which SQLite will enforce the heap limits may ** The circumstances under which SQLite will enforce the heap limits may
** changes in future releases of SQLite. ** change in future releases of SQLite.
*/ */
SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N); SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N);
@ -7693,8 +7693,8 @@ SQLITE_API int sqlite3_table_column_metadata(
** ^The entry point is zProc. ** ^The entry point is zProc.
** ^(zProc may be 0, in which case SQLite will try to come up with an ** ^(zProc may be 0, in which case SQLite will try to come up with an
** entry point name on its own. It first tries "sqlite3_extension_init". ** entry point name on its own. It first tries "sqlite3_extension_init".
** If that does not work, it constructs a name "sqlite3_X_init" where the ** If that does not work, it constructs a name "sqlite3_X_init" where
** X is consists of the lower-case equivalent of all ASCII alphabetic ** X consists of the lower-case equivalent of all ASCII alphabetic
** characters in the filename from the last "/" to the first following ** characters in the filename from the last "/" to the first following
** "." and omitting any initial "lib".)^ ** "." and omitting any initial "lib".)^
** ^The sqlite3_load_extension() interface returns ** ^The sqlite3_load_extension() interface returns
@ -7765,7 +7765,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
** ^(Even though the function prototype shows that xEntryPoint() takes ** ^(Even though the function prototype shows that xEntryPoint() takes
** no arguments and returns void, SQLite invokes xEntryPoint() with three ** no arguments and returns void, SQLite invokes xEntryPoint() with three
** arguments and expects an integer result as if the signature of the ** arguments and expects an integer result as if the signature of the
** entry point where as follows: ** entry point were as follows:
** **
** <blockquote><pre> ** <blockquote><pre>
** &nbsp; int xEntryPoint( ** &nbsp; int xEntryPoint(
@ -7929,7 +7929,7 @@ struct sqlite3_module {
** virtual table and might not be checked again by the byte code.)^ ^(The ** virtual table and might not be checked again by the byte code.)^ ^(The
** aConstraintUsage[].omit flag is an optimization hint. When the omit flag ** aConstraintUsage[].omit flag is an optimization hint. When the omit flag
** is left in its default setting of false, the constraint will always be ** is left in its default setting of false, the constraint will always be
** checked separately in byte code. If the omit flag is change to true, then ** checked separately in byte code. If the omit flag is changed to true, then
** the constraint may or may not be checked in byte code. In other words, ** the constraint may or may not be checked in byte code. In other words,
** when the omit flag is true there is no guarantee that the constraint will ** when the omit flag is true there is no guarantee that the constraint will
** not be checked again using byte code.)^ ** not be checked again using byte code.)^
@ -7955,7 +7955,7 @@ struct sqlite3_module {
** The xBestIndex method may optionally populate the idxFlags field with a ** The xBestIndex method may optionally populate the idxFlags field with a
** mask of SQLITE_INDEX_SCAN_* flags. One such flag is ** mask of SQLITE_INDEX_SCAN_* flags. One such flag is
** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN] ** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN]
** output to show the idxNum has hex instead of as decimal. Another flag is ** output to show the idxNum as hex instead of as decimal. Another flag is
** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will ** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will
** return at most one row. ** return at most one row.
** **
@ -8096,7 +8096,7 @@ struct sqlite3_index_info {
** the implementation of the [virtual table module]. ^The fourth ** the implementation of the [virtual table module]. ^The fourth
** parameter is an arbitrary client data pointer that is passed through ** parameter is an arbitrary client data pointer that is passed through
** into the [xCreate] and [xConnect] methods of the virtual table module ** into the [xCreate] and [xConnect] methods of the virtual table module
** when a new virtual table is be being created or reinitialized. ** when a new virtual table is being created or reinitialized.
** **
** ^The sqlite3_create_module_v2() interface has a fifth parameter which ** ^The sqlite3_create_module_v2() interface has a fifth parameter which
** is a pointer to a destructor for the pClientData. ^SQLite will ** is a pointer to a destructor for the pClientData. ^SQLite will
@ -8261,7 +8261,7 @@ typedef struct sqlite3_blob sqlite3_blob;
** in *ppBlob. Otherwise an [error code] is returned and, unless the error ** in *ppBlob. Otherwise an [error code] is returned and, unless the error
** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided
** the API is not misused, it is always safe to call [sqlite3_blob_close()] ** the API is not misused, it is always safe to call [sqlite3_blob_close()]
** on *ppBlob after this function it returns. ** on *ppBlob after this function returns.
** **
** This function fails with SQLITE_ERROR if any of the following are true: ** This function fails with SQLITE_ERROR if any of the following are true:
** <ul> ** <ul>
@ -8381,7 +8381,7 @@ SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
** **
** ^Returns the size in bytes of the BLOB accessible via the ** ^Returns the size in bytes of the BLOB accessible via the
** successfully opened [BLOB handle] in its only argument. ^The ** successfully opened [BLOB handle] in its only argument. ^The
** incremental blob I/O routines can only read or overwriting existing ** incremental blob I/O routines can only read or overwrite existing
** blob content; they cannot change the size of a blob. ** blob content; they cannot change the size of a blob.
** **
** This routine only works on a [BLOB handle] which has been created ** This routine only works on a [BLOB handle] which has been created
@ -8531,7 +8531,7 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
** ^The sqlite3_mutex_alloc() routine allocates a new ** ^The sqlite3_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc() ** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc()
** routine returns NULL if it is unable to allocate the requested ** routine returns NULL if it is unable to allocate the requested
** mutex. The argument to sqlite3_mutex_alloc() must one of these ** mutex. The argument to sqlite3_mutex_alloc() must be one of these
** integer constants: ** integer constants:
** **
** <ul> ** <ul>
@ -8764,7 +8764,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
** CAPI3REF: Retrieve the mutex for a database connection ** CAPI3REF: Retrieve the mutex for a database connection
** METHOD: sqlite3 ** METHOD: sqlite3
** **
** ^This interface returns a pointer the [sqlite3_mutex] object that ** ^This interface returns a pointer to the [sqlite3_mutex] object that
** serializes access to the [database connection] given in the argument ** serializes access to the [database connection] given in the argument
** when the [threading mode] is Serialized. ** when the [threading mode] is Serialized.
** ^If the [threading mode] is Single-thread or Multi-thread then this ** ^If the [threading mode] is Single-thread or Multi-thread then this
@ -8887,7 +8887,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
** CAPI3REF: SQL Keyword Checking ** CAPI3REF: SQL Keyword Checking
** **
** These routines provide access to the set of SQL language keywords ** These routines provide access to the set of SQL language keywords
** recognized by SQLite. Applications can uses these routines to determine ** recognized by SQLite. Applications can use these routines to determine
** whether or not a specific identifier needs to be escaped (for example, ** whether or not a specific identifier needs to be escaped (for example,
** by enclosing in double-quotes) so as not to confuse the parser. ** by enclosing in double-quotes) so as not to confuse the parser.
** **
@ -9055,7 +9055,7 @@ SQLITE_API void sqlite3_str_reset(sqlite3_str*);
** content of the dynamic string under construction in X. The value ** content of the dynamic string under construction in X. The value
** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X ** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X
** and might be freed or altered by any subsequent method on the same ** and might be freed or altered by any subsequent method on the same
** [sqlite3_str] object. Applications must not used the pointer returned ** [sqlite3_str] object. Applications must not use the pointer returned by
** [sqlite3_str_value(X)] after any subsequent method call on the same ** [sqlite3_str_value(X)] after any subsequent method call on the same
** object. ^Applications may change the content of the string returned ** object. ^Applications may change the content of the string returned
** by [sqlite3_str_value(X)] as long as they do not write into any bytes ** by [sqlite3_str_value(X)] as long as they do not write into any bytes
@ -9141,7 +9141,7 @@ SQLITE_API int sqlite3_status64(
** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] ** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE]
** buffer and where forced to overflow to [sqlite3_malloc()]. The ** buffer and where forced to overflow to [sqlite3_malloc()]. The
** returned value includes allocations that overflowed because they ** returned value includes allocations that overflowed because they
** where too large (they were larger than the "sz" parameter to ** were too large (they were larger than the "sz" parameter to
** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because ** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because
** no space was left in the page cache.</dd>)^ ** no space was left in the page cache.</dd>)^
** **
@ -9225,28 +9225,29 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_HIT</dt> ** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_HIT</dt>
** <dd>This parameter returns the number of malloc attempts that were ** <dd>This parameter returns the number of malloc attempts that were
** satisfied using lookaside memory. Only the high-water value is meaningful; ** satisfied using lookaside memory. Only the high-water value is meaningful;
** the current value is always zero.)^ ** the current value is always zero.</dd>)^
** **
** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]] ** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]]
** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE</dt> ** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE</dt>
** <dd>This parameter returns the number malloc attempts that might have ** <dd>This parameter returns the number of malloc attempts that might have
** been satisfied using lookaside memory but failed due to the amount of ** been satisfied using lookaside memory but failed due to the amount of
** memory requested being larger than the lookaside slot size. ** memory requested being larger than the lookaside slot size.
** Only the high-water value is meaningful; ** Only the high-water value is meaningful;
** the current value is always zero.)^ ** the current value is always zero.</dd>)^
** **
** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]] ** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]]
** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL</dt> ** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL</dt>
** <dd>This parameter returns the number malloc attempts that might have ** <dd>This parameter returns the number of malloc attempts that might have
** been satisfied using lookaside memory but failed due to all lookaside ** been satisfied using lookaside memory but failed due to all lookaside
** memory already being in use. ** memory already being in use.
** Only the high-water value is meaningful; ** Only the high-water value is meaningful;
** the current value is always zero.)^ ** the current value is always zero.</dd>)^
** **
** [[SQLITE_DBSTATUS_CACHE_USED]] ^(<dt>SQLITE_DBSTATUS_CACHE_USED</dt> ** [[SQLITE_DBSTATUS_CACHE_USED]] ^(<dt>SQLITE_DBSTATUS_CACHE_USED</dt>
** <dd>This parameter returns the approximate number of bytes of heap ** <dd>This parameter returns the approximate number of bytes of heap
** memory used by all pager caches associated with the database connection.)^ ** memory used by all pager caches associated with the database connection.)^
** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. ** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0.
** </dd>
** **
** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]] ** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]]
** ^(<dt>SQLITE_DBSTATUS_CACHE_USED_SHARED</dt> ** ^(<dt>SQLITE_DBSTATUS_CACHE_USED_SHARED</dt>
@ -9255,10 +9256,10 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** memory used by that pager cache is divided evenly between the attached ** memory used by that pager cache is divided evenly between the attached
** connections.)^ In other words, if none of the pager caches associated ** connections.)^ In other words, if none of the pager caches associated
** with the database connection are shared, this request returns the same ** with the database connection are shared, this request returns the same
** value as DBSTATUS_CACHE_USED. Or, if one or more or the pager caches are ** value as DBSTATUS_CACHE_USED. Or, if one or more of the pager caches are
** shared, the value returned by this call will be smaller than that returned ** shared, the value returned by this call will be smaller than that returned
** by DBSTATUS_CACHE_USED. ^The highwater mark associated with ** by DBSTATUS_CACHE_USED. ^The highwater mark associated with
** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0. ** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0.</dd>
** **
** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt> ** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt>
** <dd>This parameter returns the approximate number of bytes of heap ** <dd>This parameter returns the approximate number of bytes of heap
@ -9268,6 +9269,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** schema memory is shared with other database connections due to ** schema memory is shared with other database connections due to
** [shared cache mode] being enabled. ** [shared cache mode] being enabled.
** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0. ** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0.
** </dd>
** **
** [[SQLITE_DBSTATUS_STMT_USED]] ^(<dt>SQLITE_DBSTATUS_STMT_USED</dt> ** [[SQLITE_DBSTATUS_STMT_USED]] ^(<dt>SQLITE_DBSTATUS_STMT_USED</dt>
** <dd>This parameter returns the approximate number of bytes of heap ** <dd>This parameter returns the approximate number of bytes of heap
@ -9304,7 +9306,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** been written to disk in the middle of a transaction due to the page ** been written to disk in the middle of a transaction due to the page
** cache overflowing. Transactions are more efficient if they are written ** cache overflowing. Transactions are more efficient if they are written
** to disk all at once. When pages spill mid-transaction, that introduces ** to disk all at once. When pages spill mid-transaction, that introduces
** additional overhead. This parameter can be used help identify ** additional overhead. This parameter can be used to help identify
** inefficiencies that can be resolved by increasing the cache size. ** inefficiencies that can be resolved by increasing the cache size.
** </dd> ** </dd>
** **
@ -9784,7 +9786,7 @@ typedef struct sqlite3_backup sqlite3_backup;
** external process or via a database connection other than the one being ** external process or via a database connection other than the one being
** used by the backup operation, then the backup will be automatically ** used by the backup operation, then the backup will be automatically
** restarted by the next call to sqlite3_backup_step(). ^If the source ** restarted by the next call to sqlite3_backup_step(). ^If the source
** database is modified by the using the same database connection as is used ** database is modified by using the same database connection as is used
** by the backup operation, then the backup database is automatically ** by the backup operation, then the backup database is automatically
** updated at the same time. ** updated at the same time.
** **
@ -9801,7 +9803,7 @@ typedef struct sqlite3_backup sqlite3_backup;
** and may not be used following a call to sqlite3_backup_finish(). ** and may not be used following a call to sqlite3_backup_finish().
** **
** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no ** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no
** sqlite3_backup_step() errors occurred, regardless or whether or not ** sqlite3_backup_step() errors occurred, regardless of whether or not
** sqlite3_backup_step() completed. ** sqlite3_backup_step() completed.
** ^If an out-of-memory condition or IO error occurred during any prior ** ^If an out-of-memory condition or IO error occurred during any prior
** sqlite3_backup_step() call on the same [sqlite3_backup] object, then ** sqlite3_backup_step() call on the same [sqlite3_backup] object, then
@ -10871,7 +10873,7 @@ SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
** METHOD: sqlite3 ** METHOD: sqlite3
** **
** ^If a write-transaction is open on [database connection] D when the ** ^If a write-transaction is open on [database connection] D when the
** [sqlite3_db_cacheflush(D)] interface invoked, any dirty ** [sqlite3_db_cacheflush(D)] interface is invoked, any dirty
** pages in the pager-cache that are not currently in use are written out ** pages in the pager-cache that are not currently in use are written out
** to disk. A dirty page may be in use if a database cursor created by an ** to disk. A dirty page may be in use if a database cursor created by an
** active SQL statement is reading from it, or if it is page 1 of a database ** active SQL statement is reading from it, or if it is page 1 of a database
@ -15442,8 +15444,8 @@ typedef INT16_TYPE LogEst;
** assuming n is a signed integer type. UMXV(n) is similar for unsigned ** assuming n is a signed integer type. UMXV(n) is similar for unsigned
** integer types. ** integer types.
*/ */
#define SMXV(n) ((((i64)1)<<(sizeof(n)-1))-1) #define SMXV(n) ((((i64)1)<<(sizeof(n)*8-1))-1)
#define UMXV(n) ((((i64)1)<<(sizeof(n)))-1) #define UMXV(n) ((((i64)1)<<(sizeof(n)*8))-1)
/* /*
** Round up a number to the next larger multiple of 8. This is used ** Round up a number to the next larger multiple of 8. This is used
@ -19254,7 +19256,7 @@ struct AggInfo {
** from source tables rather than from accumulators */ ** from source tables rather than from accumulators */
u8 useSortingIdx; /* In direct mode, reference the sorting index rather u8 useSortingIdx; /* In direct mode, reference the sorting index rather
** than the source table */ ** than the source table */
u16 nSortingColumn; /* Number of columns in the sorting index */ u32 nSortingColumn; /* Number of columns in the sorting index */
int sortingIdx; /* Cursor number of the sorting index */ int sortingIdx; /* Cursor number of the sorting index */
int sortingIdxPTab; /* Cursor number of pseudo-table */ int sortingIdxPTab; /* Cursor number of pseudo-table */
int iFirstReg; /* First register in range for aCol[] and aFunc[] */ int iFirstReg; /* First register in range for aCol[] and aFunc[] */
@ -19263,8 +19265,8 @@ struct AggInfo {
Table *pTab; /* Source table */ Table *pTab; /* Source table */
Expr *pCExpr; /* The original expression */ Expr *pCExpr; /* The original expression */
int iTable; /* Cursor number of the source table */ int iTable; /* Cursor number of the source table */
i16 iColumn; /* Column number within the source table */ int iColumn; /* Column number within the source table */
i16 iSorterColumn; /* Column number in the sorting index */ int iSorterColumn; /* Column number in the sorting index */
} *aCol; } *aCol;
int nColumn; /* Number of used entries in aCol[] */ int nColumn; /* Number of used entries in aCol[] */
int nAccumulator; /* Number of columns that show through to the output. int nAccumulator; /* Number of columns that show through to the output.
@ -54966,7 +54968,9 @@ bitvec_set_rehash:
}else{ }else{
memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
memset(p->u.apSub, 0, sizeof(p->u.apSub)); memset(p->u.apSub, 0, sizeof(p->u.apSub));
p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR; p->iDivisor = p->iSize/BITVEC_NPTR;
if( (p->iSize%BITVEC_NPTR)!=0 ) p->iDivisor++;
if( p->iDivisor<BITVEC_NBIT ) p->iDivisor = BITVEC_NBIT;
rc = sqlite3BitvecSet(p, i); rc = sqlite3BitvecSet(p, i);
for(j=0; j<BITVEC_NINT; j++){ for(j=0; j<BITVEC_NINT; j++){
if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]); if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]);
@ -69654,6 +69658,7 @@ SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *p
if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal); if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal);
} }
SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; )
pWal->iReCksum = 0;
} }
return rc; return rc;
} }
@ -69701,6 +69706,9 @@ SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){
walCleanupHash(pWal); walCleanupHash(pWal);
} }
SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; )
if( pWal->iReCksum>pWal->hdr.mxFrame ){
pWal->iReCksum = 0;
}
} }
return rc; return rc;
@ -117346,7 +117354,9 @@ static void findOrCreateAggInfoColumn(
){ ){
struct AggInfo_col *pCol; struct AggInfo_col *pCol;
int k; int k;
int mxTerm = pParse->db->aLimit[SQLITE_LIMIT_COLUMN];
assert( mxTerm <= SMXV(i16) );
assert( pAggInfo->iFirstReg==0 ); assert( pAggInfo->iFirstReg==0 );
pCol = pAggInfo->aCol; pCol = pAggInfo->aCol;
for(k=0; k<pAggInfo->nColumn; k++, pCol++){ for(k=0; k<pAggInfo->nColumn; k++, pCol++){
@ -117364,6 +117374,10 @@ static void findOrCreateAggInfoColumn(
assert( pParse->db->mallocFailed ); assert( pParse->db->mallocFailed );
return; return;
} }
if( k>mxTerm ){
sqlite3ErrorMsg(pParse, "more than %d aggregate terms", mxTerm);
k = mxTerm;
}
pCol = &pAggInfo->aCol[k]; pCol = &pAggInfo->aCol[k];
assert( ExprUseYTab(pExpr) ); assert( ExprUseYTab(pExpr) );
pCol->pTab = pExpr->y.pTab; pCol->pTab = pExpr->y.pTab;
@ -117397,6 +117411,7 @@ fix_up_expr:
if( pExpr->op==TK_COLUMN ){ if( pExpr->op==TK_COLUMN ){
pExpr->op = TK_AGG_COLUMN; pExpr->op = TK_AGG_COLUMN;
} }
assert( k <= SMXV(pExpr->iAgg) );
pExpr->iAgg = (i16)k; pExpr->iAgg = (i16)k;
} }
@ -117481,13 +117496,19 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
** function that is already in the pAggInfo structure ** function that is already in the pAggInfo structure
*/ */
struct AggInfo_func *pItem = pAggInfo->aFunc; struct AggInfo_func *pItem = pAggInfo->aFunc;
int mxTerm = pParse->db->aLimit[SQLITE_LIMIT_COLUMN];
assert( mxTerm <= SMXV(i16) );
for(i=0; i<pAggInfo->nFunc; i++, pItem++){ for(i=0; i<pAggInfo->nFunc; i++, pItem++){
if( NEVER(pItem->pFExpr==pExpr) ) break; if( NEVER(pItem->pFExpr==pExpr) ) break;
if( sqlite3ExprCompare(0, pItem->pFExpr, pExpr, -1)==0 ){ if( sqlite3ExprCompare(0, pItem->pFExpr, pExpr, -1)==0 ){
break; break;
} }
} }
if( i>=pAggInfo->nFunc ){ if( i>mxTerm ){
sqlite3ErrorMsg(pParse, "more than %d aggregate terms", mxTerm);
i = mxTerm;
assert( i<pAggInfo->nFunc );
}else if( i>=pAggInfo->nFunc ){
/* pExpr is original. Make a new entry in pAggInfo->aFunc[] /* pExpr is original. Make a new entry in pAggInfo->aFunc[]
*/ */
u8 enc = ENC(pParse->db); u8 enc = ENC(pParse->db);
@ -117541,6 +117562,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
*/ */
assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
ExprSetVVAProperty(pExpr, EP_NoReduce); ExprSetVVAProperty(pExpr, EP_NoReduce);
assert( i <= SMXV(pExpr->iAgg) );
pExpr->iAgg = (i16)i; pExpr->iAgg = (i16)i;
pExpr->pAggInfo = pAggInfo; pExpr->pAggInfo = pAggInfo;
return WRC_Prune; return WRC_Prune;
@ -131999,7 +132021,7 @@ static void concatFuncCore(
int nSep, int nSep,
const char *zSep const char *zSep
){ ){
i64 j, k, n = 0; i64 j, n = 0;
int i; int i;
char *z; char *z;
for(i=0; i<argc; i++){ for(i=0; i<argc; i++){
@ -132013,8 +132035,8 @@ static void concatFuncCore(
} }
j = 0; j = 0;
for(i=0; i<argc; i++){ for(i=0; i<argc; i++){
k = sqlite3_value_bytes(argv[i]); if( sqlite3_value_type(argv[i])!=SQLITE_NULL ){
if( k>0 ){ int k = sqlite3_value_bytes(argv[i]);
const char *v = (const char*)sqlite3_value_text(argv[i]); const char *v = (const char*)sqlite3_value_text(argv[i]);
if( v!=0 ){ if( v!=0 ){
if( j>0 && nSep>0 ){ if( j>0 && nSep>0 ){
@ -163433,30 +163455,42 @@ static void exprAnalyzeOrTerm(
** 1. The SQLITE_Transitive optimization must be enabled ** 1. The SQLITE_Transitive optimization must be enabled
** 2. Must be either an == or an IS operator ** 2. Must be either an == or an IS operator
** 3. Not originating in the ON clause of an OUTER JOIN ** 3. Not originating in the ON clause of an OUTER JOIN
** 4. The affinities of A and B must be compatible ** 4. The operator is not IS or else the query does not contain RIGHT JOIN
** 5a. Both operands use the same collating sequence OR ** 5. The affinities of A and B must be compatible
** 5b. The overall collating sequence is BINARY ** 6a. Both operands use the same collating sequence OR
** 6b. The overall collating sequence is BINARY
** If this routine returns TRUE, that means that the RHS can be substituted ** If this routine returns TRUE, that means that the RHS can be substituted
** for the LHS anyplace else in the WHERE clause where the LHS column occurs. ** for the LHS anyplace else in the WHERE clause where the LHS column occurs.
** This is an optimization. No harm comes from returning 0. But if 1 is ** This is an optimization. No harm comes from returning 0. But if 1 is
** returned when it should not be, then incorrect answers might result. ** returned when it should not be, then incorrect answers might result.
*/ */
static int termIsEquivalence(Parse *pParse, Expr *pExpr){ static int termIsEquivalence(Parse *pParse, Expr *pExpr, SrcList *pSrc){
char aff1, aff2; char aff1, aff2;
CollSeq *pColl; CollSeq *pColl;
if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; /* (1) */
if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; /* (2) */
if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* (3) */
assert( pSrc!=0 );
if( pExpr->op==TK_IS
&& pSrc->nSrc
&& (pSrc->a[0].fg.jointype & JT_LTORJ)!=0
){
return 0; /* (4) */
}
aff1 = sqlite3ExprAffinity(pExpr->pLeft); aff1 = sqlite3ExprAffinity(pExpr->pLeft);
aff2 = sqlite3ExprAffinity(pExpr->pRight); aff2 = sqlite3ExprAffinity(pExpr->pRight);
if( aff1!=aff2 if( aff1!=aff2
&& (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2)) && (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2))
){ ){
return 0; return 0; /* (5) */
} }
pColl = sqlite3ExprCompareCollSeq(pParse, pExpr); pColl = sqlite3ExprCompareCollSeq(pParse, pExpr);
if( sqlite3IsBinary(pColl) ) return 1; if( !sqlite3IsBinary(pColl)
return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight); && !sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight)
){
return 0; /* (6) */
}
return 1;
} }
/* /*
@ -163721,8 +163755,8 @@ static void exprAnalyze(
if( op==TK_IS ) pNew->wtFlags |= TERM_IS; if( op==TK_IS ) pNew->wtFlags |= TERM_IS;
pTerm = &pWC->a[idxTerm]; pTerm = &pWC->a[idxTerm];
pTerm->wtFlags |= TERM_COPIED; pTerm->wtFlags |= TERM_COPIED;
assert( pWInfo->pTabList!=0 );
if( termIsEquivalence(pParse, pDup) ){ if( termIsEquivalence(pParse, pDup, pWInfo->pTabList) ){
pTerm->eOperator |= WO_EQUIV; pTerm->eOperator |= WO_EQUIV;
eExtraOp = WO_EQUIV; eExtraOp = WO_EQUIV;
} }
@ -184424,6 +184458,7 @@ SQLITE_API int sqlite3_setlk_timeout(sqlite3 *db, int ms, int flags){
#endif #endif
if( ms<-1 ) return SQLITE_RANGE; if( ms<-1 ) return SQLITE_RANGE;
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
sqlite3_mutex_enter(db->mutex);
db->setlkTimeout = ms; db->setlkTimeout = ms;
db->setlkFlags = flags; db->setlkFlags = flags;
sqlite3BtreeEnterAll(db); sqlite3BtreeEnterAll(db);
@ -184435,6 +184470,7 @@ SQLITE_API int sqlite3_setlk_timeout(sqlite3 *db, int ms, int flags){
} }
} }
sqlite3BtreeLeaveAll(db); sqlite3BtreeLeaveAll(db);
sqlite3_mutex_leave(db->mutex);
#endif #endif
#if !defined(SQLITE_ENABLE_API_ARMOR) && !defined(SQLITE_ENABLE_SETLK_TIMEOUT) #if !defined(SQLITE_ENABLE_API_ARMOR) && !defined(SQLITE_ENABLE_SETLK_TIMEOUT)
UNUSED_PARAMETER(db); UNUSED_PARAMETER(db);
@ -257230,7 +257266,7 @@ static void fts5SourceIdFunc(
){ ){
assert( nArg==0 ); assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused); UNUSED_PARAM2(nArg, apUnused);
sqlite3_result_text(pCtx, "fts5: 2025-06-06 14:52:32 b77dc5e0f596d2140d9ac682b2893ff65d3a4140aa86067a3efebe29dc914c95", -1, SQLITE_TRANSIENT); sqlite3_result_text(pCtx, "fts5: 2025-06-28 14:00:48 2af157d77fb1304a74176eaee7fbc7c7e932d946bf25325e9c26c91db19e3079", -1, SQLITE_TRANSIENT);
} }
/* /*
@ -258045,6 +258081,7 @@ static int fts5StorageDeleteFromIndex(
for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
if( pConfig->abUnindexed[iCol-1]==0 ){ if( pConfig->abUnindexed[iCol-1]==0 ){
sqlite3_value *pVal = 0; sqlite3_value *pVal = 0;
sqlite3_value *pFree = 0;
const char *pText = 0; const char *pText = 0;
int nText = 0; int nText = 0;
const char *pLoc = 0; const char *pLoc = 0;
@ -258061,11 +258098,22 @@ static int fts5StorageDeleteFromIndex(
if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){
rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc);
}else{ }else{
pText = (const char*)sqlite3_value_text(pVal); if( sqlite3_value_type(pVal)!=SQLITE_TEXT ){
nText = sqlite3_value_bytes(pVal); /* Make a copy of the value to work with. This is because the call
if( pConfig->bLocale && pSeek ){ ** to sqlite3_value_text() below forces the type of the value to
pLoc = (const char*)sqlite3_column_text(pSeek, iCol + pConfig->nCol); ** SQLITE_TEXT, and we may need to use it again later. */
nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol); pFree = pVal = sqlite3_value_dup(pVal);
if( pVal==0 ){
rc = SQLITE_NOMEM;
}
}
if( rc==SQLITE_OK ){
pText = (const char*)sqlite3_value_text(pVal);
nText = sqlite3_value_bytes(pVal);
if( pConfig->bLocale && pSeek ){
pLoc = (const char*)sqlite3_column_text(pSeek, iCol+pConfig->nCol);
nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol);
}
} }
} }
@ -258081,6 +258129,7 @@ static int fts5StorageDeleteFromIndex(
} }
sqlite3Fts5ClearLocale(pConfig); sqlite3Fts5ClearLocale(pConfig);
} }
sqlite3_value_free(pFree);
} }
} }
if( rc==SQLITE_OK && p->nTotalRow<1 ){ if( rc==SQLITE_OK && p->nTotalRow<1 ){

92
deps/sqlite/sqlite3.h vendored

@ -146,9 +146,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()]. ** [sqlite_version()] and [sqlite_source_id()].
*/ */
#define SQLITE_VERSION "3.50.1" #define SQLITE_VERSION "3.50.2"
#define SQLITE_VERSION_NUMBER 3050001 #define SQLITE_VERSION_NUMBER 3050002
#define SQLITE_SOURCE_ID "2025-06-06 14:52:32 b77dc5e0f596d2140d9ac682b2893ff65d3a4140aa86067a3efebe29dc914c95" #define SQLITE_SOURCE_ID "2025-06-28 14:00:48 2af157d77fb1304a74176eaee7fbc7c7e932d946bf25325e9c26c91db19e3079"
/* /*
** CAPI3REF: Run-Time Library Version Numbers ** CAPI3REF: Run-Time Library Version Numbers
@ -4079,7 +4079,7 @@ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*);
** **
** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of
** database filename D with corresponding journal file J and WAL file W and ** database filename D with corresponding journal file J and WAL file W and
** with N URI parameters key/values pairs in the array P. The result from ** an array P of N URI Key/Value pairs. The result from
** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that ** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that
** is safe to pass to routines like: ** is safe to pass to routines like:
** <ul> ** <ul>
@ -4760,7 +4760,7 @@ typedef struct sqlite3_context sqlite3_context;
** METHOD: sqlite3_stmt ** METHOD: sqlite3_stmt
** **
** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, ** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants,
** literals may be replaced by a [parameter] that matches one of following ** literals may be replaced by a [parameter] that matches one of the following
** templates: ** templates:
** **
** <ul> ** <ul>
@ -4805,7 +4805,7 @@ typedef struct sqlite3_context sqlite3_context;
** **
** [[byte-order determination rules]] ^The byte-order of ** [[byte-order determination rules]] ^The byte-order of
** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF)
** found in first character, which is removed, or in the absence of a BOM ** found in the first character, which is removed, or in the absence of a BOM
** the byte order is the native byte order of the host ** the byte order is the native byte order of the host
** machine for sqlite3_bind_text16() or the byte order specified in ** machine for sqlite3_bind_text16() or the byte order specified in
** the 6th parameter for sqlite3_bind_text64().)^ ** the 6th parameter for sqlite3_bind_text64().)^
@ -4825,7 +4825,7 @@ typedef struct sqlite3_context sqlite3_context;
** or sqlite3_bind_text16() or sqlite3_bind_text64() then ** or sqlite3_bind_text16() or sqlite3_bind_text64() then
** that parameter must be the byte offset ** that parameter must be the byte offset
** where the NUL terminator would occur assuming the string were NUL ** where the NUL terminator would occur assuming the string were NUL
** terminated. If any NUL characters occurs at byte offsets less than ** terminated. If any NUL characters occur at byte offsets less than
** the value of the fourth parameter then the resulting string value will ** the value of the fourth parameter then the resulting string value will
** contain embedded NULs. The result of expressions involving strings ** contain embedded NULs. The result of expressions involving strings
** with embedded NULs is undefined. ** with embedded NULs is undefined.
@ -5037,7 +5037,7 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
** METHOD: sqlite3_stmt ** METHOD: sqlite3_stmt
** **
** ^These routines provide a means to determine the database, table, and ** ^These routines provide a means to determine the database, table, and
** table column that is the origin of a particular result column in ** table column that is the origin of a particular result column in a
** [SELECT] statement. ** [SELECT] statement.
** ^The name of the database or table or column can be returned as ** ^The name of the database or table or column can be returned as
** either a UTF-8 or UTF-16 string. ^The _database_ routines return ** either a UTF-8 or UTF-16 string. ^The _database_ routines return
@ -5606,8 +5606,8 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
** **
** For best security, the [SQLITE_DIRECTONLY] flag is recommended for ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for
** all application-defined SQL functions that do not need to be ** all application-defined SQL functions that do not need to be
** used inside of triggers, view, CHECK constraints, or other elements of ** used inside of triggers, views, CHECK constraints, or other elements of
** the database schema. This flags is especially recommended for SQL ** the database schema. This flag is especially recommended for SQL
** functions that have side effects or reveal internal application state. ** functions that have side effects or reveal internal application state.
** Without this flag, an attacker might be able to modify the schema of ** Without this flag, an attacker might be able to modify the schema of
** a database file to include invocations of the function with parameters ** a database file to include invocations of the function with parameters
@ -5638,7 +5638,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
** [user-defined window functions|available here]. ** [user-defined window functions|available here].
** **
** ^(If the final parameter to sqlite3_create_function_v2() or ** ^(If the final parameter to sqlite3_create_function_v2() or
** sqlite3_create_window_function() is not NULL, then it is destructor for ** sqlite3_create_window_function() is not NULL, then it is the destructor for
** the application data pointer. The destructor is invoked when the function ** the application data pointer. The destructor is invoked when the function
** is deleted, either by being overloaded or when the database connection ** is deleted, either by being overloaded or when the database connection
** closes.)^ ^The destructor is also invoked if the call to ** closes.)^ ^The destructor is also invoked if the call to
@ -6038,7 +6038,7 @@ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*);
** METHOD: sqlite3_value ** METHOD: sqlite3_value
** **
** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value] ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
** object D and returns a pointer to that copy. ^The [sqlite3_value] returned ** object V and returns a pointer to that copy. ^The [sqlite3_value] returned
** is a [protected sqlite3_value] object even if the input is not. ** is a [protected sqlite3_value] object even if the input is not.
** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
** memory allocation fails. ^If V is a [pointer value], then the result ** memory allocation fails. ^If V is a [pointer value], then the result
@ -6076,7 +6076,7 @@ SQLITE_API void sqlite3_value_free(sqlite3_value*);
** allocation error occurs. ** allocation error occurs.
** **
** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is ** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is
** determined by the N parameter on first successful call. Changing the ** determined by the N parameter on the first successful call. Changing the
** value of N in any subsequent call to sqlite3_aggregate_context() within ** value of N in any subsequent call to sqlite3_aggregate_context() within
** the same aggregate function instance will not resize the memory ** the same aggregate function instance will not resize the memory
** allocation.)^ Within the xFinal callback, it is customary to set ** allocation.)^ Within the xFinal callback, it is customary to set
@ -6238,7 +6238,7 @@ SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(voi
** **
** Security Warning: These interfaces should not be exposed in scripting ** Security Warning: These interfaces should not be exposed in scripting
** languages or in other circumstances where it might be possible for an ** languages or in other circumstances where it might be possible for an
** an attacker to invoke them. Any agent that can invoke these interfaces ** attacker to invoke them. Any agent that can invoke these interfaces
** can probably also take control of the process. ** can probably also take control of the process.
** **
** Database connection client data is only available for SQLite ** Database connection client data is only available for SQLite
@ -6352,7 +6352,7 @@ typedef void (*sqlite3_destructor_type)(void*);
** pointed to by the 2nd parameter are taken as the application-defined ** pointed to by the 2nd parameter are taken as the application-defined
** function result. If the 3rd parameter is non-negative, then it ** function result. If the 3rd parameter is non-negative, then it
** must be the byte offset into the string where the NUL terminator would ** must be the byte offset into the string where the NUL terminator would
** appear if the string where NUL terminated. If any NUL characters occur ** appear if the string were NUL terminated. If any NUL characters occur
** in the string at a byte offset that is less than the value of the 3rd ** in the string at a byte offset that is less than the value of the 3rd
** parameter, then the resulting string will contain embedded NULs and the ** parameter, then the resulting string will contain embedded NULs and the
** result of expressions operating on strings with embedded NULs is undefined. ** result of expressions operating on strings with embedded NULs is undefined.
@ -6410,7 +6410,7 @@ typedef void (*sqlite3_destructor_type)(void*);
** string and preferably a string literal. The sqlite3_result_pointer() ** string and preferably a string literal. The sqlite3_result_pointer()
** routine is part of the [pointer passing interface] added for SQLite 3.20.0. ** routine is part of the [pointer passing interface] added for SQLite 3.20.0.
** **
** If these routines are called from within the different thread ** If these routines are called from within a different thread
** than the one containing the application-defined function that received ** than the one containing the application-defined function that received
** the [sqlite3_context] pointer, the results are undefined. ** the [sqlite3_context] pointer, the results are undefined.
*/ */
@ -6816,7 +6816,7 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
** METHOD: sqlite3 ** METHOD: sqlite3
** **
** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name ** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name
** for the N-th database on database connection D, or a NULL pointer of N is ** for the N-th database on database connection D, or a NULL pointer if N is
** out of range. An N value of 0 means the main database file. An N of 1 is ** out of range. An N value of 0 means the main database file. An N of 1 is
** the "temp" schema. Larger values of N correspond to various ATTACH-ed ** the "temp" schema. Larger values of N correspond to various ATTACH-ed
** databases. ** databases.
@ -6911,7 +6911,7 @@ SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema);
** <dd>The SQLITE_TXN_READ state means that the database is currently ** <dd>The SQLITE_TXN_READ state means that the database is currently
** in a read transaction. Content has been read from the database file ** in a read transaction. Content has been read from the database file
** but nothing in the database file has changed. The transaction state ** but nothing in the database file has changed. The transaction state
** will advanced to SQLITE_TXN_WRITE if any changes occur and there are ** will be advanced to SQLITE_TXN_WRITE if any changes occur and there are
** no other conflicting concurrent write transactions. The transaction ** no other conflicting concurrent write transactions. The transaction
** state will revert to SQLITE_TXN_NONE following a [ROLLBACK] or ** state will revert to SQLITE_TXN_NONE following a [ROLLBACK] or
** [COMMIT].</dd> ** [COMMIT].</dd>
@ -6920,7 +6920,7 @@ SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema);
** <dd>The SQLITE_TXN_WRITE state means that the database is currently ** <dd>The SQLITE_TXN_WRITE state means that the database is currently
** in a write transaction. Content has been written to the database file ** in a write transaction. Content has been written to the database file
** but has not yet committed. The transaction state will change to ** but has not yet committed. The transaction state will change to
** to SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].</dd> ** SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].</dd>
*/ */
#define SQLITE_TXN_NONE 0 #define SQLITE_TXN_NONE 0
#define SQLITE_TXN_READ 1 #define SQLITE_TXN_READ 1
@ -7201,7 +7201,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*);
** CAPI3REF: Impose A Limit On Heap Size ** CAPI3REF: Impose A Limit On Heap Size
** **
** These interfaces impose limits on the amount of heap memory that will be ** These interfaces impose limits on the amount of heap memory that will be
** by all database connections within a single process. ** used by all database connections within a single process.
** **
** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the ** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the
** soft limit on the amount of heap memory that may be allocated by SQLite. ** soft limit on the amount of heap memory that may be allocated by SQLite.
@ -7259,7 +7259,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*);
** </ul>)^ ** </ul>)^
** **
** The circumstances under which SQLite will enforce the heap limits may ** The circumstances under which SQLite will enforce the heap limits may
** changes in future releases of SQLite. ** change in future releases of SQLite.
*/ */
SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N); SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N);
@ -7374,8 +7374,8 @@ SQLITE_API int sqlite3_table_column_metadata(
** ^The entry point is zProc. ** ^The entry point is zProc.
** ^(zProc may be 0, in which case SQLite will try to come up with an ** ^(zProc may be 0, in which case SQLite will try to come up with an
** entry point name on its own. It first tries "sqlite3_extension_init". ** entry point name on its own. It first tries "sqlite3_extension_init".
** If that does not work, it constructs a name "sqlite3_X_init" where the ** If that does not work, it constructs a name "sqlite3_X_init" where
** X is consists of the lower-case equivalent of all ASCII alphabetic ** X consists of the lower-case equivalent of all ASCII alphabetic
** characters in the filename from the last "/" to the first following ** characters in the filename from the last "/" to the first following
** "." and omitting any initial "lib".)^ ** "." and omitting any initial "lib".)^
** ^The sqlite3_load_extension() interface returns ** ^The sqlite3_load_extension() interface returns
@ -7446,7 +7446,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
** ^(Even though the function prototype shows that xEntryPoint() takes ** ^(Even though the function prototype shows that xEntryPoint() takes
** no arguments and returns void, SQLite invokes xEntryPoint() with three ** no arguments and returns void, SQLite invokes xEntryPoint() with three
** arguments and expects an integer result as if the signature of the ** arguments and expects an integer result as if the signature of the
** entry point where as follows: ** entry point were as follows:
** **
** <blockquote><pre> ** <blockquote><pre>
** &nbsp; int xEntryPoint( ** &nbsp; int xEntryPoint(
@ -7610,7 +7610,7 @@ struct sqlite3_module {
** virtual table and might not be checked again by the byte code.)^ ^(The ** virtual table and might not be checked again by the byte code.)^ ^(The
** aConstraintUsage[].omit flag is an optimization hint. When the omit flag ** aConstraintUsage[].omit flag is an optimization hint. When the omit flag
** is left in its default setting of false, the constraint will always be ** is left in its default setting of false, the constraint will always be
** checked separately in byte code. If the omit flag is change to true, then ** checked separately in byte code. If the omit flag is changed to true, then
** the constraint may or may not be checked in byte code. In other words, ** the constraint may or may not be checked in byte code. In other words,
** when the omit flag is true there is no guarantee that the constraint will ** when the omit flag is true there is no guarantee that the constraint will
** not be checked again using byte code.)^ ** not be checked again using byte code.)^
@ -7636,7 +7636,7 @@ struct sqlite3_module {
** The xBestIndex method may optionally populate the idxFlags field with a ** The xBestIndex method may optionally populate the idxFlags field with a
** mask of SQLITE_INDEX_SCAN_* flags. One such flag is ** mask of SQLITE_INDEX_SCAN_* flags. One such flag is
** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN] ** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN]
** output to show the idxNum has hex instead of as decimal. Another flag is ** output to show the idxNum as hex instead of as decimal. Another flag is
** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will ** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will
** return at most one row. ** return at most one row.
** **
@ -7777,7 +7777,7 @@ struct sqlite3_index_info {
** the implementation of the [virtual table module]. ^The fourth ** the implementation of the [virtual table module]. ^The fourth
** parameter is an arbitrary client data pointer that is passed through ** parameter is an arbitrary client data pointer that is passed through
** into the [xCreate] and [xConnect] methods of the virtual table module ** into the [xCreate] and [xConnect] methods of the virtual table module
** when a new virtual table is be being created or reinitialized. ** when a new virtual table is being created or reinitialized.
** **
** ^The sqlite3_create_module_v2() interface has a fifth parameter which ** ^The sqlite3_create_module_v2() interface has a fifth parameter which
** is a pointer to a destructor for the pClientData. ^SQLite will ** is a pointer to a destructor for the pClientData. ^SQLite will
@ -7942,7 +7942,7 @@ typedef struct sqlite3_blob sqlite3_blob;
** in *ppBlob. Otherwise an [error code] is returned and, unless the error ** in *ppBlob. Otherwise an [error code] is returned and, unless the error
** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided
** the API is not misused, it is always safe to call [sqlite3_blob_close()] ** the API is not misused, it is always safe to call [sqlite3_blob_close()]
** on *ppBlob after this function it returns. ** on *ppBlob after this function returns.
** **
** This function fails with SQLITE_ERROR if any of the following are true: ** This function fails with SQLITE_ERROR if any of the following are true:
** <ul> ** <ul>
@ -8062,7 +8062,7 @@ SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
** **
** ^Returns the size in bytes of the BLOB accessible via the ** ^Returns the size in bytes of the BLOB accessible via the
** successfully opened [BLOB handle] in its only argument. ^The ** successfully opened [BLOB handle] in its only argument. ^The
** incremental blob I/O routines can only read or overwriting existing ** incremental blob I/O routines can only read or overwrite existing
** blob content; they cannot change the size of a blob. ** blob content; they cannot change the size of a blob.
** **
** This routine only works on a [BLOB handle] which has been created ** This routine only works on a [BLOB handle] which has been created
@ -8212,7 +8212,7 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
** ^The sqlite3_mutex_alloc() routine allocates a new ** ^The sqlite3_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc() ** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc()
** routine returns NULL if it is unable to allocate the requested ** routine returns NULL if it is unable to allocate the requested
** mutex. The argument to sqlite3_mutex_alloc() must one of these ** mutex. The argument to sqlite3_mutex_alloc() must be one of these
** integer constants: ** integer constants:
** **
** <ul> ** <ul>
@ -8445,7 +8445,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
** CAPI3REF: Retrieve the mutex for a database connection ** CAPI3REF: Retrieve the mutex for a database connection
** METHOD: sqlite3 ** METHOD: sqlite3
** **
** ^This interface returns a pointer the [sqlite3_mutex] object that ** ^This interface returns a pointer to the [sqlite3_mutex] object that
** serializes access to the [database connection] given in the argument ** serializes access to the [database connection] given in the argument
** when the [threading mode] is Serialized. ** when the [threading mode] is Serialized.
** ^If the [threading mode] is Single-thread or Multi-thread then this ** ^If the [threading mode] is Single-thread or Multi-thread then this
@ -8568,7 +8568,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
** CAPI3REF: SQL Keyword Checking ** CAPI3REF: SQL Keyword Checking
** **
** These routines provide access to the set of SQL language keywords ** These routines provide access to the set of SQL language keywords
** recognized by SQLite. Applications can uses these routines to determine ** recognized by SQLite. Applications can use these routines to determine
** whether or not a specific identifier needs to be escaped (for example, ** whether or not a specific identifier needs to be escaped (for example,
** by enclosing in double-quotes) so as not to confuse the parser. ** by enclosing in double-quotes) so as not to confuse the parser.
** **
@ -8736,7 +8736,7 @@ SQLITE_API void sqlite3_str_reset(sqlite3_str*);
** content of the dynamic string under construction in X. The value ** content of the dynamic string under construction in X. The value
** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X ** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X
** and might be freed or altered by any subsequent method on the same ** and might be freed or altered by any subsequent method on the same
** [sqlite3_str] object. Applications must not used the pointer returned ** [sqlite3_str] object. Applications must not use the pointer returned by
** [sqlite3_str_value(X)] after any subsequent method call on the same ** [sqlite3_str_value(X)] after any subsequent method call on the same
** object. ^Applications may change the content of the string returned ** object. ^Applications may change the content of the string returned
** by [sqlite3_str_value(X)] as long as they do not write into any bytes ** by [sqlite3_str_value(X)] as long as they do not write into any bytes
@ -8822,7 +8822,7 @@ SQLITE_API int sqlite3_status64(
** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] ** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE]
** buffer and where forced to overflow to [sqlite3_malloc()]. The ** buffer and where forced to overflow to [sqlite3_malloc()]. The
** returned value includes allocations that overflowed because they ** returned value includes allocations that overflowed because they
** where too large (they were larger than the "sz" parameter to ** were too large (they were larger than the "sz" parameter to
** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because ** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because
** no space was left in the page cache.</dd>)^ ** no space was left in the page cache.</dd>)^
** **
@ -8906,28 +8906,29 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_HIT</dt> ** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_HIT</dt>
** <dd>This parameter returns the number of malloc attempts that were ** <dd>This parameter returns the number of malloc attempts that were
** satisfied using lookaside memory. Only the high-water value is meaningful; ** satisfied using lookaside memory. Only the high-water value is meaningful;
** the current value is always zero.)^ ** the current value is always zero.</dd>)^
** **
** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]] ** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]]
** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE</dt> ** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE</dt>
** <dd>This parameter returns the number malloc attempts that might have ** <dd>This parameter returns the number of malloc attempts that might have
** been satisfied using lookaside memory but failed due to the amount of ** been satisfied using lookaside memory but failed due to the amount of
** memory requested being larger than the lookaside slot size. ** memory requested being larger than the lookaside slot size.
** Only the high-water value is meaningful; ** Only the high-water value is meaningful;
** the current value is always zero.)^ ** the current value is always zero.</dd>)^
** **
** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]] ** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]]
** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL</dt> ** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL</dt>
** <dd>This parameter returns the number malloc attempts that might have ** <dd>This parameter returns the number of malloc attempts that might have
** been satisfied using lookaside memory but failed due to all lookaside ** been satisfied using lookaside memory but failed due to all lookaside
** memory already being in use. ** memory already being in use.
** Only the high-water value is meaningful; ** Only the high-water value is meaningful;
** the current value is always zero.)^ ** the current value is always zero.</dd>)^
** **
** [[SQLITE_DBSTATUS_CACHE_USED]] ^(<dt>SQLITE_DBSTATUS_CACHE_USED</dt> ** [[SQLITE_DBSTATUS_CACHE_USED]] ^(<dt>SQLITE_DBSTATUS_CACHE_USED</dt>
** <dd>This parameter returns the approximate number of bytes of heap ** <dd>This parameter returns the approximate number of bytes of heap
** memory used by all pager caches associated with the database connection.)^ ** memory used by all pager caches associated with the database connection.)^
** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. ** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0.
** </dd>
** **
** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]] ** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]]
** ^(<dt>SQLITE_DBSTATUS_CACHE_USED_SHARED</dt> ** ^(<dt>SQLITE_DBSTATUS_CACHE_USED_SHARED</dt>
@ -8936,10 +8937,10 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** memory used by that pager cache is divided evenly between the attached ** memory used by that pager cache is divided evenly between the attached
** connections.)^ In other words, if none of the pager caches associated ** connections.)^ In other words, if none of the pager caches associated
** with the database connection are shared, this request returns the same ** with the database connection are shared, this request returns the same
** value as DBSTATUS_CACHE_USED. Or, if one or more or the pager caches are ** value as DBSTATUS_CACHE_USED. Or, if one or more of the pager caches are
** shared, the value returned by this call will be smaller than that returned ** shared, the value returned by this call will be smaller than that returned
** by DBSTATUS_CACHE_USED. ^The highwater mark associated with ** by DBSTATUS_CACHE_USED. ^The highwater mark associated with
** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0. ** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0.</dd>
** **
** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt> ** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt>
** <dd>This parameter returns the approximate number of bytes of heap ** <dd>This parameter returns the approximate number of bytes of heap
@ -8949,6 +8950,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** schema memory is shared with other database connections due to ** schema memory is shared with other database connections due to
** [shared cache mode] being enabled. ** [shared cache mode] being enabled.
** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0. ** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0.
** </dd>
** **
** [[SQLITE_DBSTATUS_STMT_USED]] ^(<dt>SQLITE_DBSTATUS_STMT_USED</dt> ** [[SQLITE_DBSTATUS_STMT_USED]] ^(<dt>SQLITE_DBSTATUS_STMT_USED</dt>
** <dd>This parameter returns the approximate number of bytes of heap ** <dd>This parameter returns the approximate number of bytes of heap
@ -8985,7 +8987,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** been written to disk in the middle of a transaction due to the page ** been written to disk in the middle of a transaction due to the page
** cache overflowing. Transactions are more efficient if they are written ** cache overflowing. Transactions are more efficient if they are written
** to disk all at once. When pages spill mid-transaction, that introduces ** to disk all at once. When pages spill mid-transaction, that introduces
** additional overhead. This parameter can be used help identify ** additional overhead. This parameter can be used to help identify
** inefficiencies that can be resolved by increasing the cache size. ** inefficiencies that can be resolved by increasing the cache size.
** </dd> ** </dd>
** **
@ -9465,7 +9467,7 @@ typedef struct sqlite3_backup sqlite3_backup;
** external process or via a database connection other than the one being ** external process or via a database connection other than the one being
** used by the backup operation, then the backup will be automatically ** used by the backup operation, then the backup will be automatically
** restarted by the next call to sqlite3_backup_step(). ^If the source ** restarted by the next call to sqlite3_backup_step(). ^If the source
** database is modified by the using the same database connection as is used ** database is modified by using the same database connection as is used
** by the backup operation, then the backup database is automatically ** by the backup operation, then the backup database is automatically
** updated at the same time. ** updated at the same time.
** **
@ -9482,7 +9484,7 @@ typedef struct sqlite3_backup sqlite3_backup;
** and may not be used following a call to sqlite3_backup_finish(). ** and may not be used following a call to sqlite3_backup_finish().
** **
** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no ** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no
** sqlite3_backup_step() errors occurred, regardless or whether or not ** sqlite3_backup_step() errors occurred, regardless of whether or not
** sqlite3_backup_step() completed. ** sqlite3_backup_step() completed.
** ^If an out-of-memory condition or IO error occurred during any prior ** ^If an out-of-memory condition or IO error occurred during any prior
** sqlite3_backup_step() call on the same [sqlite3_backup] object, then ** sqlite3_backup_step() call on the same [sqlite3_backup] object, then
@ -10552,7 +10554,7 @@ SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
** METHOD: sqlite3 ** METHOD: sqlite3
** **
** ^If a write-transaction is open on [database connection] D when the ** ^If a write-transaction is open on [database connection] D when the
** [sqlite3_db_cacheflush(D)] interface invoked, any dirty ** [sqlite3_db_cacheflush(D)] interface is invoked, any dirty
** pages in the pager-cache that are not currently in use are written out ** pages in the pager-cache that are not currently in use are written out
** to disk. A dirty page may be in use if a database cursor created by an ** to disk. A dirty page may be in use if a database cursor created by an
** active SQL statement is reading from it, or if it is page 1 of a database ** active SQL statement is reading from it, or if it is page 1 of a database

@ -61,6 +61,7 @@ options:
autologin (default: false): Whether mobile autologin is supported. autologin (default: false): Whether mobile autologin is supported.
broadcast (default: true): Send network discovery broadcasts. broadcast (default: true): Send network discovery broadcasts.
discovery (default: true): Receive network discovery broadcasts. discovery (default: true): Receive network discovery broadcasts.
stay_connected (default: false): Whether to attempt to keep several peer connections open.
-o, --one-proc Run everything in one process (unsafely!). -o, --one-proc Run everything in one process (unsafely!).
-z, --zip path Zip archive from which to load files. -z, --zip path Zip archive from which to load files.
-v, --verbose Log raw messages. -v, --verbose Log raw messages.

8
flake.lock generated

@ -20,16 +20,16 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1748037224, "lastModified": 1750622754,
"narHash": "sha256-92vihpZr6dwEMV6g98M5kHZIttrWahb9iRPBm1atcPk=", "narHash": "sha256-kMhs+YzV4vPGfuTpD3mwzibWUE6jotw5Al2wczI0Pv8=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "f09dede81861f3a83f7f06641ead34f02f37597f", "rev": "c7ab75210cb8cb16ddd8f290755d9558edde7ee1",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "nixos-24.11", "ref": "nixos-25.05",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }

@ -2,7 +2,7 @@
description = "Tilde Friends is a platform for making, running, and sharing web applications."; description = "Tilde Friends is a platform for making, running, and sharing web applications.";
inputs = { inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11"; nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
flake-utils.url = "github:numtide/flake-utils"; flake-utils.url = "github:numtide/flake-utils";
}; };

@ -0,0 +1,2 @@
* Updating Android SDK+target versions.
* Minor UI improvements.

6
package-lock.json generated

@ -11,9 +11,9 @@
} }
}, },
"node_modules/prettier": { "node_modules/prettier": {
"version": "3.6.1", "version": "3.6.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.1.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
"integrity": "sha512-5xGWRa90Sp2+x1dQtNpIpeOQpTDBs9cZDmA/qs2vDNN2i18PdapqY7CmBeyLlMuGqXJRIOPaCaVZTLNQRWUH/A==", "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
"bin": { "bin": {
"prettier": "bin/prettier.cjs" "prettier": "bin/prettier.cjs"
}, },

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.unprompted.tildefriends" package="com.unprompted.tildefriends"
android:versionCode="38" android:versionCode="39"
android:versionName="0.0.32"> android:versionName="0.0.32.1">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<application <application

@ -13,13 +13,13 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>0.0.32</string> <string>0.0.32.1</string>
<key>CFBundleSupportedPlatforms</key> <key>CFBundleSupportedPlatforms</key>
<array> <array>
<string>iPhoneOS</string> <string>iPhoneOS</string>
</array> </array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>14</string> <string>15</string>
<key>DTPlatformName</key> <key>DTPlatformName</key>
<string>iphoneos</string> <string>iphoneos</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>

@ -3,6 +3,7 @@
#include "util.js.h" #include "util.js.h"
#include "quickjs.h" #include "quickjs.h"
#include "sodium/crypto_generichash.h"
#include "sqlite3.h" #include "sqlite3.h"
#include "uv.h" #include "uv.h"
@ -154,11 +155,11 @@ static void _tf_mem_summarize(void* ptr, size_t size, int frames_count, void* co
{ {
summary_t* summary = user_data; summary_t* summary = user_data;
tf_mem_allocation_t allocation = { tf_mem_allocation_t allocation = {
.stack_hash = tf_util_fnv32a(frames, sizeof(void*) * frames_count, 0),
.count = 1, .count = 1,
.size = size, .size = size,
.frames_count = frames_count, .frames_count = frames_count,
}; };
crypto_generichash((void*)&allocation.stack_hash, sizeof(allocation.stack_hash), (const void*)frames, sizeof(void*) * frames_count, NULL, 0);
memcpy(allocation.frames, frames, sizeof(void*) * frames_count); memcpy(allocation.frames, frames, sizeof(void*) * frames_count);
int index = tf_util_insert_index(&allocation, summary->allocations, summary->count, sizeof(tf_mem_allocation_t), _tf_mem_hash_stack_compare); int index = tf_util_insert_index(&allocation, summary->allocations, summary->count, sizeof(tf_mem_allocation_t), _tf_mem_hash_stack_compare);

@ -2,6 +2,7 @@
#include "log.h" #include "log.h"
#include "mem.h" #include "mem.h"
#include "ssb.db.h"
#include "ssb.h" #include "ssb.h"
#include "util.js.h" #include "util.js.h"
@ -51,15 +52,19 @@ static void _tf_ssb_connections_changed_callback(tf_ssb_t* ssb, tf_ssb_change_t
} }
} }
static bool _tf_ssb_connections_get_next_connection(tf_ssb_connections_t* connections, char* host, size_t host_size, int* port, char* key, size_t key_size) static bool _tf_ssb_connections_get_next_connection(
tf_ssb_connections_t* connections, char* host, size_t host_size, int* port, char* key, size_t key_size, bool* out_stay_connected)
{ {
bool result = false; bool result = false;
sqlite3_stmt* statement; sqlite3_stmt* statement;
sqlite3* db = tf_ssb_acquire_db_reader(connections->ssb); sqlite3* db = tf_ssb_acquire_db_reader(connections->ssb);
tf_ssb_db_get_global_setting_bool(db, "stay_connected", out_stay_connected);
if (sqlite3_prepare_v2(db, "SELECT host, port, key FROM connections WHERE last_attempt IS NULL OR (strftime('%s', 'now') - last_attempt > ?1) ORDER BY last_attempt LIMIT 1", if (sqlite3_prepare_v2(db, "SELECT host, port, key FROM connections WHERE last_attempt IS NULL OR (strftime('%s', 'now') - last_attempt > ?1) ORDER BY last_attempt LIMIT 1",
-1, &statement, NULL) == SQLITE_OK) -1, &statement, NULL) == SQLITE_OK)
{ {
if (sqlite3_bind_int(statement, 1, 60000) == SQLITE_OK && sqlite3_step(statement) == SQLITE_ROW) if (sqlite3_bind_int(statement, 1, *out_stay_connected ? 15 : 60000) == SQLITE_OK && sqlite3_step(statement) == SQLITE_ROW)
{ {
tf_string_set(host, host_size, (const char*)sqlite3_column_text(statement, 0)); tf_string_set(host, host_size, (const char*)sqlite3_column_text(statement, 0));
*port = sqlite3_column_int(statement, 1); *port = sqlite3_column_int(statement, 1);
@ -80,6 +85,8 @@ typedef struct _tf_ssb_connections_get_next_t
{ {
tf_ssb_connections_t* connections; tf_ssb_connections_t* connections;
bool ready; bool ready;
bool stay_connected;
bool full;
char host[256]; char host[256];
int port; int port;
char key[k_id_base64_len]; char key[k_id_base64_len];
@ -92,7 +99,7 @@ static void _tf_ssb_connections_get_next_work(tf_ssb_t* ssb, void* user_data)
{ {
return; return;
} }
next->ready = _tf_ssb_connections_get_next_connection(next->connections, next->host, sizeof(next->host), &next->port, next->key, sizeof(next->key)); next->ready = _tf_ssb_connections_get_next_connection(next->connections, next->host, sizeof(next->host), &next->port, next->key, sizeof(next->key), &next->stay_connected);
} }
static void _tf_ssb_connections_get_next_after_work(tf_ssb_t* ssb, int status, void* user_data) static void _tf_ssb_connections_get_next_after_work(tf_ssb_t* ssb, int status, void* user_data)
@ -100,12 +107,20 @@ static void _tf_ssb_connections_get_next_after_work(tf_ssb_t* ssb, int status, v
tf_ssb_connections_get_next_t* next = user_data; tf_ssb_connections_get_next_t* next = user_data;
if (next->ready) if (next->ready)
{ {
/*
** Might be a duplicate connection or otherwise discarded by
** tf_ssb_connect() before we otherwise set attempted, so do it
** here.
*/
tf_ssb_connections_set_attempted(next->connections, next->host, next->port, next->key);
uint8_t key_bin[k_id_bin_len]; uint8_t key_bin[k_id_bin_len];
if (tf_ssb_id_str_to_bin(key_bin, next->key)) if (tf_ssb_id_str_to_bin(key_bin, next->key))
{ {
tf_ssb_connect(ssb, next->host, next->port, key_bin, k_tf_ssb_connect_flag_do_not_store, NULL, NULL); tf_ssb_connect(ssb, next->host, next->port, key_bin, k_tf_ssb_connect_flag_do_not_store, NULL, NULL);
} }
} }
uv_timer_set_repeat(&next->connections->timer, next->stay_connected ? (next->full ? 2000 : 200) : (next->full ? 10000 : 2000));
tf_free(next); tf_free(next);
} }
@ -124,6 +139,7 @@ static void _tf_ssb_connections_timer(uv_timer_t* timer)
tf_ssb_connections_get_next_t* next = tf_malloc(sizeof(tf_ssb_connections_get_next_t)); tf_ssb_connections_get_next_t* next = tf_malloc(sizeof(tf_ssb_connections_get_next_t));
*next = (tf_ssb_connections_get_next_t) { *next = (tf_ssb_connections_get_next_t) {
.connections = connections, .connections = connections,
.full = count + 1 == tf_countof(active),
}; };
tf_ssb_run_work(connections->ssb, _tf_ssb_connections_get_next_work, _tf_ssb_connections_get_next_after_work, next); tf_ssb_run_work(connections->ssb, _tf_ssb_connections_get_next_work, _tf_ssb_connections_get_next_after_work, next);
} }

@ -332,8 +332,6 @@ static void _tf_ssb_rpc_tunnel_callback(tf_ssb_connection_t* connection, uint8_t
JS_FreeValue(context, stack_val); JS_FreeValue(context, stack_val);
JS_FreeValue(context, message_val); JS_FreeValue(context, message_val);
tf_ssb_connection_close(tun->connection, buffer);
} }
else else
{ {

@ -22,6 +22,7 @@
#include "ares.h" #include "ares.h"
#include "backtrace.h" #include "backtrace.h"
#include "quickjs.h" #include "quickjs.h"
#include "sodium/crypto_generichash.h"
#include "sqlite3.h" #include "sqlite3.h"
#include "unzip.h" #include "unzip.h"
#include "uv.h" #include "uv.h"
@ -1255,6 +1256,8 @@ static void _tf_task_free_promise(tf_task_t* task, promiseid_t id)
JSValue tf_task_allocate_promise(tf_task_t* task, promiseid_t* out_promise) JSValue tf_task_allocate_promise(tf_task_t* task, promiseid_t* out_promise)
{ {
uint32_t stack_hash = 0; uint32_t stack_hash = 0;
crypto_generichash_state state;
crypto_generichash_init(&state, NULL, 0, sizeof(stack_hash));
if (task->_promise_stack_debug) if (task->_promise_stack_debug)
{ {
JSValue error = JS_ThrowInternalError(task->_context, "promise callstack"); JSValue error = JS_ThrowInternalError(task->_context, "promise callstack");
@ -1262,16 +1265,17 @@ JSValue tf_task_allocate_promise(tf_task_t* task, promiseid_t* out_promise)
JSValue stack_value = JS_GetPropertyStr(task->_context, exception, "stack"); JSValue stack_value = JS_GetPropertyStr(task->_context, exception, "stack");
size_t length = 0; size_t length = 0;
const char* stack = JS_ToCStringLen(task->_context, &length, stack_value); const char* stack = JS_ToCStringLen(task->_context, &length, stack_value);
stack_hash = tf_util_fnv32a((const void*)stack, (int)length, 0); crypto_generichash_update(&state, (const void*)stack, (int)length);
void* buffer[31]; void* buffer[31];
int count = tf_util_backtrace(buffer, sizeof(buffer) / sizeof(*buffer)); int count = tf_util_backtrace(buffer, sizeof(buffer) / sizeof(*buffer));
stack_hash = tf_util_fnv32a((const void*)buffer, sizeof(void*) * count, stack_hash); crypto_generichash_update(&state, (const void*)buffer, sizeof(void*) * count);
_add_promise_stack(task, stack_hash, stack, buffer, count); _add_promise_stack(task, stack_hash, stack, buffer, count);
JS_FreeCString(task->_context, stack); JS_FreeCString(task->_context, stack);
JS_FreeValue(task->_context, stack_value); JS_FreeValue(task->_context, stack_value);
JS_FreeValue(task->_context, exception); JS_FreeValue(task->_context, exception);
JS_FreeValue(task->_context, error); JS_FreeValue(task->_context, error);
} }
crypto_generichash_final(&state, (void*)&stack_hash, sizeof(stack_hash));
promiseid_t promise_id; promiseid_t promise_id;
do do

@ -7,7 +7,6 @@
#include "trace.h" #include "trace.h"
#include "backtrace.h" #include "backtrace.h"
#include "openssl/sha.h"
#include "picohttpparser.h" #include "picohttpparser.h"
#include "sodium/utils.h" #include "sodium/utils.h"
#include "uv.h" #include "uv.h"
@ -400,6 +399,10 @@ static const setting_t k_settings[] = {
{ .name = "autologin", .type = "boolean", .description = "Whether mobile autologin is supported.", .default_value = { .kind = k_kind_bool, .bool_value = TF_IS_MOBILE != 0 } }, { .name = "autologin", .type = "boolean", .description = "Whether mobile autologin is supported.", .default_value = { .kind = k_kind_bool, .bool_value = TF_IS_MOBILE != 0 } },
{ .name = "broadcast", .type = "boolean", .description = "Send network discovery broadcasts.", .default_value = { .kind = k_kind_bool, .bool_value = true } }, { .name = "broadcast", .type = "boolean", .description = "Send network discovery broadcasts.", .default_value = { .kind = k_kind_bool, .bool_value = true } },
{ .name = "discovery", .type = "boolean", .description = "Receive network discovery broadcasts.", .default_value = { .kind = k_kind_bool, .bool_value = true } }, { .name = "discovery", .type = "boolean", .description = "Receive network discovery broadcasts.", .default_value = { .kind = k_kind_bool, .bool_value = true } },
{ .name = "stay_connected",
.type = "boolean",
.description = "Whether to attempt to keep several peer connections open.",
.default_value = { .kind = k_kind_bool, .bool_value = false } },
}; };
static const setting_t* _util_get_setting(const char* name, tf_setting_kind_t kind) static const setting_t* _util_get_setting(const char* name, tf_setting_kind_t kind)
@ -691,17 +694,6 @@ bool tf_util_is_mobile()
return TF_IS_MOBILE != 0; return TF_IS_MOBILE != 0;
} }
uint32_t tf_util_fnv32a(const void* buffer, int length, uint32_t start)
{
uint32_t result = 0x811c9dc5;
for (int i = 0; i < length; i++)
{
result ^= ((const uint8_t*)buffer)[i];
result += (result << 1) + (result << 4) + (result << 7) + (result << 8) + (result << 24);
}
return result;
}
size_t tf_string_set(char* buffer, size_t size, const char* string) size_t tf_string_set(char* buffer, size_t size, const char* string)
{ {
size_t length = string ? strlen(string) : 0; size_t length = string ? strlen(string) : 0;

@ -224,15 +224,6 @@ void tf_util_document_settings(const char* line_prefix);
*/ */
bool tf_util_is_mobile(); bool tf_util_is_mobile();
/**
** Compute a 32-bit hash of a buffer.
** @param buffer The data.
** @param length The size of the buffer in bytes.
** @param start The hash seed.
** @return The computed hash.
*/
uint32_t tf_util_fnv32a(const void* buffer, int length, uint32_t start);
/** /**
** Populate a string buffer, truncating if necessary. ** Populate a string buffer, truncating if necessary.
** @param buffer The buffer. ** @param buffer The buffer.

@ -1,2 +1,2 @@
#define VERSION_NUMBER "0.0.32" #define VERSION_NUMBER "0.0.32.1"
#define VERSION_NAME "This program kills fascists." #define VERSION_NAME "This program kills fascists."