mirror of https://github.com/laurent22/joplin.git
fix
parent
9047605637
commit
a43d4593c5
|
@ -351,7 +351,7 @@ export default class JoplinDatabase extends Database {
|
||||||
// must be set in the synchronizer too.
|
// must be set in the synchronizer too.
|
||||||
|
|
||||||
// Note: v16 and v17 don't do anything. They were used to debug an issue.
|
// Note: v16 and v17 don't do anything. They were used to debug an issue.
|
||||||
const existingDatabaseVersions = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41];
|
const existingDatabaseVersions = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42];
|
||||||
|
|
||||||
let currentVersionIndex = existingDatabaseVersions.indexOf(fromVersion);
|
let currentVersionIndex = existingDatabaseVersions.indexOf(fromVersion);
|
||||||
|
|
||||||
|
@ -910,6 +910,10 @@ export default class JoplinDatabase extends Database {
|
||||||
queries.push('ALTER TABLE `folders` ADD COLUMN icon TEXT NOT NULL DEFAULT ""');
|
queries.push('ALTER TABLE `folders` ADD COLUMN icon TEXT NOT NULL DEFAULT ""');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (targetVersion == 42) {
|
||||||
|
queries.push('ALTER TABLE `notes` ADD COLUMN is_shared_recursive INT NOT NULL DEFAULT 0');
|
||||||
|
}
|
||||||
|
|
||||||
const updateVersionQuery = { sql: 'UPDATE version SET version = ?', params: [targetVersion] };
|
const updateVersionQuery = { sql: 'UPDATE version SET version = ?', params: [targetVersion] };
|
||||||
|
|
||||||
queries.push(updateVersionQuery);
|
queries.push(updateVersionQuery);
|
||||||
|
|
|
@ -348,24 +348,55 @@ export default class Folder extends BaseItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async updateNoteShareIds() {
|
public static async updateNoteShareIds() {
|
||||||
// Find all the notes where the share_id is not the same as the
|
{
|
||||||
// parent share_id because we only need to update those.
|
// Find all the notes where the share_id is not the same as the
|
||||||
const rows = await this.db().selectAll(`
|
// parent share_id because we only need to update those.
|
||||||
SELECT notes.id, folders.share_id, notes.parent_id
|
const rows = await this.db().selectAll(`
|
||||||
FROM notes
|
SELECT notes.id, folders.share_id, notes.parent_id
|
||||||
LEFT JOIN folders ON notes.parent_id = folders.id
|
FROM notes
|
||||||
WHERE notes.share_id != folders.share_id
|
LEFT JOIN folders ON notes.parent_id = folders.id
|
||||||
`);
|
WHERE notes.share_id != folders.share_id
|
||||||
|
`);
|
||||||
|
|
||||||
logger.debug('updateNoteShareIds: notes to update:', rows.length);
|
logger.debug('updateNoteShareIds: notes to update:', rows.length);
|
||||||
|
|
||||||
for (const row of rows) {
|
for (const row of rows) {
|
||||||
await Note.save({
|
await Note.save({
|
||||||
id: row.id,
|
id: row.id,
|
||||||
share_id: row.share_id || '',
|
share_id: row.share_id || '',
|
||||||
parent_id: row.parent_id,
|
parent_id: row.parent_id,
|
||||||
updated_time: Date.now(),
|
updated_time: Date.now(),
|
||||||
}, { autoTimestamp: false });
|
}, { autoTimestamp: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also applies recursively published notes
|
||||||
|
{
|
||||||
|
// Find all the notes where the share_id is not the same as the
|
||||||
|
// parent share_id because we only need to update those.
|
||||||
|
const rows = await this.db().selectAll(`
|
||||||
|
SELECT notes.id, folders.share_id, notes.parent_id, notes.body
|
||||||
|
FROM notes
|
||||||
|
WHERE notes.is_shared = 1 AND notes.is_shared_recursive = 1
|
||||||
|
`);
|
||||||
|
|
||||||
|
logger.debug('updateNoteShareIds: notes recursively published:', rows.length);
|
||||||
|
|
||||||
|
// for (const row of rows) {
|
||||||
|
|
||||||
|
// // await Note.save({
|
||||||
|
// // id: row.id,
|
||||||
|
// // share_id: row.share_id || '',
|
||||||
|
// // parent_id: row.parent_id,
|
||||||
|
// // updated_time: Date.now(),
|
||||||
|
// // }, { autoTimestamp: false });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// TODO: should start from root notes - don't set is_recursive on children?
|
||||||
|
// TODO: when a child note is moved out of parent, how to know that is_shared should be cleared? - need share_root prop?
|
||||||
|
// or based on Share API objects? (passed to this function?)
|
||||||
|
// TODO: also unshare notes that have been unlinked (is_shared != parent.is_shared)
|
||||||
|
// TODO: avoid infinite loops
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -625,7 +656,7 @@ export default class Folder extends BaseItem {
|
||||||
rootFolders.push(folder);
|
rootFolders.push(folder);
|
||||||
} else {
|
} else {
|
||||||
if (!idToFolders[folder.parent_id]) {
|
if (!idToFolders[folder.parent_id]) {
|
||||||
// It means the notebook is refering a folder that doesn't exist. In theory it shouldn't happen
|
// It means the notebook is referring a folder that doesn't exist. In theory it shouldn't happen
|
||||||
// but sometimes does - https://github.com/laurent22/joplin/issues/1068#issuecomment-450594708
|
// but sometimes does - https://github.com/laurent22/joplin/issues/1068#issuecomment-450594708
|
||||||
rootFolders.push(folder);
|
rootFolders.push(folder);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -52,6 +52,10 @@ export const defaultFolderIcon = () => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// AUTO-GENERATED BY packages/tools/generate-database-types.js
|
// AUTO-GENERATED BY packages/tools/generate-database-types.js
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -59,225 +63,226 @@ export const defaultFolderIcon = () => {
|
||||||
* Rerun sql-ts to regenerate this file.
|
* Rerun sql-ts to regenerate this file.
|
||||||
*/
|
*/
|
||||||
export interface AlarmEntity {
|
export interface AlarmEntity {
|
||||||
"id"?: number | null
|
'id'?: number | null;
|
||||||
"note_id"?: string
|
'note_id'?: string;
|
||||||
"trigger_time"?: number
|
'trigger_time'?: number;
|
||||||
"type_"?: number
|
'type_'?: number;
|
||||||
}
|
}
|
||||||
export interface DeletedItemEntity {
|
export interface DeletedItemEntity {
|
||||||
"id"?: number | null
|
'id'?: number | null;
|
||||||
"item_type"?: number
|
'item_type'?: number;
|
||||||
"item_id"?: string
|
'item_id'?: string;
|
||||||
"deleted_time"?: number
|
'deleted_time'?: number;
|
||||||
"sync_target"?: number
|
'sync_target'?: number;
|
||||||
"type_"?: number
|
'type_'?: number;
|
||||||
}
|
}
|
||||||
export interface FolderEntity {
|
export interface FolderEntity {
|
||||||
"id"?: string | null
|
'id'?: string | null;
|
||||||
"title"?: string
|
'title'?: string;
|
||||||
"created_time"?: number
|
'created_time'?: number;
|
||||||
"updated_time"?: number
|
'updated_time'?: number;
|
||||||
"user_created_time"?: number
|
'user_created_time'?: number;
|
||||||
"user_updated_time"?: number
|
'user_updated_time'?: number;
|
||||||
"encryption_cipher_text"?: string
|
'encryption_cipher_text'?: string;
|
||||||
"encryption_applied"?: number
|
'encryption_applied'?: number;
|
||||||
"parent_id"?: string
|
'parent_id'?: string;
|
||||||
"is_shared"?: number
|
'is_shared'?: number;
|
||||||
"share_id"?: string
|
'share_id'?: string;
|
||||||
"master_key_id"?: string
|
'master_key_id'?: string;
|
||||||
"icon"?: string
|
'icon'?: string;
|
||||||
"type_"?: number
|
'type_'?: number;
|
||||||
}
|
}
|
||||||
export interface ItemChangeEntity {
|
export interface ItemChangeEntity {
|
||||||
"id"?: number | null
|
'id'?: number | null;
|
||||||
"item_type"?: number
|
'item_type'?: number;
|
||||||
"item_id"?: string
|
'item_id'?: string;
|
||||||
"type"?: number
|
'type'?: number;
|
||||||
"created_time"?: number
|
'created_time'?: number;
|
||||||
"source"?: number
|
'source'?: number;
|
||||||
"before_change_item"?: string
|
'before_change_item'?: string;
|
||||||
"type_"?: number
|
'type_'?: number;
|
||||||
}
|
}
|
||||||
export interface KeyValueEntity {
|
export interface KeyValueEntity {
|
||||||
"id"?: number | null
|
'id'?: number | null;
|
||||||
"key"?: string
|
'key'?: string;
|
||||||
"value"?: string
|
'value'?: string;
|
||||||
"type"?: number
|
'type'?: number;
|
||||||
"updated_time"?: number
|
'updated_time'?: number;
|
||||||
"type_"?: number
|
'type_'?: number;
|
||||||
}
|
}
|
||||||
export interface MigrationEntity {
|
export interface MigrationEntity {
|
||||||
"id"?: number | null
|
'id'?: number | null;
|
||||||
"number"?: number
|
'number'?: number;
|
||||||
"updated_time"?: number
|
'updated_time'?: number;
|
||||||
"created_time"?: number
|
'created_time'?: number;
|
||||||
"type_"?: number
|
'type_'?: number;
|
||||||
}
|
}
|
||||||
export interface NoteResourceEntity {
|
export interface NoteResourceEntity {
|
||||||
"id"?: number | null
|
'id'?: number | null;
|
||||||
"note_id"?: string
|
'note_id'?: string;
|
||||||
"resource_id"?: string
|
'resource_id'?: string;
|
||||||
"is_associated"?: number
|
'is_associated'?: number;
|
||||||
"last_seen_time"?: number
|
'last_seen_time'?: number;
|
||||||
"type_"?: number
|
'type_'?: number;
|
||||||
}
|
}
|
||||||
export interface NoteTagEntity {
|
export interface NoteTagEntity {
|
||||||
"id"?: string | null
|
'id'?: string | null;
|
||||||
"note_id"?: string
|
'note_id'?: string;
|
||||||
"tag_id"?: string
|
'tag_id'?: string;
|
||||||
"created_time"?: number
|
'created_time'?: number;
|
||||||
"updated_time"?: number
|
'updated_time'?: number;
|
||||||
"user_created_time"?: number
|
'user_created_time'?: number;
|
||||||
"user_updated_time"?: number
|
'user_updated_time'?: number;
|
||||||
"encryption_cipher_text"?: string
|
'encryption_cipher_text'?: string;
|
||||||
"encryption_applied"?: number
|
'encryption_applied'?: number;
|
||||||
"is_shared"?: number
|
'is_shared'?: number;
|
||||||
"type_"?: number
|
'type_'?: number;
|
||||||
}
|
}
|
||||||
export interface NoteEntity {
|
export interface NoteEntity {
|
||||||
"id"?: string | null
|
'id'?: string | null;
|
||||||
"parent_id"?: string
|
'parent_id'?: string;
|
||||||
"title"?: string
|
'title'?: string;
|
||||||
"body"?: string
|
'body'?: string;
|
||||||
"created_time"?: number
|
'created_time'?: number;
|
||||||
"updated_time"?: number
|
'updated_time'?: number;
|
||||||
"is_conflict"?: number
|
'is_conflict'?: number;
|
||||||
"latitude"?: number
|
'latitude'?: number;
|
||||||
"longitude"?: number
|
'longitude'?: number;
|
||||||
"altitude"?: number
|
'altitude'?: number;
|
||||||
"author"?: string
|
'author'?: string;
|
||||||
"source_url"?: string
|
'source_url'?: string;
|
||||||
"is_todo"?: number
|
'is_todo'?: number;
|
||||||
"todo_due"?: number
|
'todo_due'?: number;
|
||||||
"todo_completed"?: number
|
'todo_completed'?: number;
|
||||||
"source"?: string
|
'source'?: string;
|
||||||
"source_application"?: string
|
'source_application'?: string;
|
||||||
"application_data"?: string
|
'application_data'?: string;
|
||||||
"order"?: number
|
'order'?: number;
|
||||||
"user_created_time"?: number
|
'user_created_time'?: number;
|
||||||
"user_updated_time"?: number
|
'user_updated_time'?: number;
|
||||||
"encryption_cipher_text"?: string
|
'encryption_cipher_text'?: string;
|
||||||
"encryption_applied"?: number
|
'encryption_applied'?: number;
|
||||||
"markup_language"?: number
|
'markup_language'?: number;
|
||||||
"is_shared"?: number
|
'is_shared'?: number;
|
||||||
"share_id"?: string
|
'share_id'?: string;
|
||||||
"conflict_original_id"?: string
|
'conflict_original_id'?: string;
|
||||||
"master_key_id"?: string
|
'master_key_id'?: string;
|
||||||
"type_"?: number
|
'is_shared_recursive'?: number;
|
||||||
|
'type_'?: number;
|
||||||
}
|
}
|
||||||
export interface NotesNormalizedEntity {
|
export interface NotesNormalizedEntity {
|
||||||
"id"?: string
|
'id'?: string;
|
||||||
"title"?: string
|
'title'?: string;
|
||||||
"body"?: string
|
'body'?: string;
|
||||||
"user_created_time"?: number
|
'user_created_time'?: number;
|
||||||
"user_updated_time"?: number
|
'user_updated_time'?: number;
|
||||||
"is_todo"?: number
|
'is_todo'?: number;
|
||||||
"todo_completed"?: number
|
'todo_completed'?: number;
|
||||||
"parent_id"?: string
|
'parent_id'?: string;
|
||||||
"latitude"?: number
|
'latitude'?: number;
|
||||||
"longitude"?: number
|
'longitude'?: number;
|
||||||
"altitude"?: number
|
'altitude'?: number;
|
||||||
"source_url"?: string
|
'source_url'?: string;
|
||||||
"todo_due"?: number
|
'todo_due'?: number;
|
||||||
"type_"?: number
|
'type_'?: number;
|
||||||
}
|
}
|
||||||
export interface ResourceLocalStateEntity {
|
export interface ResourceLocalStateEntity {
|
||||||
"id"?: number | null
|
'id'?: number | null;
|
||||||
"resource_id"?: string
|
'resource_id'?: string;
|
||||||
"fetch_status"?: number
|
'fetch_status'?: number;
|
||||||
"fetch_error"?: string
|
'fetch_error'?: string;
|
||||||
"type_"?: number
|
'type_'?: number;
|
||||||
}
|
}
|
||||||
export interface ResourceEntity {
|
export interface ResourceEntity {
|
||||||
"id"?: string | null
|
'id'?: string | null;
|
||||||
"title"?: string
|
'title'?: string;
|
||||||
"mime"?: string
|
'mime'?: string;
|
||||||
"filename"?: string
|
'filename'?: string;
|
||||||
"created_time"?: number
|
'created_time'?: number;
|
||||||
"updated_time"?: number
|
'updated_time'?: number;
|
||||||
"user_created_time"?: number
|
'user_created_time'?: number;
|
||||||
"user_updated_time"?: number
|
'user_updated_time'?: number;
|
||||||
"file_extension"?: string
|
'file_extension'?: string;
|
||||||
"encryption_cipher_text"?: string
|
'encryption_cipher_text'?: string;
|
||||||
"encryption_applied"?: number
|
'encryption_applied'?: number;
|
||||||
"encryption_blob_encrypted"?: number
|
'encryption_blob_encrypted'?: number;
|
||||||
"size"?: number
|
'size'?: number;
|
||||||
"is_shared"?: number
|
'is_shared'?: number;
|
||||||
"share_id"?: string
|
'share_id'?: string;
|
||||||
"master_key_id"?: string
|
'master_key_id'?: string;
|
||||||
"type_"?: number
|
'type_'?: number;
|
||||||
}
|
}
|
||||||
export interface ResourcesToDownloadEntity {
|
export interface ResourcesToDownloadEntity {
|
||||||
"id"?: number | null
|
'id'?: number | null;
|
||||||
"resource_id"?: string
|
'resource_id'?: string;
|
||||||
"updated_time"?: number
|
'updated_time'?: number;
|
||||||
"created_time"?: number
|
'created_time'?: number;
|
||||||
"type_"?: number
|
'type_'?: number;
|
||||||
}
|
}
|
||||||
export interface RevisionEntity {
|
export interface RevisionEntity {
|
||||||
"id"?: string | null
|
'id'?: string | null;
|
||||||
"parent_id"?: string
|
'parent_id'?: string;
|
||||||
"item_type"?: number
|
'item_type'?: number;
|
||||||
"item_id"?: string
|
'item_id'?: string;
|
||||||
"item_updated_time"?: number
|
'item_updated_time'?: number;
|
||||||
"title_diff"?: string
|
'title_diff'?: string;
|
||||||
"body_diff"?: string
|
'body_diff'?: string;
|
||||||
"metadata_diff"?: string
|
'metadata_diff'?: string;
|
||||||
"encryption_cipher_text"?: string
|
'encryption_cipher_text'?: string;
|
||||||
"encryption_applied"?: number
|
'encryption_applied'?: number;
|
||||||
"updated_time"?: number
|
'updated_time'?: number;
|
||||||
"created_time"?: number
|
'created_time'?: number;
|
||||||
"type_"?: number
|
'type_'?: number;
|
||||||
}
|
}
|
||||||
export interface SettingEntity {
|
export interface SettingEntity {
|
||||||
"key"?: string | null
|
'key'?: string | null;
|
||||||
"value"?: string | null
|
'value'?: string | null;
|
||||||
"type_"?: number
|
'type_'?: number;
|
||||||
}
|
}
|
||||||
export interface SyncItemEntity {
|
export interface SyncItemEntity {
|
||||||
"id"?: number | null
|
'id'?: number | null;
|
||||||
"sync_target"?: number
|
'sync_target'?: number;
|
||||||
"sync_time"?: number
|
'sync_time'?: number;
|
||||||
"item_type"?: number
|
'item_type'?: number;
|
||||||
"item_id"?: string
|
'item_id'?: string;
|
||||||
"sync_disabled"?: number
|
'sync_disabled'?: number;
|
||||||
"sync_disabled_reason"?: string
|
'sync_disabled_reason'?: string;
|
||||||
"force_sync"?: number
|
'force_sync'?: number;
|
||||||
"item_location"?: number
|
'item_location'?: number;
|
||||||
"type_"?: number
|
'type_'?: number;
|
||||||
}
|
}
|
||||||
export interface TableFieldEntity {
|
export interface TableFieldEntity {
|
||||||
"id"?: number | null
|
'id'?: number | null;
|
||||||
"table_name"?: string
|
'table_name'?: string;
|
||||||
"field_name"?: string
|
'field_name'?: string;
|
||||||
"field_type"?: number
|
'field_type'?: number;
|
||||||
"field_default"?: string | null
|
'field_default'?: string | null;
|
||||||
"type_"?: number
|
'type_'?: number;
|
||||||
}
|
}
|
||||||
export interface TagEntity {
|
export interface TagEntity {
|
||||||
"id"?: string | null
|
'id'?: string | null;
|
||||||
"title"?: string
|
'title'?: string;
|
||||||
"created_time"?: number
|
'created_time'?: number;
|
||||||
"updated_time"?: number
|
'updated_time'?: number;
|
||||||
"user_created_time"?: number
|
'user_created_time'?: number;
|
||||||
"user_updated_time"?: number
|
'user_updated_time'?: number;
|
||||||
"encryption_cipher_text"?: string
|
'encryption_cipher_text'?: string;
|
||||||
"encryption_applied"?: number
|
'encryption_applied'?: number;
|
||||||
"is_shared"?: number
|
'is_shared'?: number;
|
||||||
"parent_id"?: string
|
'parent_id'?: string;
|
||||||
"type_"?: number
|
'type_'?: number;
|
||||||
}
|
}
|
||||||
export interface TagsWithNoteCountEntity {
|
export interface TagsWithNoteCountEntity {
|
||||||
"id"?: string | null
|
'id'?: string | null;
|
||||||
"title"?: string | null
|
'title'?: string | null;
|
||||||
"created_time"?: number | null
|
'created_time'?: number | null;
|
||||||
"updated_time"?: number | null
|
'updated_time'?: number | null;
|
||||||
"note_count"?: any | null
|
'note_count'?: any | null;
|
||||||
"todo_completed_count"?: any | null
|
'todo_completed_count'?: any | null;
|
||||||
"type_"?: number
|
'type_'?: number;
|
||||||
}
|
}
|
||||||
export interface VersionEntity {
|
export interface VersionEntity {
|
||||||
"version"?: number
|
'version'?: number;
|
||||||
"table_fields_version"?: number
|
'table_fields_version'?: number;
|
||||||
"type_"?: number
|
'type_'?: number;
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,6 +241,7 @@ export default class ShareService {
|
||||||
id: note.id,
|
id: note.id,
|
||||||
parent_id: note.parent_id,
|
parent_id: note.parent_id,
|
||||||
is_shared: 1,
|
is_shared: 1,
|
||||||
|
is_shared_recursive: recursive ? 1 : 0,
|
||||||
updated_time: Date.now(),
|
updated_time: Date.now(),
|
||||||
}, {
|
}, {
|
||||||
autoTimestamp: false,
|
autoTimestamp: false,
|
||||||
|
|
|
@ -27,6 +27,7 @@ export interface StateShare {
|
||||||
folder_id: string;
|
folder_id: string;
|
||||||
note_id: string;
|
note_id: string;
|
||||||
master_key_id: string;
|
master_key_id: string;
|
||||||
|
recursive: number;
|
||||||
user?: StateShareUserUser;
|
user?: StateShareUserUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,7 @@ export default class ShareModel extends BaseModel<Share> {
|
||||||
if (object.owner_id) output.owner_id = object.owner_id;
|
if (object.owner_id) output.owner_id = object.owner_id;
|
||||||
if (object.note_id) output.note_id = object.note_id;
|
if (object.note_id) output.note_id = object.note_id;
|
||||||
if (object.master_key_id) output.master_key_id = object.master_key_id;
|
if (object.master_key_id) output.master_key_id = object.master_key_id;
|
||||||
|
if ('recursive' in object) output.recursive = object.recursive;
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue