fix(db-postgres): incorrect pagination totalDocs (#4248)
Co-authored-by: Alessio Gravili <alessio@bonfireleads.com>
This commit is contained in:
@@ -33,7 +33,7 @@ export const findMany = async function find({
|
|||||||
const db = adapter.sessions[req.transactionID]?.db || adapter.drizzle
|
const db = adapter.sessions[req.transactionID]?.db || adapter.drizzle
|
||||||
const table = adapter.tables[tableName]
|
const table = adapter.tables[tableName]
|
||||||
|
|
||||||
let limit = limitArg ?? 10
|
const limit = limitArg ?? 10
|
||||||
let totalDocs: number
|
let totalDocs: number
|
||||||
let totalPages: number
|
let totalPages: number
|
||||||
let hasPrevPage: boolean
|
let hasPrevPage: boolean
|
||||||
@@ -51,6 +51,7 @@ export const findMany = async function find({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const orderedIDMap: Record<number | string, number> = {}
|
const orderedIDMap: Record<number | string, number> = {}
|
||||||
|
let orderedIDs: (number | string)[]
|
||||||
|
|
||||||
const selectDistinctMethods: ChainedMethods = []
|
const selectDistinctMethods: ChainedMethods = []
|
||||||
|
|
||||||
@@ -116,7 +117,8 @@ export const findMany = async function find({
|
|||||||
selectDistinctResult.forEach(({ id }, i) => {
|
selectDistinctResult.forEach(({ id }, i) => {
|
||||||
orderedIDMap[id as number | string] = i
|
orderedIDMap[id as number | string] = i
|
||||||
})
|
})
|
||||||
findManyArgs.where = inArray(adapter.tables[tableName].id, Object.keys(orderedIDMap))
|
orderedIDs = Object.keys(orderedIDMap)
|
||||||
|
findManyArgs.where = inArray(adapter.tables[tableName].id, orderedIDs)
|
||||||
} else {
|
} else {
|
||||||
findManyArgs.limit = limitArg === 0 ? undefined : limitArg
|
findManyArgs.limit = limitArg === 0 ? undefined : limitArg
|
||||||
|
|
||||||
@@ -132,7 +134,7 @@ export const findMany = async function find({
|
|||||||
|
|
||||||
const findPromise = db.query[tableName].findMany(findManyArgs)
|
const findPromise = db.query[tableName].findMany(findManyArgs)
|
||||||
|
|
||||||
if (pagination !== false || selectDistinctResult?.length > limit) {
|
if (pagination !== false && (orderedIDs ? orderedIDs?.length >= limit : true)) {
|
||||||
const selectCountMethods: ChainedMethods = []
|
const selectCountMethods: ChainedMethods = []
|
||||||
|
|
||||||
joinAliases.forEach(({ condition, table }) => {
|
joinAliases.forEach(({ condition, table }) => {
|
||||||
@@ -174,9 +176,8 @@ export const findMany = async function find({
|
|||||||
rawDocs.sort((a, b) => orderedIDMap[a.id] - orderedIDMap[b.id])
|
rawDocs.sort((a, b) => orderedIDMap[a.id] - orderedIDMap[b.id])
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pagination === false) {
|
if (pagination === false || !totalDocs) {
|
||||||
totalDocs = rawDocs.length
|
totalDocs = rawDocs.length
|
||||||
limit = totalDocs
|
|
||||||
totalPages = 1
|
totalPages = 1
|
||||||
pagingCounter = 1
|
pagingCounter = 1
|
||||||
hasPrevPage = false
|
hasPrevPage = false
|
||||||
|
|||||||
@@ -199,6 +199,39 @@ export default buildConfigWithDefaults({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'movieReviewer',
|
||||||
|
relationTo: 'users',
|
||||||
|
required: true,
|
||||||
|
type: 'relationship',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'likes',
|
||||||
|
hasMany: true,
|
||||||
|
relationTo: 'users',
|
||||||
|
type: 'relationship',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'visibility',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: 'followers',
|
||||||
|
value: 'followers',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'public',
|
||||||
|
value: 'public',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
required: true,
|
||||||
|
type: 'radio',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
slug: 'movieReviews',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
onInit: async (payload) => {
|
onInit: async (payload) => {
|
||||||
await payload.create({
|
await payload.create({
|
||||||
|
|||||||
@@ -185,6 +185,73 @@ describe('Relationships', () => {
|
|||||||
expect(status).toEqual(400)
|
expect(status).toEqual(400)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should count totalDocs correctly when using or in where query and relation contains hasMany relationship fields', async () => {
|
||||||
|
const user = (
|
||||||
|
await payload.find({
|
||||||
|
collection: 'users',
|
||||||
|
})
|
||||||
|
).docs[0]
|
||||||
|
|
||||||
|
const user2 = await payload.create({
|
||||||
|
collection: 'users',
|
||||||
|
data: {
|
||||||
|
email: '1@test.com',
|
||||||
|
password: 'fwefe',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const user3 = await payload.create({
|
||||||
|
collection: 'users',
|
||||||
|
data: {
|
||||||
|
email: '2@test.com',
|
||||||
|
password: 'fwsefe',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const user4 = await payload.create({
|
||||||
|
collection: 'users',
|
||||||
|
data: {
|
||||||
|
email: '3@test.com',
|
||||||
|
password: 'fwddsefe',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
await Promise.all([
|
||||||
|
payload.create({
|
||||||
|
collection: 'movieReviews',
|
||||||
|
data: {
|
||||||
|
likes: [user3.id, user2.id, user.id, user4.id],
|
||||||
|
movieReviewer: user.id,
|
||||||
|
visibility: 'public',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
payload.create({
|
||||||
|
collection: 'movieReviews',
|
||||||
|
data: {
|
||||||
|
movieReviewer: user2.id,
|
||||||
|
visibility: 'public',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
|
||||||
|
const query = await payload.find({
|
||||||
|
collection: 'movieReviews',
|
||||||
|
depth: 1,
|
||||||
|
where: {
|
||||||
|
or: [
|
||||||
|
{
|
||||||
|
visibility: {
|
||||||
|
equals: 'public',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
movieReviewer: {
|
||||||
|
equals: user.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
expect(query.totalDocs).toEqual(2)
|
||||||
|
})
|
||||||
|
|
||||||
describe('Custom ID', () => {
|
describe('Custom ID', () => {
|
||||||
it('should query a custom id relation', async () => {
|
it('should query a custom id relation', async () => {
|
||||||
const { doc } = await client.findByID<Post>({ id: post.id })
|
const { doc } = await client.findByID<Post>({ id: post.id })
|
||||||
|
|||||||
Reference in New Issue
Block a user