@@ -190,65 +190,123 @@ module.exports.insertData = async (req, res) => {
190190} ;
191191
192192// GET ALL DATA
193- const getAllData = async ( req , res ) => {
194- try {
195- const { collectionName } = req . params ;
196- const { project, rlsFilter, query } = req ;
197-
198- const model = await getCompiledModel ( project , collectionName ) ;
199-
200- // Create QueryEngine instance with the query
201- const engine = new QueryEngine ( query ) ;
202-
203- // Apply filters
204- let result = engine . filter ( ) ;
205- result = result . sort ( ) ;
206-
207- // Apply populate if provided in query
208- if ( query . populate ) {
209- const populateFields = Array . isArray ( query . populate )
210- ? query . populate
211- : query . populate . split ( ',' ) . map ( p => p . trim ( ) ) ;
212-
213- populateFields . forEach ( field => {
214- result = result . populate ( field ) ;
215- } ) ;
216- }
217-
218- result = result . paginate ( ) ;
219-
220- // Get the MongoDB query and apply RLS filter
221- const mongoQuery = model . find ( ) ;
222- if ( Object . keys ( rlsFilter ) . length > 0 ) {
223- mongoQuery . and ( [ rlsFilter ] ) ;
224- }
225-
226- const docs = await mongoQuery . lean ( ) ;
227- const count = await engine . count ( ) ;
228-
229- return res . status ( 200 ) . json ( {
230- success : true ,
231- data : docs ,
232- count,
233- } ) ;
234- } catch ( error ) {
235- // Handle QueryEngine validation errors with statusCode
236- if ( error . statusCode && error . statusCode === 400 ) {
237- return res . status ( 400 ) . json ( {
238- success : false ,
239- data : { } ,
240- message : error . message ,
241- } ) ;
193+ module . exports . getAllData = async ( req , res ) => {
194+ try {
195+ let start ;
196+ if ( isDebug ) start = performance . now ( ) ;
197+ const { collectionName } = req . params ;
198+ const project = req . project ;
199+
200+ const collectionConfig = project . collections . find (
201+ ( c ) => c . name === collectionName ,
202+ ) ;
203+ if ( ! collectionConfig )
204+ return res . status ( 404 ) . json ( { error : "Collection not found" } ) ;
205+
206+ const connection = await getConnection ( project . _id ) ;
207+ const Model = getCompiledModel (
208+ connection ,
209+ collectionConfig ,
210+ project . _id ,
211+ project . resources . db . isExternal ,
212+ ) ;
213+
214+ const baseFilter = req . rlsFilter && typeof req . rlsFilter === 'object' ? req . rlsFilter : { } ;
215+
216+ if ( req . query . count === 'true' ) {
217+ const countEngine = new QueryEngine ( Model . find ( ) , req . query ) ;
218+ const mongoFilter = countEngine . _buildMongoQuery ( true ) ;
219+ const mergedFilter = Object . keys ( baseFilter ) . length > 0
220+ ? { $and : [ mongoFilter , baseFilter ] }
221+ : mongoFilter ;
222+
223+ const countQuery = Model . countDocuments ( mergedFilter ) ;
224+
225+ if ( countEngine . hasRegexFilter && countQuery && typeof countQuery . maxTimeMS === 'function' ) {
226+ countQuery . maxTimeMS ( QueryEngine . REGEX_MAX_TIME_MS ) ;
227+ }
228+
229+ const count = await countQuery ;
230+
231+ return res . status ( 200 ) . json ( {
232+ success : true ,
233+ data : { count } ,
234+ message : "Count fetched successfully." ,
235+ } ) ;
236+ }
237+
238+ const features = new QueryEngine ( Model . find ( ) , req . query ) . filter ( ) ;
239+
240+ if ( Object . keys ( baseFilter ) . length > 0 ) {
241+ features . query = features . query . and ( [ baseFilter ] ) ;
242+ }
243+
244+ features . sort ( ) . limitFields ( ) . populate ( ) ;
245+
246+ const total = await features . count ( ) ;
247+
248+ // Use cursor-based pagination if cursor parameter is provided, otherwise use offset-based
249+ const useCursor = ! ! req . query . cursor ;
250+ if ( useCursor ) {
251+ features . cursorPaginate ( ) ;
252+ } else {
253+ features . paginate ( ) ;
254+ }
255+
256+ const data = await features . query . lean ( ) ;
257+
258+ // Handle cursor pagination: slice to actual limit and generate next cursor
259+ let items = data ;
260+ let nextCursor = null ;
261+ if ( useCursor ) {
262+ const limit = Math . min ( parseInt ( req . query . limit , 10 ) || 100 , 100 ) ;
263+ features . generateNextCursor ( data , limit ) ;
264+ items = data . slice ( 0 , limit ) ;
265+ nextCursor = features . nextCursor ;
266+ }
267+
268+ if ( isDebug ) console . log ( `[DEBUG] getall took ${ ( performance . now ( ) - start ) . toFixed ( 2 ) } ms` ) ;
269+
270+ const responseMeta = useCursor
271+ ? {
272+ total,
273+ cursor : req . query . cursor || null ,
274+ nextCursor,
275+ limit : Math . max ( 1 , Math . min ( parseInt ( req . query . limit , 10 ) || 100 , 100 ) ) ,
242276 }
243-
244- // Handle other errors
245- console . error ( 'getAllData error:' , error ) ;
246- return res . status ( 500 ) . json ( {
247- success : false ,
248- data : { } ,
249- message : 'Internal server error' ,
250- } ) ;
277+ : {
278+ total,
279+ page : parseInt ( req . query . page , 10 ) || 1 ,
280+ limit : Math . max ( 1 , Math . min ( parseInt ( req . query . limit , 10 ) || 100 , 100 ) ) ,
281+ } ;
282+
283+ res . json ( {
284+ success : true ,
285+ data : {
286+ items,
287+ ...responseMeta ,
288+ } ,
289+ message : "Data fetched successfully" ,
290+ } ) ;
291+ } catch ( err ) {
292+ if ( process . env . NODE_ENV !== 'test' ) {
293+ console . error ( err ) ;
251294 }
295+
296+ if ( err && ( err . statusCode === 400 || err . name === 'QueryFilterError' ) ) {
297+ return res . status ( 400 ) . json ( {
298+ success : false ,
299+ data : { } ,
300+ message : err . message || "Invalid query filter." ,
301+ } ) ;
302+ }
303+
304+ res . status ( 500 ) . json ( {
305+ success : false ,
306+ data : { } ,
307+ message : "Failed to fetch data." ,
308+ } ) ;
309+ }
252310} ;
253311
254312// GET SINGLE DOC
0 commit comments