mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Handle settings
This commit is contained in:
parent
a0472274a6
commit
1c9f358f96
@ -1,5 +1,6 @@
|
||||
import { Log } from 'src/log.js';
|
||||
import { Database } from 'src/database.js';
|
||||
import { Registry } from 'src/registry.js';
|
||||
import createUuid from 'uuid/v4';
|
||||
|
||||
class BaseModel {
|
||||
@ -29,12 +30,8 @@ class BaseModel {
|
||||
return this.db().exec(query.sql, query.params).then(() => { return o; });
|
||||
}
|
||||
|
||||
static setDb(database) {
|
||||
this.db_ = database;
|
||||
}
|
||||
|
||||
static db() {
|
||||
return this.db_;
|
||||
return Registry.db();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import SQLite from 'react-native-sqlite-storage';
|
||||
import { Log } from 'src/log.js';
|
||||
import createUuid from 'uuid/v4';
|
||||
|
||||
const structureSql = `
|
||||
CREATE TABLE folders (
|
||||
@ -84,6 +85,7 @@ class Database {
|
||||
|
||||
constructor() {
|
||||
this.debugMode_ = false;
|
||||
this.initialized_ = false;
|
||||
}
|
||||
|
||||
setDebugEnabled(v) {
|
||||
@ -95,14 +97,26 @@ class Database {
|
||||
return this.debugMode_;
|
||||
}
|
||||
|
||||
initialized() {
|
||||
return this.initialized_;
|
||||
}
|
||||
|
||||
open() {
|
||||
this.db_ = SQLite.openDatabase({ name: '/storage/emulated/0/Download/joplin.sqlite' }, (db) => {
|
||||
this.db_ = SQLite.openDatabase({ name: '/storage/emulated/0/Download/joplin-4.sqlite' }, (db) => {
|
||||
Log.info('Database was open successfully');
|
||||
}, (error) => {
|
||||
Log.error('Cannot open database: ', error);
|
||||
});
|
||||
|
||||
this.updateSchema();
|
||||
return this.updateSchema();
|
||||
}
|
||||
|
||||
static enumToId(type, s) {
|
||||
if (type == 'settings') {
|
||||
if (s == 'int') return 1;
|
||||
if (s == 'string') return 2;
|
||||
}
|
||||
throw new Error('Unknown enum type or value: ' + type + ', ' + s);
|
||||
}
|
||||
|
||||
sqlStringToLines(sql) {
|
||||
@ -202,28 +216,41 @@ class Database {
|
||||
};
|
||||
}
|
||||
|
||||
transaction(readyCallack, errorCallback, successCallback) {
|
||||
return this.db_.transaction(readyCallack, errorCallback, successCallback);
|
||||
}
|
||||
|
||||
updateSchema() {
|
||||
Log.info('Checking for database schema update...');
|
||||
|
||||
this.selectOne('SELECT * FROM version LIMIT 1').then((row) => {
|
||||
Log.info('Current database version', row);
|
||||
// TODO: version update logic
|
||||
}).catch((error) => {
|
||||
// Assume that error was:
|
||||
// { message: 'no such table: version (code 1): , while compiling: SELECT * FROM version', code: 0 }
|
||||
// which means the database is empty and the tables need to be created.
|
||||
return new Promise((resolve, reject) => {
|
||||
this.selectOne('SELECT * FROM version LIMIT 1').then((row) => {
|
||||
Log.info('Current database version', row);
|
||||
resolve();
|
||||
// TODO: version update logic
|
||||
}).catch((error) => {
|
||||
// Assume that error was:
|
||||
// { message: 'no such table: version (code 1): , while compiling: SELECT * FROM version', code: 0 }
|
||||
// which means the database is empty and the tables need to be created.
|
||||
|
||||
Log.info('Database is new - creating the schema...');
|
||||
Log.info('Database is new - creating the schema...');
|
||||
|
||||
let statements = this.sqlStringToLines(structureSql)
|
||||
this.db_.transaction((tx) => {
|
||||
for (let i = 0; i < statements.length; i++) {
|
||||
tx.executeSql(statements[i]);
|
||||
}
|
||||
}, (error) => {
|
||||
Log.error('Could not create database schema:', error);
|
||||
}, () => {
|
||||
Log.info('Database schema created successfully');
|
||||
let statements = this.sqlStringToLines(structureSql)
|
||||
//this.db_.transaction((tx) => {
|
||||
this.transaction((tx) => {
|
||||
try {
|
||||
for (let i = 0; i < statements.length; i++) {
|
||||
tx.executeSql(statements[i]);
|
||||
}
|
||||
tx.executeSql('INSERT INTO settings (`key`, `value`, `type`) VALUES ("clientId", "' + createUuid() + '", "' + Database.enumToId('settings', 'string') + '")');
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
}, (error) => {
|
||||
reject(error);
|
||||
}, () => {
|
||||
resolve('Database schema created successfully');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -1,20 +1,14 @@
|
||||
import { AppRegistry } from 'react-native';
|
||||
import { Database } from 'src/database.js'
|
||||
import { Log } from 'src/log.js'
|
||||
import { Root } from 'src/root.js';
|
||||
import { BaseModel } from 'src/base-model.js';
|
||||
import { Registry } from 'src/registry.js';
|
||||
import { Database } from 'src/database.js';
|
||||
|
||||
function main() {
|
||||
let debugMode = true;
|
||||
let clientId = 'A7D301DA7D301DA7D301DA7D301DA7D3';
|
||||
|
||||
Registry.setDebugMode(true);
|
||||
AppRegistry.registerComponent('AwesomeProject', () => Root);
|
||||
|
||||
let db = new Database();
|
||||
db.setDebugEnabled(debugMode);
|
||||
db.open();
|
||||
|
||||
BaseModel.setDb(db);
|
||||
// Note: The final part of the initialization process is in
|
||||
// AppComponent.componentDidMount(), when the application is ready.
|
||||
}
|
||||
|
||||
export { main }
|
82
ReactNativeClient/src/models/setting.js
Normal file
82
ReactNativeClient/src/models/setting.js
Normal file
@ -0,0 +1,82 @@
|
||||
import { BaseModel } from 'src/base-model.js';
|
||||
import { Log } from 'src/log.js';
|
||||
import { Database } from 'src/database.js';
|
||||
|
||||
class Setting extends BaseModel {
|
||||
|
||||
static tableName() {
|
||||
return 'settings';
|
||||
}
|
||||
|
||||
static defaultSetting(key) {
|
||||
if (!this.defaults_) {
|
||||
this.defaults_ = {
|
||||
'clientId': { value: '', type: 'string' },
|
||||
'sessionId': { value: '', type: 'string' },
|
||||
'lastUpdateTime': { value: '', type: 'int' },
|
||||
}
|
||||
}
|
||||
if (!(key in this.defaults_)) throw new Error('Unknown key: ' + key);
|
||||
|
||||
let output = Object.assign({}, this.defaults_[key]);
|
||||
output.key = key;
|
||||
return output;
|
||||
}
|
||||
|
||||
static load() {
|
||||
this.cache_ = [];
|
||||
return this.db().selectAll('SELECT * FROM settings').then((r) => {
|
||||
for (let i = 0; i < r.rows.length; i++) {
|
||||
this.cache_.push(r.rows.item(i));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static setValue(key, value) {
|
||||
this.scheduleUpdate();
|
||||
for (let i = 0; i < this.cache_.length; i++) {
|
||||
if (this.cache_[i].key == key) {
|
||||
this.cache_[i].value = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let s = this.defaultSetting(key);
|
||||
s.value = value;
|
||||
this.cache_.push(s);
|
||||
}
|
||||
|
||||
static value(key) {
|
||||
for (let i = 0; i < this.cache_.length; i++) {
|
||||
if (this.cache_[i].key == key) {
|
||||
return this.cache_[i].value;
|
||||
}
|
||||
}
|
||||
|
||||
let s = this.defaultSetting(key);
|
||||
return s.value;
|
||||
}
|
||||
|
||||
static scheduleUpdate() {
|
||||
if (this.updateTimeoutId) clearTimeout(this.updateTimeoutId);
|
||||
|
||||
this.updateTimeoutId = setTimeout(() => {
|
||||
Log.info('Saving settings...');
|
||||
this.updateTimeoutId = null;
|
||||
BaseModel.db().transaction((tx) => {
|
||||
tx.executeSql('DELETE FROM settings');
|
||||
for (let i = 0; i < this.cache_.length; i++) {
|
||||
let q = Database.insertQuery(this.tableName(), this.cache_[i]);
|
||||
tx.executeSql(q.sql, q.params);
|
||||
}
|
||||
}, (error) => {
|
||||
Log.warn('Could not update settings:', error);
|
||||
}, () => {
|
||||
Log.info('Settings have been saved.');
|
||||
});
|
||||
}, 500);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { Setting };
|
45
ReactNativeClient/src/registry.js
Normal file
45
ReactNativeClient/src/registry.js
Normal file
@ -0,0 +1,45 @@
|
||||
// Stores global dynamic objects that are not state but that are required
|
||||
// throughout the application. Dependency injection would be a better solution
|
||||
// but more complex and YAGNI at this point. However classes that make use of the
|
||||
// registry should be designed in such a way that they can be converted to use
|
||||
// dependency injection later on (eg. `BaseModel.db()`, `Synchroniser.api()`)
|
||||
|
||||
import { Database } from 'src/database.js'
|
||||
|
||||
class Registry {
|
||||
|
||||
static setDebugMode(v) {
|
||||
this.debugMode_ = v;
|
||||
}
|
||||
|
||||
static debugMode() {
|
||||
if (this.debugMode_ === undefined) return false;
|
||||
return this.debugMode_;
|
||||
}
|
||||
|
||||
static setApi(v) {
|
||||
this.api_ = v;
|
||||
}
|
||||
|
||||
static setDb(v) {
|
||||
this.db_ = v;
|
||||
}
|
||||
|
||||
static db() {
|
||||
if (!this.db_) throw new Error('Accessing database before it has been initialised');
|
||||
// if (!this.db_) {
|
||||
// this.db_ = new Database();
|
||||
// this.db_.setDebugEnabled(this.debugMode());
|
||||
// this.db_.open();
|
||||
// }
|
||||
return this.db_;
|
||||
}
|
||||
|
||||
static api() {
|
||||
if (!this.api_) throw new Error('Accessing web API before it has been initialised');
|
||||
return this.api_;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { Registry };
|
@ -8,7 +8,10 @@ import { StackNavigator } from 'react-navigation';
|
||||
import { addNavigationHelpers } from 'react-navigation';
|
||||
import { Log } from 'src/log.js'
|
||||
import { Note } from 'src/models/note.js'
|
||||
import { Database } from 'src/database.js'
|
||||
import { Registry } from 'src/registry.js'
|
||||
import { ItemList } from 'src/components/item-list.js'
|
||||
import { Setting } from 'src/models/setting.js'
|
||||
|
||||
let defaultState = {
|
||||
defaultText: 'bla',
|
||||
@ -93,12 +96,24 @@ class NotesScreenComponent extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
loginButton_press = () => {
|
||||
|
||||
}
|
||||
|
||||
syncButton_press = () => {
|
||||
Log.info('SYNC');
|
||||
}
|
||||
|
||||
render() {
|
||||
const { navigate } = this.props.navigation;
|
||||
return (
|
||||
<View style={{flex: 1}}>
|
||||
<ItemList style={{flex: 1}}/>
|
||||
<Button title="Create note" onPress={this.createNoteButton_press} />
|
||||
<View style={{flexDirection: 'row'}}>
|
||||
<Button title="Create note" onPress={this.createNoteButton_press} />
|
||||
<Button title="Login" onPress={this.loginButton_press} />
|
||||
<Button title="Sync" onPress={this.syncButton_press} />
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@ -180,13 +195,27 @@ const AppNavigator = StackNavigator({
|
||||
class AppComponent extends React.Component {
|
||||
|
||||
componentDidMount() {
|
||||
Note.previews().then((notes) => {
|
||||
this.props.dispatch({
|
||||
type: 'NOTES_UPDATE_ALL',
|
||||
notes: notes,
|
||||
let db = new Database();
|
||||
db.setDebugEnabled(Registry.debugMode());
|
||||
|
||||
db.open().then(() => {
|
||||
Log.info('Database is ready.');
|
||||
Registry.setDb(db);
|
||||
}).then(() => {
|
||||
Log.info('Loading settings...');
|
||||
return Setting.load();
|
||||
}).then(() => {
|
||||
Log.info('Loading notes...');
|
||||
Note.previews().then((notes) => {
|
||||
this.props.dispatch({
|
||||
type: 'NOTES_UPDATE_ALL',
|
||||
notes: notes,
|
||||
});
|
||||
}).catch((error) => {
|
||||
Log.warn('Cannot load notes', error);
|
||||
});
|
||||
}).catch((error) => {
|
||||
Log.warn('Cannot load notes', error);
|
||||
Log.error('Cannot initialize database:', error);
|
||||
});
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user