diff --git a/storage/framework/core/orm/src/generate.ts b/storage/framework/core/orm/src/generate.ts index f9a991c6f..de31632f0 100644 --- a/storage/framework/core/orm/src/generate.ts +++ b/storage/framework/core/orm/src/generate.ts @@ -1186,11 +1186,27 @@ export async function generateModelString( return result.count || 0 } + static async max(field: keyof ${modelName}Model): Promise { + const instance = new ${modelName}Model(null) + + return await instance.selectFromQuery + .select(sql\`MAX(\${sql.raw(field as string)}) \`) + .executeTakeFirst() + } + async max(field: keyof ${modelName}Model): Promise { return await this.selectFromQuery .select(sql\`MAX(\${sql.raw(field as string)}) \`) .executeTakeFirst() } + + static async min(field: keyof ${modelName}Model): Promise { + const instance = new ${modelName}Model(null) + + return await instance.selectFromQuery + .select(sql\`MIN(\${sql.raw(field as string)}) \`) + .executeTakeFirst() + } async min(field: keyof ${modelName}Model): Promise { return await this.selectFromQuery @@ -1198,12 +1214,28 @@ export async function generateModelString( .executeTakeFirst() } + static async avg(field: keyof ${modelName}Model): Promise { + const instance = new ${modelName}Model(null) + + return instance.selectFromQuery + .select(sql\`AVG(\${sql.raw(field as string)})\`) + .executeTakeFirst() + } + async avg(field: keyof ${modelName}Model): Promise { return this.selectFromQuery .select(sql\`AVG(\${sql.raw(field as string)})\`) .executeTakeFirst() } + static async sum(field: keyof ${modelName}Model): Promise { + const instance = new ${modelName}Model(null) + + return instance.selectFromQuery + .select(sql\`SUM(\${sql.raw(field as string)})\`) + .executeTakeFirst() + } + async sum(field: keyof ${modelName}Model): Promise { return this.selectFromQuery .select(sql\`SUM(\${sql.raw(field as string)})\`) diff --git a/storage/framework/orm/src/models/AccessToken.ts b/storage/framework/orm/src/models/AccessToken.ts index e26617a8e..302de4ee7 100644 --- a/storage/framework/orm/src/models/AccessToken.ts +++ b/storage/framework/orm/src/models/AccessToken.ts @@ -413,24 +413,56 @@ export class AccessTokenModel { return result.count || 0 } + static async max(field: keyof AccessTokenModel): Promise { + const instance = new AccessTokenModel(null) + + return await instance.selectFromQuery + .select(sql`MAX(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async max(field: keyof AccessTokenModel): Promise { return await this.selectFromQuery .select(sql`MAX(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async min(field: keyof AccessTokenModel): Promise { + const instance = new AccessTokenModel(null) + + return await instance.selectFromQuery + .select(sql`MIN(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async min(field: keyof AccessTokenModel): Promise { return await this.selectFromQuery .select(sql`MIN(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async avg(field: keyof AccessTokenModel): Promise { + const instance = new AccessTokenModel(null) + + return instance.selectFromQuery + .select(sql`AVG(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async avg(field: keyof AccessTokenModel): Promise { return this.selectFromQuery .select(sql`AVG(${sql.raw(field as string)})`) .executeTakeFirst() } + static async sum(field: keyof AccessTokenModel): Promise { + const instance = new AccessTokenModel(null) + + return instance.selectFromQuery + .select(sql`SUM(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async sum(field: keyof AccessTokenModel): Promise { return this.selectFromQuery .select(sql`SUM(${sql.raw(field as string)})`) diff --git a/storage/framework/orm/src/models/Activity.ts b/storage/framework/orm/src/models/Activity.ts index 8ecf888ce..10fc44de7 100644 --- a/storage/framework/orm/src/models/Activity.ts +++ b/storage/framework/orm/src/models/Activity.ts @@ -432,24 +432,56 @@ export class ActivityModel { return result.count || 0 } + static async max(field: keyof ActivityModel): Promise { + const instance = new ActivityModel(null) + + return await instance.selectFromQuery + .select(sql`MAX(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async max(field: keyof ActivityModel): Promise { return await this.selectFromQuery .select(sql`MAX(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async min(field: keyof ActivityModel): Promise { + const instance = new ActivityModel(null) + + return await instance.selectFromQuery + .select(sql`MIN(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async min(field: keyof ActivityModel): Promise { return await this.selectFromQuery .select(sql`MIN(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async avg(field: keyof ActivityModel): Promise { + const instance = new ActivityModel(null) + + return instance.selectFromQuery + .select(sql`AVG(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async avg(field: keyof ActivityModel): Promise { return this.selectFromQuery .select(sql`AVG(${sql.raw(field as string)})`) .executeTakeFirst() } + static async sum(field: keyof ActivityModel): Promise { + const instance = new ActivityModel(null) + + return instance.selectFromQuery + .select(sql`SUM(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async sum(field: keyof ActivityModel): Promise { return this.selectFromQuery .select(sql`SUM(${sql.raw(field as string)})`) diff --git a/storage/framework/orm/src/models/Deployment.ts b/storage/framework/orm/src/models/Deployment.ts index 42ef611d0..95654a2b0 100644 --- a/storage/framework/orm/src/models/Deployment.ts +++ b/storage/framework/orm/src/models/Deployment.ts @@ -450,24 +450,56 @@ export class DeploymentModel { return result.count || 0 } + static async max(field: keyof DeploymentModel): Promise { + const instance = new DeploymentModel(null) + + return await instance.selectFromQuery + .select(sql`MAX(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async max(field: keyof DeploymentModel): Promise { return await this.selectFromQuery .select(sql`MAX(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async min(field: keyof DeploymentModel): Promise { + const instance = new DeploymentModel(null) + + return await instance.selectFromQuery + .select(sql`MIN(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async min(field: keyof DeploymentModel): Promise { return await this.selectFromQuery .select(sql`MIN(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async avg(field: keyof DeploymentModel): Promise { + const instance = new DeploymentModel(null) + + return instance.selectFromQuery + .select(sql`AVG(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async avg(field: keyof DeploymentModel): Promise { return this.selectFromQuery .select(sql`AVG(${sql.raw(field as string)})`) .executeTakeFirst() } + static async sum(field: keyof DeploymentModel): Promise { + const instance = new DeploymentModel(null) + + return instance.selectFromQuery + .select(sql`SUM(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async sum(field: keyof DeploymentModel): Promise { return this.selectFromQuery .select(sql`SUM(${sql.raw(field as string)})`) diff --git a/storage/framework/orm/src/models/Error.ts b/storage/framework/orm/src/models/Error.ts index f1006cae9..917724840 100644 --- a/storage/framework/orm/src/models/Error.ts +++ b/storage/framework/orm/src/models/Error.ts @@ -405,24 +405,56 @@ export class ErrorModel { return result.count || 0 } + static async max(field: keyof ErrorModel): Promise { + const instance = new ErrorModel(null) + + return await instance.selectFromQuery + .select(sql`MAX(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async max(field: keyof ErrorModel): Promise { return await this.selectFromQuery .select(sql`MAX(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async min(field: keyof ErrorModel): Promise { + const instance = new ErrorModel(null) + + return await instance.selectFromQuery + .select(sql`MIN(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async min(field: keyof ErrorModel): Promise { return await this.selectFromQuery .select(sql`MIN(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async avg(field: keyof ErrorModel): Promise { + const instance = new ErrorModel(null) + + return instance.selectFromQuery + .select(sql`AVG(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async avg(field: keyof ErrorModel): Promise { return this.selectFromQuery .select(sql`AVG(${sql.raw(field as string)})`) .executeTakeFirst() } + static async sum(field: keyof ErrorModel): Promise { + const instance = new ErrorModel(null) + + return instance.selectFromQuery + .select(sql`SUM(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async sum(field: keyof ErrorModel): Promise { return this.selectFromQuery .select(sql`SUM(${sql.raw(field as string)})`) diff --git a/storage/framework/orm/src/models/FailedJob.ts b/storage/framework/orm/src/models/FailedJob.ts index 012da4655..15ed876a8 100644 --- a/storage/framework/orm/src/models/FailedJob.ts +++ b/storage/framework/orm/src/models/FailedJob.ts @@ -405,24 +405,56 @@ export class FailedJobModel { return result.count || 0 } + static async max(field: keyof FailedJobModel): Promise { + const instance = new FailedJobModel(null) + + return await instance.selectFromQuery + .select(sql`MAX(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async max(field: keyof FailedJobModel): Promise { return await this.selectFromQuery .select(sql`MAX(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async min(field: keyof FailedJobModel): Promise { + const instance = new FailedJobModel(null) + + return await instance.selectFromQuery + .select(sql`MIN(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async min(field: keyof FailedJobModel): Promise { return await this.selectFromQuery .select(sql`MIN(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async avg(field: keyof FailedJobModel): Promise { + const instance = new FailedJobModel(null) + + return instance.selectFromQuery + .select(sql`AVG(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async avg(field: keyof FailedJobModel): Promise { return this.selectFromQuery .select(sql`AVG(${sql.raw(field as string)})`) .executeTakeFirst() } + static async sum(field: keyof FailedJobModel): Promise { + const instance = new FailedJobModel(null) + + return instance.selectFromQuery + .select(sql`SUM(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async sum(field: keyof FailedJobModel): Promise { return this.selectFromQuery .select(sql`SUM(${sql.raw(field as string)})`) diff --git a/storage/framework/orm/src/models/Job.ts b/storage/framework/orm/src/models/Job.ts index b8c0cd3ed..e41a2e0e4 100644 --- a/storage/framework/orm/src/models/Job.ts +++ b/storage/framework/orm/src/models/Job.ts @@ -405,24 +405,56 @@ export class JobModel { return result.count || 0 } + static async max(field: keyof JobModel): Promise { + const instance = new JobModel(null) + + return await instance.selectFromQuery + .select(sql`MAX(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async max(field: keyof JobModel): Promise { return await this.selectFromQuery .select(sql`MAX(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async min(field: keyof JobModel): Promise { + const instance = new JobModel(null) + + return await instance.selectFromQuery + .select(sql`MIN(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async min(field: keyof JobModel): Promise { return await this.selectFromQuery .select(sql`MIN(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async avg(field: keyof JobModel): Promise { + const instance = new JobModel(null) + + return instance.selectFromQuery + .select(sql`AVG(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async avg(field: keyof JobModel): Promise { return this.selectFromQuery .select(sql`AVG(${sql.raw(field as string)})`) .executeTakeFirst() } + static async sum(field: keyof JobModel): Promise { + const instance = new JobModel(null) + + return instance.selectFromQuery + .select(sql`SUM(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async sum(field: keyof JobModel): Promise { return this.selectFromQuery .select(sql`SUM(${sql.raw(field as string)})`) diff --git a/storage/framework/orm/src/models/PaymentMethod.ts b/storage/framework/orm/src/models/PaymentMethod.ts index 84643d655..518b74832 100644 --- a/storage/framework/orm/src/models/PaymentMethod.ts +++ b/storage/framework/orm/src/models/PaymentMethod.ts @@ -463,24 +463,56 @@ export class PaymentMethodModel { return result.count || 0 } + static async max(field: keyof PaymentMethodModel): Promise { + const instance = new PaymentMethodModel(null) + + return await instance.selectFromQuery + .select(sql`MAX(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async max(field: keyof PaymentMethodModel): Promise { return await this.selectFromQuery .select(sql`MAX(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async min(field: keyof PaymentMethodModel): Promise { + const instance = new PaymentMethodModel(null) + + return await instance.selectFromQuery + .select(sql`MIN(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async min(field: keyof PaymentMethodModel): Promise { return await this.selectFromQuery .select(sql`MIN(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async avg(field: keyof PaymentMethodModel): Promise { + const instance = new PaymentMethodModel(null) + + return instance.selectFromQuery + .select(sql`AVG(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async avg(field: keyof PaymentMethodModel): Promise { return this.selectFromQuery .select(sql`AVG(${sql.raw(field as string)})`) .executeTakeFirst() } + static async sum(field: keyof PaymentMethodModel): Promise { + const instance = new PaymentMethodModel(null) + + return instance.selectFromQuery + .select(sql`SUM(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async sum(field: keyof PaymentMethodModel): Promise { return this.selectFromQuery .select(sql`SUM(${sql.raw(field as string)})`) diff --git a/storage/framework/orm/src/models/Post.ts b/storage/framework/orm/src/models/Post.ts index 998531716..dad3cd3dc 100644 --- a/storage/framework/orm/src/models/Post.ts +++ b/storage/framework/orm/src/models/Post.ts @@ -395,24 +395,56 @@ export class PostModel { return result.count || 0 } + static async max(field: keyof PostModel): Promise { + const instance = new PostModel(null) + + return await instance.selectFromQuery + .select(sql`MAX(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async max(field: keyof PostModel): Promise { return await this.selectFromQuery .select(sql`MAX(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async min(field: keyof PostModel): Promise { + const instance = new PostModel(null) + + return await instance.selectFromQuery + .select(sql`MIN(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async min(field: keyof PostModel): Promise { return await this.selectFromQuery .select(sql`MIN(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async avg(field: keyof PostModel): Promise { + const instance = new PostModel(null) + + return instance.selectFromQuery + .select(sql`AVG(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async avg(field: keyof PostModel): Promise { return this.selectFromQuery .select(sql`AVG(${sql.raw(field as string)})`) .executeTakeFirst() } + static async sum(field: keyof PostModel): Promise { + const instance = new PostModel(null) + + return instance.selectFromQuery + .select(sql`SUM(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async sum(field: keyof PostModel): Promise { return this.selectFromQuery .select(sql`SUM(${sql.raw(field as string)})`) diff --git a/storage/framework/orm/src/models/Product.ts b/storage/framework/orm/src/models/Product.ts index e3f6bdbbc..ab81a49e5 100644 --- a/storage/framework/orm/src/models/Product.ts +++ b/storage/framework/orm/src/models/Product.ts @@ -433,24 +433,56 @@ export class ProductModel { return result.count || 0 } + static async max(field: keyof ProductModel): Promise { + const instance = new ProductModel(null) + + return await instance.selectFromQuery + .select(sql`MAX(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async max(field: keyof ProductModel): Promise { return await this.selectFromQuery .select(sql`MAX(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async min(field: keyof ProductModel): Promise { + const instance = new ProductModel(null) + + return await instance.selectFromQuery + .select(sql`MIN(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async min(field: keyof ProductModel): Promise { return await this.selectFromQuery .select(sql`MIN(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async avg(field: keyof ProductModel): Promise { + const instance = new ProductModel(null) + + return instance.selectFromQuery + .select(sql`AVG(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async avg(field: keyof ProductModel): Promise { return this.selectFromQuery .select(sql`AVG(${sql.raw(field as string)})`) .executeTakeFirst() } + static async sum(field: keyof ProductModel): Promise { + const instance = new ProductModel(null) + + return instance.selectFromQuery + .select(sql`SUM(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async sum(field: keyof ProductModel): Promise { return this.selectFromQuery .select(sql`SUM(${sql.raw(field as string)})`) diff --git a/storage/framework/orm/src/models/Project.ts b/storage/framework/orm/src/models/Project.ts index 05358ab0e..3db8ba04e 100644 --- a/storage/framework/orm/src/models/Project.ts +++ b/storage/framework/orm/src/models/Project.ts @@ -396,24 +396,56 @@ export class ProjectModel { return result.count || 0 } + static async max(field: keyof ProjectModel): Promise { + const instance = new ProjectModel(null) + + return await instance.selectFromQuery + .select(sql`MAX(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async max(field: keyof ProjectModel): Promise { return await this.selectFromQuery .select(sql`MAX(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async min(field: keyof ProjectModel): Promise { + const instance = new ProjectModel(null) + + return await instance.selectFromQuery + .select(sql`MIN(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async min(field: keyof ProjectModel): Promise { return await this.selectFromQuery .select(sql`MIN(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async avg(field: keyof ProjectModel): Promise { + const instance = new ProjectModel(null) + + return instance.selectFromQuery + .select(sql`AVG(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async avg(field: keyof ProjectModel): Promise { return this.selectFromQuery .select(sql`AVG(${sql.raw(field as string)})`) .executeTakeFirst() } + static async sum(field: keyof ProjectModel): Promise { + const instance = new ProjectModel(null) + + return instance.selectFromQuery + .select(sql`SUM(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async sum(field: keyof ProjectModel): Promise { return this.selectFromQuery .select(sql`SUM(${sql.raw(field as string)})`) diff --git a/storage/framework/orm/src/models/Release.ts b/storage/framework/orm/src/models/Release.ts index 117590f73..007f9e490 100644 --- a/storage/framework/orm/src/models/Release.ts +++ b/storage/framework/orm/src/models/Release.ts @@ -369,24 +369,56 @@ export class ReleaseModel { return result.count || 0 } + static async max(field: keyof ReleaseModel): Promise { + const instance = new ReleaseModel(null) + + return await instance.selectFromQuery + .select(sql`MAX(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async max(field: keyof ReleaseModel): Promise { return await this.selectFromQuery .select(sql`MAX(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async min(field: keyof ReleaseModel): Promise { + const instance = new ReleaseModel(null) + + return await instance.selectFromQuery + .select(sql`MIN(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async min(field: keyof ReleaseModel): Promise { return await this.selectFromQuery .select(sql`MIN(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async avg(field: keyof ReleaseModel): Promise { + const instance = new ReleaseModel(null) + + return instance.selectFromQuery + .select(sql`AVG(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async avg(field: keyof ReleaseModel): Promise { return this.selectFromQuery .select(sql`AVG(${sql.raw(field as string)})`) .executeTakeFirst() } + static async sum(field: keyof ReleaseModel): Promise { + const instance = new ReleaseModel(null) + + return instance.selectFromQuery + .select(sql`SUM(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async sum(field: keyof ReleaseModel): Promise { return this.selectFromQuery .select(sql`SUM(${sql.raw(field as string)})`) diff --git a/storage/framework/orm/src/models/Subscriber.ts b/storage/framework/orm/src/models/Subscriber.ts index b41a840e2..5679e02b3 100644 --- a/storage/framework/orm/src/models/Subscriber.ts +++ b/storage/framework/orm/src/models/Subscriber.ts @@ -369,24 +369,56 @@ export class SubscriberModel { return result.count || 0 } + static async max(field: keyof SubscriberModel): Promise { + const instance = new SubscriberModel(null) + + return await instance.selectFromQuery + .select(sql`MAX(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async max(field: keyof SubscriberModel): Promise { return await this.selectFromQuery .select(sql`MAX(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async min(field: keyof SubscriberModel): Promise { + const instance = new SubscriberModel(null) + + return await instance.selectFromQuery + .select(sql`MIN(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async min(field: keyof SubscriberModel): Promise { return await this.selectFromQuery .select(sql`MIN(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async avg(field: keyof SubscriberModel): Promise { + const instance = new SubscriberModel(null) + + return instance.selectFromQuery + .select(sql`AVG(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async avg(field: keyof SubscriberModel): Promise { return this.selectFromQuery .select(sql`AVG(${sql.raw(field as string)})`) .executeTakeFirst() } + static async sum(field: keyof SubscriberModel): Promise { + const instance = new SubscriberModel(null) + + return instance.selectFromQuery + .select(sql`SUM(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async sum(field: keyof SubscriberModel): Promise { return this.selectFromQuery .select(sql`SUM(${sql.raw(field as string)})`) diff --git a/storage/framework/orm/src/models/SubscriberEmail.ts b/storage/framework/orm/src/models/SubscriberEmail.ts index 6c59025d0..6b2dcf8bf 100644 --- a/storage/framework/orm/src/models/SubscriberEmail.ts +++ b/storage/framework/orm/src/models/SubscriberEmail.ts @@ -387,24 +387,56 @@ export class SubscriberEmailModel { return result.count || 0 } + static async max(field: keyof SubscriberEmailModel): Promise { + const instance = new SubscriberEmailModel(null) + + return await instance.selectFromQuery + .select(sql`MAX(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async max(field: keyof SubscriberEmailModel): Promise { return await this.selectFromQuery .select(sql`MAX(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async min(field: keyof SubscriberEmailModel): Promise { + const instance = new SubscriberEmailModel(null) + + return await instance.selectFromQuery + .select(sql`MIN(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async min(field: keyof SubscriberEmailModel): Promise { return await this.selectFromQuery .select(sql`MIN(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async avg(field: keyof SubscriberEmailModel): Promise { + const instance = new SubscriberEmailModel(null) + + return instance.selectFromQuery + .select(sql`AVG(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async avg(field: keyof SubscriberEmailModel): Promise { return this.selectFromQuery .select(sql`AVG(${sql.raw(field as string)})`) .executeTakeFirst() } + static async sum(field: keyof SubscriberEmailModel): Promise { + const instance = new SubscriberEmailModel(null) + + return instance.selectFromQuery + .select(sql`SUM(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async sum(field: keyof SubscriberEmailModel): Promise { return this.selectFromQuery .select(sql`SUM(${sql.raw(field as string)})`) diff --git a/storage/framework/orm/src/models/Subscription.ts b/storage/framework/orm/src/models/Subscription.ts index 0fca338d4..4a7868875 100644 --- a/storage/framework/orm/src/models/Subscription.ts +++ b/storage/framework/orm/src/models/Subscription.ts @@ -477,24 +477,56 @@ export class SubscriptionModel { return result.count || 0 } + static async max(field: keyof SubscriptionModel): Promise { + const instance = new SubscriptionModel(null) + + return await instance.selectFromQuery + .select(sql`MAX(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async max(field: keyof SubscriptionModel): Promise { return await this.selectFromQuery .select(sql`MAX(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async min(field: keyof SubscriptionModel): Promise { + const instance = new SubscriptionModel(null) + + return await instance.selectFromQuery + .select(sql`MIN(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async min(field: keyof SubscriptionModel): Promise { return await this.selectFromQuery .select(sql`MIN(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async avg(field: keyof SubscriptionModel): Promise { + const instance = new SubscriptionModel(null) + + return instance.selectFromQuery + .select(sql`AVG(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async avg(field: keyof SubscriptionModel): Promise { return this.selectFromQuery .select(sql`AVG(${sql.raw(field as string)})`) .executeTakeFirst() } + static async sum(field: keyof SubscriptionModel): Promise { + const instance = new SubscriptionModel(null) + + return instance.selectFromQuery + .select(sql`SUM(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async sum(field: keyof SubscriptionModel): Promise { return this.selectFromQuery .select(sql`SUM(${sql.raw(field as string)})`) diff --git a/storage/framework/orm/src/models/Team.ts b/storage/framework/orm/src/models/Team.ts index 2d9a05ada..1ed33575d 100644 --- a/storage/framework/orm/src/models/Team.ts +++ b/storage/framework/orm/src/models/Team.ts @@ -446,24 +446,56 @@ export class TeamModel { return result.count || 0 } + static async max(field: keyof TeamModel): Promise { + const instance = new TeamModel(null) + + return await instance.selectFromQuery + .select(sql`MAX(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async max(field: keyof TeamModel): Promise { return await this.selectFromQuery .select(sql`MAX(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async min(field: keyof TeamModel): Promise { + const instance = new TeamModel(null) + + return await instance.selectFromQuery + .select(sql`MIN(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async min(field: keyof TeamModel): Promise { return await this.selectFromQuery .select(sql`MIN(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async avg(field: keyof TeamModel): Promise { + const instance = new TeamModel(null) + + return instance.selectFromQuery + .select(sql`AVG(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async avg(field: keyof TeamModel): Promise { return this.selectFromQuery .select(sql`AVG(${sql.raw(field as string)})`) .executeTakeFirst() } + static async sum(field: keyof TeamModel): Promise { + const instance = new TeamModel(null) + + return instance.selectFromQuery + .select(sql`SUM(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async sum(field: keyof TeamModel): Promise { return this.selectFromQuery .select(sql`SUM(${sql.raw(field as string)})`) diff --git a/storage/framework/orm/src/models/Transaction.ts b/storage/framework/orm/src/models/Transaction.ts index ff30393d5..1a11eabed 100644 --- a/storage/framework/orm/src/models/Transaction.ts +++ b/storage/framework/orm/src/models/Transaction.ts @@ -450,24 +450,56 @@ export class TransactionModel { return result.count || 0 } + static async max(field: keyof TransactionModel): Promise { + const instance = new TransactionModel(null) + + return await instance.selectFromQuery + .select(sql`MAX(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async max(field: keyof TransactionModel): Promise { return await this.selectFromQuery .select(sql`MAX(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async min(field: keyof TransactionModel): Promise { + const instance = new TransactionModel(null) + + return await instance.selectFromQuery + .select(sql`MIN(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async min(field: keyof TransactionModel): Promise { return await this.selectFromQuery .select(sql`MIN(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async avg(field: keyof TransactionModel): Promise { + const instance = new TransactionModel(null) + + return instance.selectFromQuery + .select(sql`AVG(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async avg(field: keyof TransactionModel): Promise { return this.selectFromQuery .select(sql`AVG(${sql.raw(field as string)})`) .executeTakeFirst() } + static async sum(field: keyof TransactionModel): Promise { + const instance = new TransactionModel(null) + + return instance.selectFromQuery + .select(sql`SUM(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async sum(field: keyof TransactionModel): Promise { return this.selectFromQuery .select(sql`SUM(${sql.raw(field as string)})`) diff --git a/storage/framework/orm/src/models/User.ts b/storage/framework/orm/src/models/User.ts index 295688049..153e92a93 100644 --- a/storage/framework/orm/src/models/User.ts +++ b/storage/framework/orm/src/models/User.ts @@ -483,24 +483,56 @@ export class UserModel { return result.count || 0 } + static async max(field: keyof UserModel): Promise { + const instance = new UserModel(null) + + return await instance.selectFromQuery + .select(sql`MAX(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async max(field: keyof UserModel): Promise { return await this.selectFromQuery .select(sql`MAX(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async min(field: keyof UserModel): Promise { + const instance = new UserModel(null) + + return await instance.selectFromQuery + .select(sql`MIN(${sql.raw(field as string)}) `) + .executeTakeFirst() + } + async min(field: keyof UserModel): Promise { return await this.selectFromQuery .select(sql`MIN(${sql.raw(field as string)}) `) .executeTakeFirst() } + static async avg(field: keyof UserModel): Promise { + const instance = new UserModel(null) + + return instance.selectFromQuery + .select(sql`AVG(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async avg(field: keyof UserModel): Promise { return this.selectFromQuery .select(sql`AVG(${sql.raw(field as string)})`) .executeTakeFirst() } + static async sum(field: keyof UserModel): Promise { + const instance = new UserModel(null) + + return instance.selectFromQuery + .select(sql`SUM(${sql.raw(field as string)})`) + .executeTakeFirst() + } + async sum(field: keyof UserModel): Promise { return this.selectFromQuery .select(sql`SUM(${sql.raw(field as string)})`) diff --git a/storage/framework/orm/src/tests/Models.test.ts b/storage/framework/orm/src/tests/Models.test.ts index 1c83c32bb..d0c5d8ed0 100644 --- a/storage/framework/orm/src/tests/Models.test.ts +++ b/storage/framework/orm/src/tests/Models.test.ts @@ -7,577 +7,799 @@ beforeEach(async () => { }) describe('Models test', () => { - it('should fetch a single record in models', async () => { - const user = { - name: 'Chris Breuer', - job_title: 'Open Sourceror', - email: 'chris@stacksjs.org', - password: '123456', - } - - const result = await User.create(user) + // it('should fetch a single record in models', async () => { + // const user = { + // name: 'Chris Breuer', + // job_title: 'Open Sourceror', + // email: 'chris@stacksjs.org', + // password: '123456', + // } - const model = await User.find(result.id as number) + // const result = await User.create(user) - expect(model?.email).toBe(user.email) - }) + // const model = await User.find(result.id as number) - it('should store records in models', async () => { - const user = { - name: 'Chris Breuer', - job_title: 'Open Sourceror', - email: 'chris@stacksjs.org', - password: '123456', - } + // expect(model?.email).toBe(user.email) + // }) - const result = await User.create(user) + // it('should store records in models', async () => { + // const user = { + // name: 'Chris Breuer', + // job_title: 'Open Sourceror', + // email: 'chris@stacksjs.org', + // password: '123456', + // } - expect(result?.email).toBe(user.email) - }) + // const result = await User.create(user) - it('should update records in models', async () => { - const user = { - name: 'Chris Breuer', - job_title: 'Open Sourceror', - email: 'chris@stacksjs.org', - password: '123456', - } + // expect(result?.email).toBe(user.email) + // }) - const model = await User.create(user) + // it('should update records in models', async () => { + // const user = { + // name: 'Chris Breuer', + // job_title: 'Open Sourceror', + // email: 'chris@stacksjs.org', + // password: '123456', + // } - expect(model?.email).toBe(user.email) + // const model = await User.create(user) - const updatedModel = await model.update({ job_title: 'Open Source Developer' }) + // expect(model?.email).toBe(user.email) - expect(updatedModel?.job_title).toBe('Open Source Developer') - }) + // const updatedModel = await model.update({ job_title: 'Open Source Developer' }) - it('should delete records in models', async () => { - const user = { - name: 'Chris Breuer', - job_title: 'Open Sourceror', - email: 'chris@stacksjs.org', - password: '123456', - } + // expect(updatedModel?.job_title).toBe('Open Source Developer') + // }) - const model = await User.create(user) + // it('should delete records in models', async () => { + // const user = { + // name: 'Chris Breuer', + // job_title: 'Open Sourceror', + // email: 'chris@stacksjs.org', + // password: '123456', + // } - expect(model?.email).toBe(user.email) + // const model = await User.create(user) - await model.delete() - - const userDeleted = await User.find(model?.id as number) - - expect(userDeleted).toBeUndefined() - }) - - it('should remove records in models', async () => { - const user = { - name: 'Chris Breuer', - job_title: 'Open Sourceror', - email: 'chris@stacksjs.org', - password: '123456', - } - - const model = await User.create(user) - - expect(model?.email).toBe(user.email) - - await User.remove(model.id!) - - const deletedUser = await User.find(model.id!) - - expect(deletedUser).toBeUndefined() - }) - - it('should fetch the first record in models', async () => { - const user = { - name: 'Chris Breuer', - job_title: 'Open Sourceror', - email: 'chris@stacksjs.org', - password: '123456', - } - - await User.create(user) - - const firstModel = await User.first() - - expect(firstModel?.email).toBe(user.email) - }) - - it('should fetch a record by ID in models', async () => { - const user = { - name: 'Chris Breuer', - job_title: 'Open Sourceror', - email: 'chris@stacksjs.org', - password: '123456', - } - - const model = await User.create(user) - - const foundModel = await User.findOrFail(model.id as number) - - expect(foundModel?.email).toBe(user.email) - }) - - it('should throw an exception when record is not found by ID in models', async () => { - await expect(User.findOrFail(99999)).rejects.toThrowError('No UserModel results for 99999') - }) - - it('should fetch the last record in models', async () => { - const user1 = { - name: 'Chris Breuer', - job_title: 'Open Sourceror', - email: 'chris@stacksjs.org', - password: '123456', - } - - const user2 = { - name: 'John Doe', - job_title: 'Data Scientist', - email: 'john@stacks.com', - password: '789012', - } - - await User.create(user1) - await User.create(user2) - - const lastModel = await User.last() - - expect(lastModel?.email).toBe(user2.email) - }) - - it('should fetch records ordered by a specific column in models', async () => { - const user1 = { - name: 'Chris Breuer', - job_title: 'Open Sourceror', - email: 'chris@stacksjs.org', - password: '123456', - } + // expect(model?.email).toBe(user.email) - const user2 = { - name: 'John Doe', - job_title: 'Data Scientist', - email: 'john@stacks.com', - password: '789012', - } + // await model.delete() - await User.create(user1) - await User.create(user2) + // const userDeleted = await User.find(model?.id as number) - const orderedModels = await User.orderBy('name', 'asc').get() + // expect(userDeleted).toBeUndefined() + // }) - expect(orderedModels[0]?.email).toBe(user1.email) - expect(orderedModels[1]?.email).toBe(user2.email) - }) + // it('should remove records in models', async () => { + // const user = { + // name: 'Chris Breuer', + // job_title: 'Open Sourceror', + // email: 'chris@stacksjs.org', + // password: '123456', + // } - it('should fetch distinct records in models', async () => { - const user1 = { - name: 'Chris Breuer', - job_title: 'Open Sourceror', - email: 'chris@stacksjs.org', - password: '123456', - } + // const model = await User.create(user) - const user2 = { - name: 'John Doe', - job_title: 'Data Scientist', - email: 'john@stacks.com', - password: '789012', - } + // expect(model?.email).toBe(user.email) - const user3 = { - name: 'Jane Doe', - job_title: 'Data Scientist', - email: 'jane@stacks.com', - password: '101112', - } + // await User.remove(model.id!) - await User.create(user1) - await User.create(user2) - await User.create(user3) + // const deletedUser = await User.find(model.id!) - const distinctModels = await User.distinct('job_title').get() + // expect(deletedUser).toBeUndefined() + // }) - expect(distinctModels.length).toBe(2) - expect(distinctModels.map((model: UserModel) => model.job_title)).toEqual(['Open Sourceror', 'Data Scientist']) - }) + // it('should fetch the first record in models', async () => { + // const user = { + // name: 'Chris Breuer', + // job_title: 'Open Sourceror', + // email: 'chris@stacksjs.org', + // password: '123456', + // } - it('should fetch records ordered in ascending order in models', async () => { - const user1 = { - name: 'Chris Breuer', - job_title: 'Open Sourceror', - email: 'chris@stacksjs.org', - password: '123456', - } + // await User.create(user) - const user2 = { - name: 'John Doe', - job_title: 'Data Scientist', - email: 'john@stacks.com', - password: '789012', - } + // const firstModel = await User.first() - await User.create(user1) - await User.create(user2) + // expect(firstModel?.email).toBe(user.email) + // }) - const orderedModelsAsc = await User.orderByAsc('name').get() + // it('should fetch a record by ID in models', async () => { + // const user = { + // name: 'Chris Breuer', + // job_title: 'Open Sourceror', + // email: 'chris@stacksjs.org', + // password: '123456', + // } - expect(orderedModelsAsc[0]?.email).toBe(user1.email) - expect(orderedModelsAsc[1]?.email).toBe(user2.email) - }) + // const model = await User.create(user) - it('should fetch records ordered in descending order in models', async () => { - const user1 = { - name: 'Chris Breuer', - job_title: 'Open Sourceror', - email: 'chris@stacksjs.org', + // const foundModel = await User.findOrFail(model.id as number) + + // expect(foundModel?.email).toBe(user.email) + // }) + + // it('should throw an exception when record is not found by ID in models', async () => { + // await expect(User.findOrFail(99999)).rejects.toThrowError('No UserModel results for 99999') + // }) + + // it('should fetch the last record in models', async () => { + // const user1 = { + // name: 'Chris Breuer', + // job_title: 'Open Sourceror', + // email: 'chris@stacksjs.org', + // password: '123456', + // } + + // const user2 = { + // name: 'John Doe', + // job_title: 'Data Scientist', + // email: 'john@stacks.com', + // password: '789012', + // } + + // await User.create(user1) + // await User.create(user2) + + // const lastModel = await User.last() + + // expect(lastModel?.email).toBe(user2.email) + // }) + + // it('should fetch records ordered by a specific column in models', async () => { + // const user1 = { + // name: 'Chris Breuer', + // job_title: 'Open Sourceror', + // email: 'chris@stacksjs.org', + // password: '123456', + // } + + // const user2 = { + // name: 'John Doe', + // job_title: 'Data Scientist', + // email: 'john@stacks.com', + // password: '789012', + // } + + // await User.create(user1) + // await User.create(user2) + + // const orderedModels = await User.orderBy('name', 'asc').get() + + // expect(orderedModels[0]?.email).toBe(user1.email) + // expect(orderedModels[1]?.email).toBe(user2.email) + // }) + + // it('should fetch distinct records in models', async () => { + // const user1 = { + // name: 'Chris Breuer', + // job_title: 'Open Sourceror', + // email: 'chris@stacksjs.org', + // password: '123456', + // } + + // const user2 = { + // name: 'John Doe', + // job_title: 'Data Scientist', + // email: 'john@stacks.com', + // password: '789012', + // } + + // const user3 = { + // name: 'Jane Doe', + // job_title: 'Data Scientist', + // email: 'jane@stacks.com', + // password: '101112', + // } + + // await User.create(user1) + // await User.create(user2) + // await User.create(user3) + + // const distinctModels = await User.distinct('job_title').get() + + // expect(distinctModels.length).toBe(2) + // expect(distinctModels.map((model: UserModel) => model.job_title)).toEqual(['Open Sourceror', 'Data Scientist']) + // }) + + // it('should fetch records ordered in ascending order in models', async () => { + // const user1 = { + // name: 'Chris Breuer', + // job_title: 'Open Sourceror', + // email: 'chris@stacksjs.org', + // password: '123456', + // } + + // const user2 = { + // name: 'John Doe', + // job_title: 'Data Scientist', + // email: 'john@stacks.com', + // password: '789012', + // } + + // await User.create(user1) + // await User.create(user2) + + // const orderedModelsAsc = await User.orderByAsc('name').get() + + // expect(orderedModelsAsc[0]?.email).toBe(user1.email) + // expect(orderedModelsAsc[1]?.email).toBe(user2.email) + // }) + + // it('should fetch records ordered in descending order in models', async () => { + // const user1 = { + // name: 'Chris Breuer', + // job_title: 'Open Sourceror', + // email: 'chris@stacksjs.org', + // password: '123456', + // } + + // const user2 = { + // name: 'John Doe', + // job_title: 'Data Scientist', + // email: 'john@stacks.com', + // password: '789012', + // } + + // await User.create(user1) + // await User.create(user2) + + // const orderedModelsDesc = await User.orderByDesc('name').get() + + // expect(orderedModelsDesc[0]?.email).toBe(user2.email) + // expect(orderedModelsDesc[1]?.email).toBe(user1.email) + // }) + + // it('should fetch records with where clause', async () => { + // const user1 = { + // name: 'Chris Breuer', + // job_title: 'Open Sourceror', + // email: 'chris@stacksjs.org', + // password: '123456', + // } + + // const user2 = { + // name: 'John Doe', + // job_title: 'Data Scientist', + // email: 'john@stacks.com', + // password: '789012', + // } + + // await User.create(user1) + // await User.create(user2) + + // const results = await User.where('job_title', 'Data Scientist').get() + + // expect(results.length).toBe(1) + // expect(results[0]?.email).toBe(user2.email) + // }) + + // it('should fetch records with multiple where clauses', async () => { + // const testUser = [ + // { + // name: 'Chris Breuer', + // job_title: 'Developer', + // email: 'chris@stacksjs.org', + // password: '123456', + // }, + // { + // name: 'John Doe', + // job_title: 'Developer', + // email: 'john@stacks.com', + // password: '789012', + // }, + // ] + + // await Promise.all(testUser.map(user => User.create(user))) + + // const results = await User + // .where('job_title', 'Developer') + // .where('name', 'John Doe') + // .get() + + // expect(results[0]?.email).toBe(testUser[1]!.email) + + // expect(results.length).toBe(1) + // }) + + // it('should fetch records with whereIn clause', async () => { + // const users = [ + // { + // name: 'Chris Breuer', + // job_title: 'Developer', + // email: 'chris@stacksjs.org', + // password: '123456', + // }, + // { + // name: 'John Doe', + // job_title: 'Designer', + // email: 'john@stacks.com', + // password: '789012', + // }, + // { + // name: 'Jane Smith', + // job_title: 'Manager', + // email: 'jane@stacks.com', + // password: '345678', + // }, + // ] + + // await Promise.all(users.map(user => User.create(user))) + + // const results = await User + // .whereIn('job_title', ['Developer', 'Designer']) + // .get() + + // expect(results.length).toBe(2) + // expect(results.map(r => r.job_title).sort()).toEqual(['Designer', 'Developer']) + // }) + + // it('should paginate with default options', async () => { + // // Create 15 users for basic pagination test + // const users = Array.from({ length: 15 }, (_, i) => ({ + // name: `User ${i + 1}`, + // job_title: 'Developer', + // email: `user${i + 1}@stacks.com`, + // password: '123456', + // })) + + // await Promise.all(users.map(user => User.create(user))) + + // const result = await User.paginate() + + // expect(result.data.length).toBe(10) // Default limit + // expect(result.paging.page).toBe(1) + // expect(result.paging.total_records).toBe(15) + // expect(result.paging.total_pages).toBe(2) + // expect(result.next_cursor).not.toBeNull() + // }) + + // it('should handle last page with custom limit', async () => { + // // Create 12 users to test partial page + // const users = Array.from({ length: 12 }, (_, i) => ({ + // name: `User ${i + 1}`, + // job_title: 'Developer', + // email: `user${i + 1}@stacks.com`, + // password: '123456', + // })) + + // await Promise.all(users.map(user => User.create(user))) + + // const result = await User.paginate({ limit: 10, page: 2 }) + + // expect(result.data.length).toBe(2) // Only 2 records on last page + // expect(result.paging.page).toBe(2) + // expect(result.paging.total_records).toBe(12) + // expect(result.paging.total_pages).toBe(2) + // expect(result.next_cursor).toBeNull() + // }) + + // it('should handle last page with fewer records', async () => { + // // Create 18 users + // const users = Array.from({ length: 18 }, (_, i) => ({ + // name: `User ${i + 1}`, + // job_title: 'Developer', + // email: `user${i + 1}@stacks.com`, + // password: '123456', + // })) + + // await Promise.all(users.map(user => User.create(user))) + + // const result = await User.paginate({ limit: 10, page: 2 }) + + // expect(result.data.length).toBe(8) // Only 8 records on last page + // expect(result.paging.page).toBe(2) + // expect(result.paging.total_records).toBe(18) + // expect(result.paging.total_pages).toBe(2) + // expect(result.next_cursor).toBeNull() // No next cursor on last page + // }) + + // it('should handle empty result set', async () => { + // const result = await User.paginate() + + // expect(result.data.length).toBe(0) + // expect(result.paging.page).toBe(1) + // expect(result.paging.total_records).toBe(0) + // expect(result.paging.total_pages).toBe(0) + // expect(result.next_cursor).toBeNull() + // }) + + // it('should handle custom offset', async () => { + // // Create 30 users + // const users = Array.from({ length: 30 }, (_, i) => ({ + // name: `User ${i + 1}`, + // job_title: 'Developer', + // email: `user${i + 1}@stacks.com`, + // password: '123456', + // })) + + // await Promise.all(users.map(user => User.create(user))) + + // const result = await User.paginate({ limit: 10, offset: 5 }) + + // expect(result.data.length).toBe(10) + // expect(result.data[0]!.name).toBe('User 1') // First user after offset + // expect(result.paging.total_records).toBe(30) + // expect(result.next_cursor).not.toBeNull() + // }) + + // it('should count total records', async () => { + // const users = Array.from({ length: 5 }, (_, i) => ({ + // name: `User ${i}`, + // job_title: 'Developer', + // email: `user${i}@stacks.com`, + // password: '123456', + // })) + + // await Promise.all(users.map(user => User.create(user))) + + // const count = await User.count() + + // expect(count).toBe(5) + // }) + + // it('should perform where like queries', async () => { + // const users = [ + // { + // name: 'Chris Breuer', + // job_title: 'Senior Developer', + // email: 'chris@stacksjs.org', + // password: '123456', + // }, + // { + // name: 'John Doe', + // job_title: 'Junior Developer', + // email: 'john@stacks.com', + // password: '789012', + // }, + // ] + + // await Promise.all(users.map(user => User.create(user))) + + // const results = await User + // .whereLike('job_title', '%Developer%') + // .get() + + // expect(results.length).toBe(2) + // }) + + // it('should fetch records with OR conditions', async () => { + // const users = [ + // { + // name: 'Chris', + // job_title: 'Developer', + // email: 'chris@test.com', + // password: '123456', + // }, + // { + // name: 'John', + // job_title: 'Designer', + // email: 'john@test.com', + // password: '123456', + // }, + // { + // name: 'Jane', + // job_title: 'Manager', + // email: 'jane@test.com', + // password: '123456', + // }, + // ] + + // await Promise.all(users.map(user => User.create(user))) + + // const results = await User + // .orWhere( + // ['job_title', 'Developer'], + // ['job_title', 'Designer'], + // ) + // .get() + + // expect(results.length).toBe(2) + // expect(results.map(r => r.job_title).sort()).toEqual(['Designer', 'Developer']) + // }) + + // it('should perform whereNotIn queries', async () => { + // const users = [ + // { + // name: 'Chris Breuer', + // job_title: 'Developer', + // email: 'chris@stacksjs.org', + // password: '123456', + // }, + // { + // name: 'John Doe', + // job_title: 'Designer', + // email: 'john@stacks.com', + // password: '789012', + // }, + // { + // name: 'Jane Smith', + // job_title: 'Manager', + // email: 'jane@stacks.com', + // password: '345678', + // }, + // ] + + // await Promise.all(users.map(user => User.create(user))) + + // const results = await User + // .whereNotIn('job_title', ['Developer', 'Designer']) + // .get() + + // expect(results.length).toBe(1) + // expect(results[0]?.job_title).toBe('Manager') + // }) + + // it('should perform whereBetween queries', async () => { + // const users = Array.from({ length: 5 }, (_, i) => ({ + // name: `User ${i}`, + // job_title: 'Developer', + // email: `user${i}@stacks.com`, + // password: '123456', + // age: 20 + i * 5, + // })) + + // await Promise.all(users.map(user => User.create(user))) + + // const results = await User + // .whereBetween('id', [1, 3]) + // .get() + + // expect(results.length).toBe(3) + // }) + + // it('should perform advanced where clause combinations', async () => { + // const users = [ + // { + // name: 'Chris Breuer', + // job_title: 'Senior Developer', + // email: 'chris@stacksjs.org', + // password: '123456', + // }, + // { + // name: 'John Doe', + // job_title: 'Junior Developer', + // email: 'john@stacks.com', + // password: '789012', + // }, + // { + // name: 'Jane Smith', + // job_title: 'Senior Designer', + // email: 'jane@stacks.com', + // password: '345678', + // }, + // ] + + // await Promise.all(users.map(user => User.create(user))) + + // const results = await User + // .whereLike('job_title', 'Junior%') + // .get() + + // expect(results.length).toBe(1) + // expect(results[0]?.email).toBe('john@stacks.com') + // }) + + it('should perform aggregation functions (min, max, avg, sum)', async () => { + const users = Array.from({ length: 5 }, (_, i) => ({ + name: `User ${i + 1}`, + job_title: 'Developer', + email: `user${i + 1}@stacks.com`, password: '123456', - } - - const user2 = { - name: 'John Doe', - job_title: 'Data Scientist', - email: 'john@stacks.com', - password: '789012', - } + })) - await User.create(user1) - await User.create(user2) + await Promise.all(users.map(user => User.create(user))) - const orderedModelsDesc = await User.orderByDesc('name').get() + const maxId = await User.max('id') + const minId = await User.min('id') + const avgId = await User.avg('id') + const totalId = await User.sum('id') - expect(orderedModelsDesc[0]?.email).toBe(user2.email) - expect(orderedModelsDesc[1]?.email).toBe(user1.email) + expect(maxId).toBe(5) // Last created user's id + expect(minId).toBe(1) // First created user's id + expect(avgId).toBe(3) // Average of ids 1,2,3,4,5 + expect(totalId).toBe(15) // Sum of ids 1,2,3,4,5 }) - it('should fetch records with where clause', async () => { - const user1 = { - name: 'Chris Breuer', - job_title: 'Open Sourceror', - email: 'chris@stacksjs.org', + it('should handle chunk processing of records', async () => { + // Create 25 users + const users = Array.from({ length: 25 }, (_, i) => ({ + name: `User ${i + 1}`, + job_title: 'Developer', + email: `user${i + 1}@stacks.com`, password: '123456', - } - - const user2 = { - name: 'John Doe', - job_title: 'Data Scientist', - email: 'john@stacks.com', - password: '789012', - } - - await User.create(user1) - await User.create(user2) - - const results = await User.where('job_title', 'Data Scientist').get() - - expect(results.length).toBe(1) - expect(results[0]?.email).toBe(user2.email) - }) - - it('should fetch records with multiple where clauses', async () => { - const testUser = [ - { - name: 'Chris Breuer', - job_title: 'Developer', - email: 'chris@stacksjs.org', - password: '123456', - }, - { - name: 'John Doe', - job_title: 'Developer', - email: 'john@stacks.com', - password: '789012', - }, - ] + })) - await Promise.all(testUser.map(user => User.create(user))) + await Promise.all(users.map(user => User.create(user))) - const results = await User - .where('job_title', 'Developer') - .where('name', 'John Doe') - .get() + let processedCount = 0 + const chunkSize = 10 - expect(results[0]?.email).toBe(testUser[1]!.email) + await User.chunk(chunkSize, async (models) => { + processedCount += models.length + }) - expect(results.length).toBe(1) + expect(processedCount).toBe(25) }) - it('should fetch records with whereIn clause', async () => { + it('should handle pluck operation for specific fields', async () => { const users = [ { name: 'Chris Breuer', job_title: 'Developer', - email: 'chris@stacksjs.org', + email: 'chris@test.com', password: '123456', }, { name: 'John Doe', job_title: 'Designer', - email: 'john@stacks.com', - password: '789012', - }, - { - name: 'Jane Smith', - job_title: 'Manager', - email: 'jane@stacks.com', - password: '345678', + email: 'john@test.com', + password: '123456', }, ] await Promise.all(users.map(user => User.create(user))) - const results = await User - .whereIn('job_title', ['Developer', 'Designer']) - .get() - - expect(results.length).toBe(2) - expect(results.map(r => r.job_title).sort()).toEqual(['Designer', 'Developer']) - }) - - it('should paginate with default options', async () => { - // Create 15 users for basic pagination test - const users = Array.from({ length: 15 }, (_, i) => ({ - name: `User ${i + 1}`, - job_title: 'Developer', - email: `user${i + 1}@stacks.com`, - password: '123456', - })) - - await Promise.all(users.map(user => User.create(user))) - - const result = await User.paginate() - - expect(result.data.length).toBe(10) // Default limit - expect(result.paging.page).toBe(1) - expect(result.paging.total_records).toBe(15) - expect(result.paging.total_pages).toBe(2) - expect(result.next_cursor).not.toBeNull() + const emails = await User.pluck('email') + expect(emails).toContain('chris@test.com') + expect(emails).toContain('john@test.com') + expect(emails.length).toBe(2) }) - it('should handle last page with custom limit', async () => { - // Create 12 users to test partial page - const users = Array.from({ length: 12 }, (_, i) => ({ - name: `User ${i + 1}`, + it('should handle firstOrCreate operation', async () => { + const userData = { + name: 'Chris Breuer', job_title: 'Developer', - email: `user${i + 1}@stacks.com`, + email: 'chris@test.com', password: '123456', - })) + } - await Promise.all(users.map(user => User.create(user))) + // First creation + const firstUser = await User.firstOrCreate( + { email: 'chris@test.com' }, + userData, + ) - const result = await User.paginate({ limit: 10, page: 2 }) + // Attempt to create the same user + const existingUser = await User.firstOrCreate( + { email: 'chris@test.com' }, + { + name: 'Different Name', + job_title: 'Different Job', + email: 'chris@test.com', + password: '789012', + }, + ) - expect(result.data.length).toBe(2) // Only 2 records on last page - expect(result.paging.page).toBe(2) - expect(result.paging.total_records).toBe(12) - expect(result.paging.total_pages).toBe(2) - expect(result.next_cursor).toBeNull() + expect(firstUser.id).toBe(existingUser.id) + expect(existingUser.name).toBe('Chris Breuer') }) - it('should handle last page with fewer records', async () => { - // Create 18 users - const users = Array.from({ length: 18 }, (_, i) => ({ - name: `User ${i + 1}`, + it('should handle updateOrCreate operation', async () => { + const initialData = { + name: 'Chris Breuer', job_title: 'Developer', - email: `user${i + 1}@stacks.com`, + email: 'chris@test.com', password: '123456', - })) - - await Promise.all(users.map(user => User.create(user))) - - const result = await User.paginate({ limit: 10, page: 2 }) - - expect(result.data.length).toBe(8) // Only 8 records on last page - expect(result.paging.page).toBe(2) - expect(result.paging.total_records).toBe(18) - expect(result.paging.total_pages).toBe(2) - expect(result.next_cursor).toBeNull() // No next cursor on last page - }) + } - it('should handle empty result set', async () => { - const result = await User.paginate() + const updatedData = { + name: 'Chris B', + job_title: 'Senior Developer', + email: 'chris@test.com', + password: '789012', + } - expect(result.data.length).toBe(0) - expect(result.paging.page).toBe(1) - expect(result.paging.total_records).toBe(0) - expect(result.paging.total_pages).toBe(0) - expect(result.next_cursor).toBeNull() + // First creation + const created = await User.updateOrCreate( + { email: 'chris@test.com' }, + initialData, + ) + + // Update the existing record + const updated = await User.updateOrCreate( + { email: 'chris@test.com' }, + updatedData, + ) + + expect(created.id).toBe(updated.id) + expect(updated.job_title).toBe('Senior Developer') + expect(updated.name).toBe('Chris B') }) - it('should handle custom offset', async () => { - // Create 30 users - const users = Array.from({ length: 30 }, (_, i) => ({ - name: `User ${i + 1}`, + it('should handle model state tracking (isDirty, isClean, wasChanged)', async () => { + const user = await User.create({ + name: 'Chris Breuer', job_title: 'Developer', - email: `user${i + 1}@stacks.com`, + email: 'chris@test.com', password: '123456', - })) + }) - await Promise.all(users.map(user => User.create(user))) + expect(user.isDirty()).toBe(false) + expect(user.isClean()).toBe(true) - const result = await User.paginate({ limit: 10, offset: 5 }) + user.name = 'Chris B' + expect(user.isDirty('name')).toBe(true) + expect(user.isClean('job_title')).toBe(true) - expect(result.data.length).toBe(10) - expect(result.data[0]!.name).toBe('User 1') // First user after offset - expect(result.paging.total_records).toBe(30) - expect(result.next_cursor).not.toBeNull() + await user.save() + expect(user.wasChanged('name')).toBe(true) + expect(user.wasChanged('job_title')).toBe(false) }) - it('should count total records', async () => { - const users = Array.from({ length: 5 }, (_, i) => ({ - name: `User ${i}`, + it('should handle join operations', async () => { + // First create a user + const user = await User.create({ + name: 'Chris Breuer', job_title: 'Developer', - email: `user${i}@stacks.com`, + email: 'chris@test.com', password: '123456', - })) - - await Promise.all(users.map(user => User.create(user))) - - const count = await User.count() - - expect(count).toBe(5) - }) - - it('should perform where like queries', async () => { - const users = [ - { - name: 'Chris Breuer', - job_title: 'Senior Developer', - email: 'chris@stacksjs.org', - password: '123456', - }, - { - name: 'John Doe', - job_title: 'Junior Developer', - email: 'john@stacks.com', - password: '789012', - }, - ] + }) - await Promise.all(users.map(user => User.create(user))) + // Create some posts for the user + await DB.instance.insertInto('posts').values([ + { user_id: user.id, title: 'Post 1' }, + { user_id: user.id, title: 'Post 2' }, + ]).execute() const results = await User - .whereLike('job_title', '%Developer%') + .join('posts', 'users.id', 'posts.user_id') + .where('users.id', '=', user.id) .get() - expect(results.length).toBe(2) + expect(results.length).toBeGreaterThan(0) + expect(results[0].name).toBe('Chris Breuer') }) - it('should fetch records with OR conditions', async () => { + it('should handle groupBy and having operations', async () => { + // Create users with different job titles const users = [ - { - name: 'Chris', - job_title: 'Developer', - email: 'chris@test.com', - password: '123456', - }, - { - name: 'John', - job_title: 'Designer', - email: 'john@test.com', - password: '123456', - }, - { - name: 'Jane', - job_title: 'Manager', - email: 'jane@test.com', - password: '123456', - }, + { name: 'User 1', job_title: 'Developer', email: 'user1@test.com', password: '123456' }, + { name: 'User 2', job_title: 'Developer', email: 'user2@test.com', password: '123456' }, + { name: 'User 3', job_title: 'Designer', email: 'user3@test.com', password: '123456' }, ] await Promise.all(users.map(user => User.create(user))) const results = await User - .orWhere( - ['job_title', 'Developer'], - ['job_title', 'Designer'], - ) + .groupBy('job_title') + .having('id', '>', 0) .get() - expect(results.length).toBe(2) - expect(results.map(r => r.job_title).sort()).toEqual(['Designer', 'Developer']) + expect(results.length).toBe(2) // Should have two groups: Developer and Designer }) - it('should perform whereNotIn queries', async () => { - const users = [ - { - name: 'Chris Breuer', - job_title: 'Developer', - email: 'chris@stacksjs.org', - password: '123456', - }, - { - name: 'John Doe', - job_title: 'Designer', - email: 'john@stacks.com', - password: '789012', - }, - { - name: 'Jane Smith', - job_title: 'Manager', - email: 'jane@stacks.com', - password: '345678', - }, - ] + it('should handle fill and forceFill operations', async () => { + const user = new User({}) - await Promise.all(users.map(user => User.create(user))) - - const results = await User - .whereNotIn('job_title', ['Developer', 'Designer']) - .get() - - expect(results.length).toBe(1) - expect(results[0]?.job_title).toBe('Manager') - }) - - it('should perform whereBetween queries', async () => { - const users = Array.from({ length: 5 }, (_, i) => ({ - name: `User ${i}`, + user.fill({ + name: 'Chris Breuer', job_title: 'Developer', - email: `user${i}@stacks.com`, + email: 'chris@test.com', password: '123456', - age: 20 + i * 5, - })) + }) - await Promise.all(users.map(user => User.create(user))) + expect(user.name).toBe('Chris Breuer') - const results = await User - .whereBetween('id', [1, 3]) - .get() + // Try to fill a guarded attribute + user.forceFill({ + id: 999, + name: 'Changed Name', + }) - expect(results.length).toBe(3) + expect(user.id).toBe(999) // Should work with forceFill }) - it('should perform advanced where clause combinations', async () => { - const users = [ - { - name: 'Chris Breuer', - job_title: 'Senior Developer', - email: 'chris@stacksjs.org', - password: '123456', - }, - { - name: 'John Doe', - job_title: 'Junior Developer', - email: 'john@stacks.com', - password: '789012', - }, - { - name: 'Jane Smith', - job_title: 'Senior Designer', - email: 'jane@stacks.com', - password: '345678', - }, - ] - - await Promise.all(users.map(user => User.create(user))) - - const results = await User - .whereLike('job_title', 'Junior%') - .get() + it('should handle raw queries', async () => { + await User.create({ + name: 'Chris Breuer', + job_title: 'Developer', + email: 'chris@test.com', + password: '123456', + }) - expect(results.length).toBe(1) - expect(results[0]?.email).toBe('john@stacks.com') + const results = await User.rawQuery('SELECT * FROM users WHERE job_title = ?') + expect(Array.isArray(results)).toBe(true) }) })