1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-11-24 08:12:24 +02:00

Handles deleting folders

This commit is contained in:
Laurent Cozic 2017-05-18 22:31:40 +02:00
parent db4b6cf0d6
commit 8cce2af07e
7 changed files with 99 additions and 82 deletions

View File

@ -47,8 +47,19 @@ class BaseModel {
return output;
}
static modOptions(options) {
if (!options) {
options = {};
} else {
options = Object.assign({}, options);
}
if (!('trackChanges' in options)) options.trackChanges = true;
if (!('isNew' in options)) options.isNew = 'auto';
return options;
}
static saveQuery(o, isNew = 'auto') {
if (isNew == 'auto') isNew = !o.id;
if (isNew == 'auto') isNew = !o.id;
let query = '';
let itemId = o.id;
@ -71,14 +82,16 @@ class BaseModel {
return query;
}
static save(o, trackChanges = true, isNew = 'auto') {
if (isNew == 'auto') isNew = !o.id;
static save(o, options = null) {
options = this.modOptions(options);
let isNew = options.isNew == 'auto' ? !o.id : options.isNew;
let query = this.saveQuery(o, isNew);
return this.db().transaction((tx) => {
tx.executeSql(query.sql, query.params);
if (trackChanges && this.trackChanges()) {
if (options.trackChanges && this.trackChanges()) {
// Cannot import this class the normal way due to cyclical dependencies between Change and BaseModel
// which are not handled by React Native.
const { Change } = require('src/models/change.js');
@ -96,23 +109,30 @@ class BaseModel {
}).then(() => {
o = Object.assign({}, o);
o.id = query.id;
this.dispatch({
type: 'FOLDERS_UPDATE_ONE',
folder: o,
});
return o;
});
}
static delete(id) {
static delete(id, options = null) {
options = this.modOptions(options);
if (!id) {
Log.warn('Cannot delete object without an ID');
return;
}
return this.db().exec('DELETE FROM ' + this.tableName() + ' WHERE id = ?', [id]);
return this.db().exec('DELETE FROM ' + this.tableName() + ' WHERE id = ?', [id]).then(() => {
// if (options.trackChanges && this.trackChanges()) {
// const { Change } = require('src/models/change.js');
// let change = Change.newChange();
// change.type = Change.TYPE_DELETE;
// change.item_id = id;
// change.item_type = this.itemType();
// return Change.save(change);
// }
});
}
static db() {

View File

@ -31,10 +31,6 @@ class NotesScreenComponent extends React.Component {
deleteFolder_onPress = (folderId) => {
Folder.delete(folderId).then(() => {
this.props.dispatch({
type: 'FOLDER_DELETE',
folderId: folderId,
});
this.props.dispatch({
type: 'Navigation/NAVIGATE',
routeName: 'Folders',

View File

@ -1,7 +1,7 @@
import SQLite from 'react-native-sqlite-storage';
import { Log } from 'src/log.js';
import { uuid } from 'src/uuid.js';
import { PromiseChain } from 'src/promise-chain.js';
import { promiseChain } from 'src/promise-chain.js';
const structureSql = `
CREATE TABLE folders (
@ -110,7 +110,7 @@ class Database {
}
open() {
this.db_ = SQLite.openDatabase({ name: '/storage/emulated/0/Download/joplin-10.sqlite' }, (db) => {
this.db_ = SQLite.openDatabase({ name: '/storage/emulated/0/Download/joplin-11.sqlite' }, (db) => {
Log.info('Database was open successfully');
}, (error) => {
Log.error('Cannot open database: ', error);
@ -185,6 +185,10 @@ class Database {
});
}
executeSql(sql, params = null) {
return this.exec(sql, params);
}
static insertQuery(tableName, data) {
let keySql= '';
let valueSql = '';
@ -258,13 +262,13 @@ class Database {
});
}
return PromiseChain.exec(chain).then((queries) => {
return this.transaction((tx) => {
tx.executeSql('DELETE FROM table_fields');
for (let i = 0; i < queries.length; i++) {
tx.executeSql(queries[i].sql, queries[i].params);
}
});
return promiseChain(chain);
}).then((queries) => {
return this.transaction((tx) => {
tx.executeSql('DELETE FROM table_fields');
for (let i = 0; i < queries.length; i++) {
tx.executeSql(queries[i].sql, queries[i].params);
}
});
});
}
@ -308,45 +312,6 @@ class Database {
return this.initialize();
})
});
// return new Promise((resolve, reject) => {
// this.selectOne('SELECT * FROM version LIMIT 1').then((row) => {
// Log.info('Current database version', row);
// // TODO: version update logic
// // TODO: only do this if db has been updated
// return this.refreshTableFields();
// }).then(() => {
// return this.exec('SELECT * FROM table_fields').then((r) => {
// this.tableFields_ = {};
// for (let i = 0; i < r.rows.length; i++) {
// let row = r.rows.item(i);
// if (!this.tableFields_[row.table_name]) this.tableFields_[row.table_name] = [];
// this.tableFields_[row.table_name].push(row.field_name);
// }
// });
// }).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...');
// let statements = this.sqlStringToLines(structureSql)
// this.transaction((tx) => {
// for (let i = 0; i < statements.length; i++) {
// tx.executeSql(statements[i]);
// }
// tx.executeSql('INSERT INTO settings (`key`, `value`, `type`) VALUES ("clientId", "' + uuid.create() + '", "' + Database.enumToId('settings', 'string') + '")');
// }).then(() => {
// Log.info('Database schema created successfully');
// // Calling initialize() now that the db has been created will make it go through
// // the normal db update process (applying any additional patch).
// return this.initialize();
// }).catch((error) => {
// reject(error);
// });
// });
// });
}
}

View File

@ -1,5 +1,7 @@
import { BaseModel } from 'src/base-model.js';
import { Log } from 'src/log.js';
import { promiseChain } from 'src/promise-chain.js';
import { Note } from 'src/models/note.js';
class Folder extends BaseModel {
@ -26,10 +28,34 @@ class Folder extends BaseModel {
}
}
static delete(id) {
return this.db().transactionPromise((tx) => {
tx.executeSql('DELETE FROM notes WHERE parent_id = ?', [id]);
tx.executeSql('DELETE FROM folders WHERE id = ?', [id]);
static noteIds(id) {
return this.db().exec('SELECT id FROM notes WHERE parent_id = ?', [id]).then((r) => {
let output = [];
for (let i = 0; i < r.rows.length; i++) {
let row = r.rows.item(i);
output.push(row.id);
}
return output;
});
}
static delete(folderId, options = null) {
return this.noteIds(folderId).then((ids) => {
let chain = [];
for (let i = 0; i < ids.length; i++) {
chain.push(() => {
return Note.delete(ids[i]);
});
}
return promiseChain(chain);
}).then(() => {
return super.delete(folderId, options);
}).then(() => {
this.dispatch({
type: 'FOLDER_DELETE',
folderId: folderId,
});
});
}
@ -43,6 +69,16 @@ class Folder extends BaseModel {
});
}
static save(o, options = null) {
return super.save(o, options).then((folder) => {
this.dispatch({
type: 'FOLDERS_UPDATE_ONE',
folder: folder,
});
return folder;
});
}
}
export { Folder };

View File

@ -1,14 +1,10 @@
class PromiseChain {
static exec(chain) {
let output = new Promise((resolve, reject) => { resolve(); });
for (let i = 0; i < chain.length; i++) {
let f = chain[i];
output = output.then(f);
}
return output;
function promiseChain(chain) {
let output = new Promise((resolve, reject) => { resolve(); });
for (let i = 0; i < chain.length; i++) {
let f = chain[i];
output = output.then(f);
}
return output;
}
export { PromiseChain };
export { promiseChain }

View File

@ -187,6 +187,10 @@ class AppComponent extends React.Component {
Log.info('Loading folders...');
// Folder.noteIds('80a90393377b440bbf6edfe849bb87c5').then((ids) => {
// Log.info(ids);
// });
Folder.all().then((folders) => {
this.props.dispatch({
type: 'FOLDERS_UPDATE_ALL',
@ -196,8 +200,8 @@ class AppComponent extends React.Component {
Log.warn('Cannot load folders', error);
});
}).then(() => {
let synchronizer = new Synchronizer();
synchronizer.start();
// let synchronizer = new Synchronizer();
// synchronizer.start();
}).catch((error) => {
Log.error('Initialization error:', error);
});

View File

@ -36,7 +36,7 @@ class Synchronizer {
let folder = Folder.fromApiResult(syncOp.item);
// TODO: automatically handle NULL fields by checking type and default value of field
if (!folder.parent_id) folder.parent_id = '';
return Folder.save(folder, true, true);
return Folder.save(folder, { isNew: true });
});
}
}