Git Product home page Git Product logo

Comments (11)

KnorpelSenf avatar KnorpelSenf commented on June 15, 2024 2

Ah so it's about operator precedence, I see.

Using . will go one level deeper and basically create brackets. Basically, messages.where.chat.id.is(3).and.title.is("Friends") translates to this:

messages
  where
   -> chat
      -> id is 3
      -> AND title is "Friends"

You can go back to the top and add more clauses by using where again: The query messages.where.chat.id.is(3).and.title.is("Friends").and.where.text.exists translates to this:

messages
  -> where
    -> chat
      -> id is 3
      -> AND title is "Friends"
  -> AND where
    -> text exists

Naturally, this will have the following precedence: (chat.id == 3 && chat.title == "Friends") && !!text.

Thus, you can do messages.where.chat.id.is(ctx.chat.id).and.where.from.id.is(1234).or.username.is("someusername")

which translates to

messages
  -> where
    -> chat
      -> id is ctx.chat.id
  -> AND where
    -> from
      -> id is 1234
      -> OR username is "someusername"

and therefore gives you the desired

chat.id === ctx.chat.id && (from.id === 1234 || from.username === "someusername")

In addition, if things stay on the same level, this will be done with && before || like in JS. In other words, doing a.and.b.or.c will be interpreted as a && b || c and hence turn into (a && b) || c because && binds stronger than ||.

In contrast, if you wanted to test for

(chat.id === ctx.chat.id && from.id === 1234) || from.username === "someusername"

you would have to combine the chat and the from into one, and then add a second check for from. Hence, you can use messages.where.chat.id.is(ctx.chat.id).and.where.from.id.is(1234).or.where.from.username.is("someusername") because it translates to

messages
  -> where
    -> chat
      -> id is ctx.chat.id
  -> AND where
    -> from
      -> id is 1234
  -> OR where
    -> from
      -> username is "someusername"

which gives you the desired

(chat.id === ctx.chat.id && from.id === 1234) || from.username === "someusername"

Does this make more sense now?

from history.

Mi3liX9 avatar Mi3liX9 commented on June 15, 2024 1

Now it is clear :)

from history.

Mi3liX9 avatar Mi3liX9 commented on June 15, 2024

It seems unfamiliar to use dots,
Why do you use them instead of objects?
Something like Prisma way:

const count = await ctx.history
  .messages.select({
    where: { 
      id: ctx.chat.id,
      from: { id: ctx.from.id }
    }
}).count();

from history.

KnorpelSenf avatar KnorpelSenf commented on June 15, 2024

I find dots a bit easier to read and a bit easier to write. They translate into English prose, which is nice. It's familiar from chai.js to check object structures.

But to be honest, I don't have too strong opinions about it—if people agree that objects are better than dots, feel free to change it.

How would disjunctions look (queries with OR)?

from history.

Mi3liX9 avatar Mi3liX9 commented on June 15, 2024

Inspired by Prisma, it could be like this:

const count = await ctx.history .messages.select({ 
  where: { 
    and: {
      or: [
        { from: { username: "someusername" } },
        { from: { id: 1234 } },
      ],
      id: ctx.chat.id,
    } 
  } 
}).count();

But I find working with nested objects is hard a little bit

Maybe making something in the middle will be easier like this:

const count = ctx.history.select
  .where({ chat: { id: ctx.chat.id } })
  .or([ 
    { from: { id: 1234 } },
    { from: { username: "someusername" } } 
  ])
  .count();

from history.

KnorpelSenf avatar KnorpelSenf commented on June 15, 2024

Maybe making something in the middle will be easier like this:

const count = ctx.history.select
  .where({ chat: { id: ctx.chat.id } })
  .or([ 
    { from: { id: 1234 } },
    { from: { username: "someusername" } } 
  ])
  .count();

Do you find this better because you are familiar with Prisma, or because it is more readable than this?

const count = ctx.history.select.messages
    .where.chat.id.is(ctx.chat.id)
    .and.where.from.id.is(1234).or.username.is("someusername")
    .count()

from history.

Mi3liX9 avatar Mi3liX9 commented on June 15, 2024

Maybe making something in the middle will be easier like this:

const count = ctx.history.select
  .where({ chat: { id: ctx.chat.id } })
  .or([ 
    { from: { id: 1234 } },
    { from: { username: "someusername" } } 
  ])
  .count();

Do you find this better because you are familiar with Prisma, or because it is more readable than this?

const count = ctx.history.select.messages
    .where.chat.id.is(ctx.chat.id)
    .and.where.from.id.is(1234).or.username.is("someusername")
    .count()

I find this easier to read and write but and/or queries confused me

from history.

KnorpelSenf avatar KnorpelSenf commented on June 15, 2024

and/or queries confused me

Can you elaborate?

from history.

Mi3liX9 avatar Mi3liX9 commented on June 15, 2024

and/or queries confused me

Can you elaborate?

const count = ctx.history.select.messages
    .where.chat.id.is(ctx.chat.id)
    .and.where.from.id.is(1234).or.username.is("someusername")
    .count()

How can I make sure it is:

chat.id === ctx.chat.id && (from.id === 1234 || from.username === "someusername")

Not this:

(chat.id === ctx.chat.id && from.id === 1234) || from.username === "someusername"

And what about if I want the second one?

from history.

Loskir avatar Loskir commented on June 15, 2024

I definitely prefer {"chat.id": 123} over chat.id.is(123). The first one is way easier to read for me because in the second one values and operators are mixed together.

const count = ctx.history.select.messages
    .where({"chat.id": ctx.chat.id})
    .and.where({"from.id": 1234}).or({username: "someusername"})
    .count()

The problem is that this way we can't use custom operators like < or >.

Mongo works around this with {$lt: 123} and I don't like this approach.
kysely uses arrays and strings like this ['id', '<', 123] and I like it.

Maybe we can use arrays too?

const count = ctx.history.select.messages
    .where([
      ["chat.id", "=", ctx.chat.id],
      [
        ["from.id", "=", 1234],
        "or",
        ["username", "=", "someusername"],
      ],
    ])
    .count()

from history.

KnorpelSenf avatar KnorpelSenf commented on June 15, 2024

I find that syntax okay, too. I don't really feel like implementing it because this will take a huge effort, but I'm sure it's possible.

Do you always have to wrap stuff in double arrays, or can we just use where(["text", "exists"])?

from history.

Related Issues (1)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.