prisma-client-go icon indicating copy to clipboard operation
prisma-client-go copied to clipboard

Support for composite types

Open arthur-fontaine opened this issue 1 year ago • 4 comments

Considering the following Prisma schema:

generator db {
  provider = "go run github.com/steebchen/prisma-client-go"
}

datasource db {
  provider = "mongodb"
  url      = env("DATABASE_URL")
}

model User {
  id     String  @id @default(auto()) @map("_id") @db.ObjectId
  avatar Avatar
}

type Avatar {
  imageUrl String
}

Currently, the user model generated looks like this:

// InnerUser holds the actual data
type InnerUser struct {
        ID string `json:"id"`
}

// RawUserModel is a struct for User when used in raw queries
type RawUserModel struct {
        ID RawString `json:"id"`
}

// RelationsUser holds the relation data separately
type RelationsUser struct {
        Avatar *AvatarModel `json:"avatar,omitempty"`
}

However this is not correct. Avatar should not be treated as a model. It is a composite type (a feature of Prisma for MongoDB).

[!NOTE] The code does not even work because Avatar is a type, not a model, so there is no AvatarModel generated.

  • [x] I am open to work on this feature if you want

arthur-fontaine avatar Dec 08 '24 00:12 arthur-fontaine

Yeah I started the feature here: https://github.com/steebchen/prisma-client-go/pull/1086 but haven't had the time to finish it as it needs some more work.

If you want to work on it I'd be happy to help and review, feel free to use the existing PR as a starting point if it helps.

steebchen avatar Dec 08 '24 05:12 steebchen

I started to work on it based on your PR. The tests work now but I still need to work on Select and Where.

I open a new PR with my branch and you close your one?

arthur-fontaine avatar Dec 08 '24 19:12 arthur-fontaine

Before I start working on Select and Where, here is my proposal:

Typescript Go equivalent

where with the object as a parameter (is, equals, isNot, etc.)

const orders = await prisma.order.findMany({
  where: {
    shippingAddress: {
      is: {
        street: '555 Candy Cane Lane',
      },
    },
  },
})
orders, err := client.Order.FindMany(
  db.Order.ShippingAddress.Is(db.ShippingAddress{
    Street: "555 Candy Cane Lane",
  }),
).Exec(ctx)

where with the a boolean as parameter (isSet, etc.)

const orders = await prisma.order.findMany({
  where: {
    billingAddress: {
      isSet: true,
    },
  },
});
orders, err := client.Order.FindMany(
  db.Order.BillingAddress.IsSet(true),
).Exec(ctx)

select the whole object

const orders = await prisma.order.findMany({
  select: {
    billingAddress: true,
  },
});
orders, err := client.Order.FindMany().Select(
  db.Order.BillingAddress.Field(),
).Exec(ctx)

select specific properties in the object

const orders = await prisma.order.findMany({
  select: {
    billingAddress: {
      select: { street: true },
    },
  },
});
orders, err := client.Order.FindMany().Select(
  db.Order.BillingAddress.Select(
    db.Order.BillingAddress.Street.Field()
  ),
).Exec(ctx)

Are you ok with it?

arthur-fontaine avatar Dec 08 '24 19:12 arthur-fontaine

Yes that looks great!

steebchen avatar Dec 09 '24 06:12 steebchen