mirror of https://github.com/laurent22/joplin.git
Merge branch 'dev' into release-2.0
commit
50d17bfb36
|
@ -97,7 +97,10 @@ export default abstract class BaseModel<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mainTable) {
|
if (mainTable) {
|
||||||
output = output.map(f => `${mainTable}.${f}`);
|
output = output.map(f => {
|
||||||
|
if (f.includes(`${mainTable}.`)) return f;
|
||||||
|
return `${mainTable}.${f}`;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
|
|
|
@ -68,7 +68,7 @@ export default class ChangeModel extends BaseModel<Change> {
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private changesForUserQuery(userId: Uuid): Knex.QueryBuilder {
|
private changesForUserQuery(userId: Uuid, count: boolean): Knex.QueryBuilder {
|
||||||
// When need to get:
|
// When need to get:
|
||||||
//
|
//
|
||||||
// - All the CREATE and DELETE changes associated with the user
|
// - All the CREATE and DELETE changes associated with the user
|
||||||
|
@ -78,15 +78,8 @@ export default class ChangeModel extends BaseModel<Change> {
|
||||||
// UPDATE changes do not have the user_id set because they are specific
|
// UPDATE changes do not have the user_id set because they are specific
|
||||||
// to the item, not to a particular user.
|
// to the item, not to a particular user.
|
||||||
|
|
||||||
return this
|
const query = this
|
||||||
.db('changes')
|
.db('changes')
|
||||||
.select([
|
|
||||||
'id',
|
|
||||||
'item_id',
|
|
||||||
'item_name',
|
|
||||||
'type',
|
|
||||||
'updated_time',
|
|
||||||
])
|
|
||||||
.where(function() {
|
.where(function() {
|
||||||
void this.whereRaw('((type = ? OR type = ?) AND user_id = ?)', [ChangeType.Create, ChangeType.Delete, userId])
|
void this.whereRaw('((type = ? OR type = ?) AND user_id = ?)', [ChangeType.Create, ChangeType.Delete, userId])
|
||||||
// Need to use a RAW query here because Knex has a "not a
|
// Need to use a RAW query here because Knex has a "not a
|
||||||
|
@ -96,6 +89,20 @@ export default class ChangeModel extends BaseModel<Change> {
|
||||||
// https://github.com/knex/knex/issues/1851
|
// https://github.com/knex/knex/issues/1851
|
||||||
.orWhereRaw('type = ? AND item_id IN (SELECT item_id FROM user_items WHERE user_id = ?)', [ChangeType.Update, userId]);
|
.orWhereRaw('type = ? AND item_id IN (SELECT item_id FROM user_items WHERE user_id = ?)', [ChangeType.Update, userId]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (count) {
|
||||||
|
void query.countDistinct('id', { as: 'total' });
|
||||||
|
} else {
|
||||||
|
void query.select([
|
||||||
|
'id',
|
||||||
|
'item_id',
|
||||||
|
'item_name',
|
||||||
|
'type',
|
||||||
|
'updated_time',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async allByUser(userId: Uuid, pagination: Pagination = null): Promise<PaginatedChanges> {
|
public async allByUser(userId: Uuid, pagination: Pagination = null): Promise<PaginatedChanges> {
|
||||||
|
@ -106,9 +113,9 @@ export default class ChangeModel extends BaseModel<Change> {
|
||||||
...pagination,
|
...pagination,
|
||||||
};
|
};
|
||||||
|
|
||||||
const query = this.changesForUserQuery(userId);
|
const query = this.changesForUserQuery(userId, false);
|
||||||
const countQuery = query.clone();
|
const countQuery = this.changesForUserQuery(userId, true);
|
||||||
const itemCount = (await countQuery.countDistinct('id', { as: 'total' }))[0].total;
|
const itemCount = (await countQuery.first()).total;
|
||||||
|
|
||||||
void query
|
void query
|
||||||
.orderBy(pagination.order[0].by, pagination.order[0].dir)
|
.orderBy(pagination.order[0].by, pagination.order[0].dir)
|
||||||
|
@ -140,7 +147,7 @@ export default class ChangeModel extends BaseModel<Change> {
|
||||||
if (!changeAtCursor) throw new ErrorResyncRequired();
|
if (!changeAtCursor) throw new ErrorResyncRequired();
|
||||||
}
|
}
|
||||||
|
|
||||||
const query = this.changesForUserQuery(userId);
|
const query = this.changesForUserQuery(userId, false);
|
||||||
|
|
||||||
// If a cursor was provided, apply it to the query.
|
// If a cursor was provided, apply it to the query.
|
||||||
if (changeAtCursor) {
|
if (changeAtCursor) {
|
||||||
|
|
|
@ -130,4 +130,16 @@ describe('ItemModel', function() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should count items', async function() {
|
||||||
|
const { user: user1 } = await createUserAndSession(1, true);
|
||||||
|
|
||||||
|
await createItemTree(user1.id, '', {
|
||||||
|
'000000000000000000000000000000F1': {
|
||||||
|
'00000000000000000000000000000001': null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(await models().item().childrenCount(user1.id)).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -349,13 +349,18 @@ export default class ItemModel extends BaseModel<Item> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private childrenQuery(userId: Uuid, pathQuery: string = '', options: LoadOptions = {}): Knex.QueryBuilder {
|
private childrenQuery(userId: Uuid, pathQuery: string = '', count: boolean = false, options: LoadOptions = {}): Knex.QueryBuilder {
|
||||||
const query = this
|
const query = this
|
||||||
.db('user_items')
|
.db('user_items')
|
||||||
.leftJoin('items', 'user_items.item_id', 'items.id')
|
.leftJoin('items', 'user_items.item_id', 'items.id')
|
||||||
.select(this.selectFields(options, ['id', 'name', 'updated_time'], 'items'))
|
|
||||||
.where('user_items.user_id', '=', userId);
|
.where('user_items.user_id', '=', userId);
|
||||||
|
|
||||||
|
if (count) {
|
||||||
|
void query.countDistinct('items.id', { as: 'total' });
|
||||||
|
} else {
|
||||||
|
void query.select(this.selectFields(options, ['id', 'name', 'updated_time'], 'items'));
|
||||||
|
}
|
||||||
|
|
||||||
if (pathQuery) {
|
if (pathQuery) {
|
||||||
// We support /* as a prefix only. Anywhere else would have
|
// We support /* as a prefix only. Anywhere else would have
|
||||||
// performance issue or requires a revert index.
|
// performance issue or requires a revert index.
|
||||||
|
@ -376,14 +381,14 @@ export default class ItemModel extends BaseModel<Item> {
|
||||||
|
|
||||||
public async children(userId: Uuid, pathQuery: string = '', pagination: Pagination = null, options: LoadOptions = {}): Promise<PaginatedItems> {
|
public async children(userId: Uuid, pathQuery: string = '', pagination: Pagination = null, options: LoadOptions = {}): Promise<PaginatedItems> {
|
||||||
pagination = pagination || defaultPagination();
|
pagination = pagination || defaultPagination();
|
||||||
const query = this.childrenQuery(userId, pathQuery, options);
|
const query = this.childrenQuery(userId, pathQuery, false, options);
|
||||||
return paginateDbQuery(query, pagination, 'items');
|
return paginateDbQuery(query, pagination, 'items');
|
||||||
}
|
}
|
||||||
|
|
||||||
public async childrenCount(userId: Uuid, pathQuery: string = ''): Promise<number> {
|
public async childrenCount(userId: Uuid, pathQuery: string = ''): Promise<number> {
|
||||||
const query = this.childrenQuery(userId, pathQuery);
|
const query = this.childrenQuery(userId, pathQuery, true);
|
||||||
const r = await query.countDistinct('items.id', { as: 'total' });
|
const r = await query.first();
|
||||||
return r[0].total;
|
return r ? r.total : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async joplinItemPath(jopId: string): Promise<Item[]> {
|
private async joplinItemPath(jopId: string): Promise<Item[]> {
|
||||||
|
|
|
@ -68,7 +68,7 @@ export async function beforeAllDb(unitName: string) {
|
||||||
|
|
||||||
// initConfig({
|
// initConfig({
|
||||||
// DB_CLIENT: 'pg',
|
// DB_CLIENT: 'pg',
|
||||||
// POSTGRES_DATABASE: createdDbPath_,
|
// POSTGRES_DATABASE: unitName,
|
||||||
// POSTGRES_USER: 'joplin',
|
// POSTGRES_USER: 'joplin',
|
||||||
// POSTGRES_PASSWORD: 'joplin',
|
// POSTGRES_PASSWORD: 'joplin',
|
||||||
// }, {
|
// }, {
|
||||||
|
|
Loading…
Reference in New Issue