我目前正在嘗試爲react-native項目實現react-native-sqlite-storage插件,該代碼基於的原始repo上位於react-native-sqlite-storage關閉不是iOS中的功能
https://github.com/andpor/react-native-sqlite-storage [2]
我重寫位於在利用經由JS承諾插件庫的SRC文件夾的示例腳本。我重新創建的類幾乎完全可以工作,並且可以在iOS模擬器中執行。但是,使用close()函數關閉數據庫時出現錯誤 - 調試時返回的錯誤爲
that.db.close()不是函數。
引起錯誤的行是下面(apparantly)
that.db.close().then(onDbCloseSuccess).catch(onDbCloseError);
爲類的完整代碼如下。任何幫助解決這個問題非常感謝。 (注意,我保留原作者的參考,現在使用'that'作爲'this',意圖將'''稍後'重構成'this')。
'use strict';
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
ListView
} from 'react-native';
import SQLite from 'react-native-sqlite-storage';
SQLite.DEBUG(true);
SQLite.enablePromise(true);
export default class ExampleClass extends Component {
database_name = "Test.db";
database_version = "1.0";
database_displayname = "SQLite Test Database";
database_size = 200000;
db: Promise;
state = { progress:[] };
constructor(){
super();
}
getInitialState(){
return {
progress: [],
dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => any = (row1, row2) => { return row1 !== row2 ; },
})
};
}
componentWillUnmount(){
this.closeDatabase();
}
setAppState(msg: string){
this.state.progress.push(msg);
this.setState(this.state);
}
errorCB(err) {
console.log("(errorCB) ERROR: ", err);
this.setAppState("ERROR: " + (err.message || err));
}
closeDatabase(){
let that = this;
if (that.db) {
console.log("CLOSING DATABASE");
that.setAppState("CLOSING DATABASE");
const onDbCloseSuccess: (status: any) => void = (status: any) => {
console.log("DATABASE CLOSED");
that.setAppState("DATABASE CLOSED");
};
const onDbCloseError: (error: string) => void = (error: string) => {
that.errorCB(error);
};
// error closing database? no close method()?
that.db.close().then(onDbCloseSuccess).catch(onDbCloseError);
} else {
that.setAppState("DATABASE WAS NOT OPENED");
}
}
deleteDatabase(){
let that = this;
that.setAppState("DELETING DATABASE");
const onDeleteDBSuccess:() => void =() => {
console.log("DATABASE DELETED");
that.setAppState("DATABASE DELETED");
};
const onDeleteDBError: (error: string) => void = (error: string) => {
console.log("ERROR DELETING DATABASE");
that.errorCB(error);
};
SQLite.deleteDatabase(that.database_name).then(onDeleteDBSuccess).catch(onDeleteDBError);
}
queryEmployees(tx) {
let that = this;
console.log("Executing employee query");
const q: string = `SELECT a.name, b.name as deptName FROM Employees a, Departments b WHERE a.department = b.department_id`;
const executeSqlSuccess: Function = ([tx,results]) => {
that.state.progress.push("QUERY COMPLETED");
that.setState(that.state);
const numRows: number = results.rows.length;
for (let i = 0; i < numRows; i++) {
let row = results.rows.item(i);
that.state.progress.push(`Empl Name: ${row.name}, Dept Name: ${row.deptName}`);
}
that.setState(that.state);
};
const executeSqlFailure: (error: string) => void = (error: string) => {
console.log(error);
};
tx.executeSql(q).then(executeSqlSuccess).catch(executeSqlFailure);
}
populateDB(tx) {
console.log(`populateDB`);
let that = this;
that.setAppState("EXECUTING DROP STATEMENTS");
tx.executeSql('DROP TABLE IF EXISTS Employees;');
tx.executeSql('DROP TABLE IF EXISTS Offices;');
tx.executeSql('DROP TABLE IF EXISTS Departments;');
that.setAppState("EXECUTING CREATE STATEMENTS");
const onCreateTableError: (error: string) => void = (error) => {
that.errorCB(error);
};
tx.executeSql('CREATE TABLE IF NOT EXISTS Version('
+ 'version_id INTEGER PRIMARY KEY NOT NULL); ').catch(onCreateTableError);
tx.executeSql('CREATE TABLE IF NOT EXISTS Departments('
+ 'department_id INTEGER PRIMARY KEY NOT NULL, '
+ 'name VARCHAR(30)); ').catch(onCreateTableError);
tx.executeSql('CREATE TABLE IF NOT EXISTS Offices('
+ 'office_id INTEGER PRIMARY KEY NOT NULL, '
+ 'name VARCHAR(20), '
+ 'longtitude FLOAT, '
+ 'latitude FLOAT) ; ').catch(onCreateTableError);
tx.executeSql('CREATE TABLE IF NOT EXISTS Employees('
+ 'employee_id INTEGER PRIMARY KEY NOT NULL, '
+ 'name VARCHAR(55), '
+ 'office INTEGER, '
+ 'department INTEGER, '
+ 'FOREIGN KEY (office) REFERENCES Offices (office_id) '
+ 'FOREIGN KEY (department) REFERENCES Departments (department_id));').catch(onCreateTableError);
that.setAppState("EXECUTING INSERT STATEMENTS");
tx.executeSql('INSERT INTO Departments (name) VALUES ("Client Services");');
tx.executeSql('INSERT INTO Departments (name) VALUES ("Investor Services");');
tx.executeSql('INSERT INTO Departments (name) VALUES ("Shipping");');
tx.executeSql('INSERT INTO Departments (name) VALUES ("Direct Sales");');
tx.executeSql('INSERT INTO Offices (name, longtitude, latitude) VALUES ("Denver", 59.8, 34.1);');
tx.executeSql('INSERT INTO Offices (name, longtitude, latitude) VALUES ("Warsaw", 15.7, 54.1);');
tx.executeSql('INSERT INTO Offices (name, longtitude, latitude) VALUES ("Berlin", 35.3, 12.1);');
tx.executeSql('INSERT INTO Offices (name, longtitude, latitude) VALUES ("Paris", 10.7, 14.1);');
tx.executeSql('INSERT INTO Employees (name, office, department) VALUES ("Sylvester Stallone", 2, 4);');
tx.executeSql('INSERT INTO Employees (name, office, department) VALUES ("Elvis Presley", 2, 4);');
tx.executeSql('INSERT INTO Employees (name, office, department) VALUES ("Leslie Nelson", 3, 4);');
tx.executeSql('INSERT INTO Employees (name, office, department) VALUES ("Fidel Castro", 3, 3);');
tx.executeSql('INSERT INTO Employees (name, office, department) VALUES ("Bill Clinton", 1, 3);');
tx.executeSql('INSERT INTO Employees (name, office, department) VALUES ("Margaret Thatcher", 1, 3);');
tx.executeSql('INSERT INTO Employees (name, office, department) VALUES ("Donald Trump", 1, 3);');
tx.executeSql('INSERT INTO Employees (name, office, department) VALUES ("Dr DRE", 2, 2);');
tx.executeSql('INSERT INTO Employees (name, office, department) VALUES ("Samantha Fox", 2, 1);');
console.log("ALL CONFIG SQL DONE");
}
populateDatabase(dbResult){
let that = this;
that.state.progress.push("Database integrity check");
that.setState(that.state);
const q: string = 'SELECT 1 FROM Version LIMIT 1';
const executeSqlSuccess:() => void =() =>{
that.state.progress.push("Database is ready ... executing query ...");
that.setState(that.state);
const transactionSuccess:() => void =() => {
that.state.progress.push("Processing completed");
that.setState(that.state);
};
const transactionFailure: (error: string) => void = (error: string) => {
console.log(`*** transactionFailure error. details ***`, error);
};
dbResult.transaction(that.queryEmployees.bind(that)).then(transactionSuccess).catch(transactionFailure);
};
const executeSqlFailure: (error: string) => void = (error: string) =>{
console.log("Received error: ", error);
that.state.progress.push("DATABASE NOT READY ... POPULATING DATA");
that.setState(that.state);
const onPopulateDBSuccess:() => void =() =>{
that.state.progress.push("Database populated ... executing query ...");
that.setState(that.state);
const onTransactionComplete = (result) => {
console.log("Transaction is now finished");
that.state.progress.push("Processing completed");
that.setState(that.state);
that.closeDatabase()
};
const onTransactionFailure: (error: string) => void = (error: string) => {
console.log(`*** populateDatabase: transactionFailure error *** \n`,error);
};
dbResult.transaction(that.queryEmployees.bind(that)).then(onTransactionComplete).catch(onTransactionFailure);
};
const onPopulateDBFailure: Function = (error: string) => {
console.log(error);
};
dbResult.transaction(that.populateDB.bind(that)).then(onPopulateDBSuccess).catch(onPopulateDBFailure);
};
dbResult.executeSql(q).then(executeSqlSuccess).catch(executeSqlFailure);
}
loadAndQueryDB(){
const that = this;
that.setAppState("PLUGIN INTEGRITY CHECK");
const onOpenDBSuccess: (dbResult: any) => any = (dbResult: any) => {
console.log('*** onOpenDBSuccess ***');
console.log('DATABASE OPENED');
that.state.progress.push('DATABASE OPENED');
that.setState(that.state);
console.log(dbResult);
that.populateDatabase(dbResult);
};
const onOpenDBFailure: (error: string) => void = (error: string) => {
console.log('*** onOpenDBFailure ***');
console.log(error);
};
const onEchoTestComplete:() => void =() => {
console.log('*** onEchoTestComplete ***');
that.state.progress.push("Integrity check passed ...");
that.setState(that.state);
that.state.progress.push("Opening database ...");
that.setState(that.state);
// create a database
that.db = SQLite.openDatabase(this.database_name, this.database_version, this.database_displayname, this.database_size).then(onOpenDBSuccess).catch(onOpenDBFailure);
};
const onEchoTestFailure:() => void =() => {
console.log('*** onEchoTestFailure ***');
that.state.progress.push("echoTest failed - plugin not functional");
that.setState(that.state);
};
SQLite.echoTest().then(onEchoTestComplete).catch(onEchoTestFailure);
}
runDemo(){
this.state.progress = ["Starting SQLite Promise Demo"];
this.setState(this.state);
this.loadAndQueryDB();
}
render(){
let ds = new ListView.DataSource({rowHasChanged: (row1, row2) => { return row1 !== row2;}});
return (<View style={styles.mainContainer}>
<View style={styles.toolbar}>
<Text style={styles.toolbarButton} onPress={this.runDemo.bind(this)}>
Run Demo
</Text>
<Text style={styles.toolbarButton} onPress={this.closeDatabase.bind(this)}>
Close DB
</Text>
<Text style={styles.toolbarButton} onPress={this.deleteDatabase.bind(this)}>
Delete DB
</Text>
</View>
<ListView
enableEmptySections={true}
dataSource={ds.cloneWithRows(this.state.progress)}
renderRow={this.renderProgressEntry}
style={listStyles.liContainer}/>
</View>);
}
renderProgressEntry(entry){
return (<View style={listStyles.li}>
<View>
<Text style={listStyles.liText}>{entry}</Text>
</View>
</View>)
}
}
const listStyles = StyleSheet.create({
li: {
borderBottomColor: '#c8c7cc',
borderBottomWidth: 0.5,
paddingTop: 15,
paddingRight: 15,
paddingBottom: 15,
},
liContainer: {
backgroundColor: '#fff',
flex: 1,
paddingLeft: 15,
},
liIndent: {
flex: 1,
},
liText: {
color: '#333',
fontSize: 17,
fontWeight: '400',
marginBottom: -3.5,
marginTop: -3.5,
},
});
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
toolbar: {
backgroundColor: '#51c04d',
paddingTop: 30,
paddingBottom: 10,
flexDirection: 'row'
},
toolbarButton: {
color: 'blue',
textAlign: 'center',
flex: 1
},
mainContainer: {
flex: 1
}
});
AppRegistry.registerComponent('ExampleClass',() => ExampleClass);
這裏是從iOS模擬器中運行的反應,本機應用程序的詳細的錯誤信息(我削除項目名稱):