本应不可变的对象上具有值“nosync”的键“dblocation”已被冻结

问题描述 投票:0回答:1

在 SQLite 数据库中,我将数据本地存储在 iOS 和 Android 设备上。我创建了一个用于连接和操作的通用服务文件。打开数据库后我得到:

您尝试在一个不可变且已被冻结的对象上设置键“dblocation”和值“nosync”。

React-Native 0.74.1,节点 v22.3.0,react-native-sqlite-storage 6.0.1。服务文件:

import SQLite, { SQLiteDatabase, ResultSet } from 'react-native-sqlite-storage';
import {  databaseName, location } from './DbConfig';

SQLite.DEBUG(true);
SQLite.enablePromise(true);

const databaseConfig = {
name: databaseName,
location: location,
dblocation: location,
// createFromLocation:createFromLocation
};

export interface Item {
id: number;
name: string;
description: string;
new_column?: string; }
class DatabaseService {
private readOnly: boolean = false;

private async initDB(): Promise<SQLiteDatabase> {
    try {
        const opens = await SQLite.openDatabase(databaseConfig);
        console.log('opens', opens);
        return opens;
    } catch (error) {
        console.error('Failed to open database:', error);
        throw error;
    }
}

private closeDatabase(db: SQLiteDatabase): void {
    db.close().catch((error) => console.error('Failed to close database:', error));
}

setReadOnlyMode(isReadOnly: boolean): void {
    this.readOnly = isReadOnly;
}

async createTable(): Promise<void> {
    if (this.readOnly) throw new Error('Database is in read-only mode');
    const db = await this.initDB();
    await db.executeSql(`
  CREATE TABLE IF NOT EXISTS items (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT,
    description TEXT
  )
`);
    this.closeDatabase(db);
}

async addItem(item: Item): Promise<ResultSet> {
    if (this.readOnly) throw new Error('Database is in read-only mode');
    const db = await this.initDB();
    const result = await db.executeSql('INSERT INTO items (name, description) VALUES (?, ?)', [
        item.name,
        item.description,
    ]);
    this.closeDatabase(db);
    return result[0];
}

async updateItem(id: number, item: Item): Promise<ResultSet> {
    if (this.readOnly) throw new Error('Database is in read-only mode');
    const db = await this.initDB();
    const result = await db.executeSql('UPDATE items SET name = ?, description = ? WHERE id = ?', [
        item.name,
        item.description,
        id,
    ]);
    this.closeDatabase(db);
    return result[0];
}

async deleteItem(id: number): Promise<ResultSet> {
    if (this.readOnly) throw new Error('Database is in read-only mode');
    const db = await this.initDB();
    const result = await db.executeSql('DELETE FROM items WHERE id = ?', [id]);
    this.closeDatabase(db);
    return result[0];
}

async getItems(): Promise<Item[]> {
    const db = await this.initDB();
    console.log('--------', '----', db);

    const [result] = await db.executeSql('SELECT * FROM items', []);
    console.log('---result-----', result);

    this.closeDatabase(db);

    const items: Item[] = [];
    for (let i = 0; i < result.rows.length; i++) {
        items.push(result.rows.item(i));
    }
    return items;
}

async updateDatabaseVersion(newVersion: number): Promise<void> {
    if (this.readOnly) throw new Error('Database is in read-only mode');
    const db = await this.initDB();
    const [result] = await db.executeSql('PRAGMA user_version');
    const currentVersion = result.rows.item(0).user_version;

    if (currentVersion < newVersion) {
        await db.executeSql('ALTER TABLE items ADD COLUMN new_column TEXT');
        await db.executeSql(`PRAGMA user_version = ${newVersion}`);
    }

    this.closeDatabase(db);
}
}
export default new DatabaseService();

配置:

export const databaseName='Database2024.db';
export const dbVersion=1;
export const location='default'
export const createFromLocation =1

用途:

useEffect(() => {
    (async () => {
        const aa=  await DatabaseService.createTable();
        await fetchItems();
    })();
}, []);
ios react-native sqlite react-native-sqlite-storage
1个回答
0
投票

似乎您正在尝试打开数据库,但没有正确设置数据库,也许这段代码可以帮助您,它是我写的

创建数据库并建立连接的代码 // 应用程序/db/db.ts

import { SQLiteDatabase, enablePromise, openDatabase } 
from "react-native-sqlite-storage"
  
// Enable promise for SQLite
enablePromise(true)

export const connectToDatabase = async () => {
  return openDatabase(
    { name: "loope.db", location: "default" },
    () => {},
    (error) => {
      console.error(error)
      throw Error("Could not connect to database")
    }
  )
}

export const createTables = async (db: SQLiteDatabase) => {
  const wordQuery = `
    CREATE TABLE IF NOT EXISTS words (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      word TEXT UNIQUE
    )
  `;
  try {
    await db.executeSql(wordQuery);
  } catch (error) {
    console.error(error);
    throw new Error(`Failed to create tables`);
  }
};

export const insertWord = async (db: SQLiteDatabase, word: string) => {
  const insertQuery = `INSERT INTO words (word) VALUES (?)`;
  try {
    await db.executeSql(insertQuery, [word]);
  } catch (error) {
    console.error(error);
    throw new Error(`Failed to insert word`);
  }
}

如果你想从另一个文件调用它,你只需放置这个useEffect

useEffect(() => {
    async function initializeDatabase() {
      try {
        const db = await connectToDatabase(); // Get connection from DB
        await createTables(db); // Create the tables
      } catch (error) {
        console.error(error);
      }
    }
    initializeDatabase();
  }, []);
© www.soinside.com 2019 - 2024. All rights reserved.