mirror of
https://github.com/laurent22/joplin.git
synced 2024-11-24 08:12:24 +02:00
Server: Fixed Item and Log page when using Postgres
This commit is contained in:
parent
12a66342db
commit
ee0f23718b
@ -97,7 +97,10 @@ export default abstract class BaseModel<T> {
|
||||
}
|
||||
|
||||
if (mainTable) {
|
||||
output = output.map(f => `${mainTable}.${f}`);
|
||||
output = output.map(f => {
|
||||
if (f.includes(`${mainTable}.`)) return f;
|
||||
return `${mainTable}.${f}`;
|
||||
});
|
||||
}
|
||||
|
||||
return output;
|
||||
|
@ -68,7 +68,7 @@ export default class ChangeModel extends BaseModel<Change> {
|
||||
return results;
|
||||
}
|
||||
|
||||
private changesForUserQuery(userId: Uuid): Knex.QueryBuilder {
|
||||
private changesForUserQuery(userId: Uuid, count: boolean): Knex.QueryBuilder {
|
||||
// When need to get:
|
||||
//
|
||||
// - 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
|
||||
// to the item, not to a particular user.
|
||||
|
||||
return this
|
||||
const query = this
|
||||
.db('changes')
|
||||
.select([
|
||||
'id',
|
||||
'item_id',
|
||||
'item_name',
|
||||
'type',
|
||||
'updated_time',
|
||||
])
|
||||
.where(function() {
|
||||
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
|
||||
@ -96,6 +89,20 @@ export default class ChangeModel extends BaseModel<Change> {
|
||||
// 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]);
|
||||
});
|
||||
|
||||
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> {
|
||||
@ -106,9 +113,9 @@ export default class ChangeModel extends BaseModel<Change> {
|
||||
...pagination,
|
||||
};
|
||||
|
||||
const query = this.changesForUserQuery(userId);
|
||||
const countQuery = query.clone();
|
||||
const itemCount = (await countQuery.countDistinct('id', { as: 'total' }))[0].total;
|
||||
const query = this.changesForUserQuery(userId, false);
|
||||
const countQuery = this.changesForUserQuery(userId, true);
|
||||
const itemCount = (await countQuery.first()).total;
|
||||
|
||||
void query
|
||||
.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();
|
||||
}
|
||||
|
||||
const query = this.changesForUserQuery(userId);
|
||||
const query = this.changesForUserQuery(userId, false);
|
||||
|
||||
// If a cursor was provided, apply it to the query.
|
||||
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
|
||||
.db('user_items')
|
||||
.leftJoin('items', 'user_items.item_id', 'items.id')
|
||||
.select(this.selectFields(options, ['id', 'name', 'updated_time'], 'items'))
|
||||
.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) {
|
||||
// We support /* as a prefix only. Anywhere else would have
|
||||
// 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> {
|
||||
pagination = pagination || defaultPagination();
|
||||
const query = this.childrenQuery(userId, pathQuery, options);
|
||||
const query = this.childrenQuery(userId, pathQuery, false, options);
|
||||
return paginateDbQuery(query, pagination, 'items');
|
||||
}
|
||||
|
||||
public async childrenCount(userId: Uuid, pathQuery: string = ''): Promise<number> {
|
||||
const query = this.childrenQuery(userId, pathQuery);
|
||||
const r = await query.countDistinct('items.id', { as: 'total' });
|
||||
return r[0].total;
|
||||
const query = this.childrenQuery(userId, pathQuery, true);
|
||||
const r = await query.first();
|
||||
return r ? r.total : 0;
|
||||
}
|
||||
|
||||
private async joplinItemPath(jopId: string): Promise<Item[]> {
|
||||
|
@ -68,7 +68,7 @@ export async function beforeAllDb(unitName: string) {
|
||||
|
||||
// initConfig({
|
||||
// DB_CLIENT: 'pg',
|
||||
// POSTGRES_DATABASE: createdDbPath_,
|
||||
// POSTGRES_DATABASE: unitName,
|
||||
// POSTGRES_USER: 'joplin',
|
||||
// POSTGRES_PASSWORD: 'joplin',
|
||||
// }, {
|
||||
|
Loading…
Reference in New Issue
Block a user