iOS: `get()` and `getArray()` always throw on iOS: the result set is read before `next()`
まだ誰も着手していません。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 88/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- ios, sqlite, typescript
調査の方向性
src/sqlite/sqlite.ios.ts の getRaw() から始め、結果セットの処理を selectRaw() およびヘルパーの getResultsAsObject()/getResultsAsArray() と比較します。空の結果を含め、get() と getArray() の両方について iOS で再現することを確認し、最初の行が返され、行がない場合は TypeError なしで null が返されることを確認します。
索引モデルが issue の本文から書いたものです。
説明
Environment
@nativescript-community/sqlite |
3.5.9 (latest) |
@nativescript/core |
9.1.2 |
@nativescript/ios |
9.1.0 |
| NativeScript CLI | 9.1.1 |
| Xcode | 26.3 |
| Device | iPhone 16 Pro simulator, iOS 18.6 |
Android (@nativescript/android 9.1.1) is unaffected - the same code path works there.
What happens
Every call to db.get() or db.getArray() rejects, no matter what the query is or whether it matches any row:
NSqlite Error: TypeError: Cannot read properties of null (reading 'enumerateKeysAndObjectsUsingBlock')
at throwError (node_modules/@nativescript-community/sqlite/sqlite.common.js:72)
Minimal reproduction
import { openOrCreate } from '@nativescript-community/sqlite';
import { knownFolders, path } from '@nativescript/core';
const db = openOrCreate(path.join(knownFolders.documents().path, 'repro.sqlite'));
await db.execute('CREATE TABLE IF NOT EXISTS t (a INTEGER)');
await db.execute('INSERT INTO t (a) VALUES (1)');
await db.select('SELECT a FROM t'); // [{ a: 1 }]
await db.get('SELECT a FROM t'); // throws
Cause
getRaw() in src/sqlite/sqlite.ios.ts hands the fresh FMResultSet straight to getResultsAsObject() / getResultsAsArray() (links below are to the v3.5.9 tag):
and those read resultDictionary right away:
FMDB's resultDictionary describes the row the result set currently sits on, and a result set that has never been stepped sits on no row, so it returns nil - hence the TypeError on null. selectRaw() in the same file gets this right, which is why select() works and get() does not:
Suggested fix
Step onto the first row, and report "no row" rather than an empty object:
function getRaw(db: SQLiteDatabase, query: string, params: SqliteParams, asObject: boolean, options?: SqliteRequestOptions): SqliteRow | SqliteParam[] {
const s = db.db.executeQueryWithArgumentsInArray(query, paramsToStringArray(params));
if (!s) {
throw db.db.lastError();
}
if (!s.next()) {
s.close();
return null;
}
const transformBlobs = options?.transformBlobs ?? db.transformBlobs;
const row = asObject ? getResultsAsObject(s, transformBlobs) : getResultsAsArray(s, transformBlobs);
s.close();
return row;
}
get() and getArray() already coerce a falsy result to null, so the signature does not change.
Workaround
Read single rows through select() and take the first element:
const rows = await db.select(query, params);
const row = rows[0] || null;
PR
I'm happy to open a pull request with the fix above (getRaw() in src/sqlite/sqlite.ios.ts)
- 主要言語
- TypeScript
- スター
- 26
- フォーク
- 4
- PR マージ指標
- 30日以内にマージされた PR はありません
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドなし
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
nativescript-community/sqlite のほかの issue
-
v6オープン
難易度 4/5 3〜5日 初心者へのやさしさ 25/100
nativescript-community/sqlite の issue をすべて見る
似ている issue
-
bug via-triage
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
pingdotgg/t3code#14452 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
solana-foundation/program-examples#747 · コメント 1 件 ·
メンテナーはふだん 9 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
remotion-dev/remotion#11847 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
openwatersio/slackwater#355 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
melgarafael/DeskcommCRM#1998 · コメント 3 件 ·
メンテナーはふだん 1 日以内に返信