Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

iOS: `get()` and `getArray()` always throw on iOS: the result set is read before `next()`

Aperta Adatta ai principianti
#50 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
88/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
ios, sqlite, typescript
Ambito
database, mobile

Direzione di ricerca

Inizia in src/sqlite/sqlite.ios.ts, in getRaw(), quindi confronta la gestione del relativo result set con selectRaw() e gli helper getResultsAsObject()/getResultsAsArray(). Verifica la riproduzione su iOS sia per get() che per getArray(), incluso un risultato vuoto, e conferma che venga restituita la prima riga, mentre in assenza di righe venga restituito null senza il TypeError.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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):

https://github.com/nativescript-community/sqlite/blob/60489226bc6badacf3a45504a55c1ec882099de4/src/sqlite/sqlite.ios.ts#L266-L279

and those read resultDictionary right away:

https://github.com/nativescript-community/sqlite/blob/60489226bc6badacf3a45504a55c1ec882099de4/src/sqlite/sqlite.ios.ts#L114-L131

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:

https://github.com/nativescript-community/sqlite/blob/60489226bc6badacf3a45504a55c1ec882099de4/src/sqlite/sqlite.ios.ts#L350-L359

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)

Lingua principale
TypeScript
Stelle
26
Fork
4
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

  • Nessun Dockerfile né file Docker Compose
  • Ha un modello di pull request
  • Nessuna guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di nativescript-community/sqlite

Tutte le issue di nativescript-community/sqlite

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.