A view of Luxor, Egypt

Build time Queries

  • By Artem V. Shamsutdinov
  • Early 2020

Just like with persistence operations it is possible to process query operations at build time, while keeping all of the benefits of TypeScript type checking and auto-completion.

Given the following two entities:

@Entity()
export class Parent {

    @Id()
    @GeneratedValue()
    key: number;

    value: string;

    @OneToMany({cascade: CascadeType.DELETE, mappedBy: 'parent'})
    children: Child<[];
}

@Entity()
export class Child {

    @Id()
    @GeneratedValue()
    key: number;

    value: string;

    @ManyToOne()
    parent: Parent;
}

It is then possible to create build time query definitions:

export class ParentDao extends BaseParentDao {

    @Query<IQParent>(select({
            id: Y,
            value: Y,
            children: {
                id: Y,
                value: Y
            }
        }).from(p => ({
            p,
            c: p.children.innerJoin()
        }).where((parentId, notLikeChildValue, q) =>
            q.p.id == parentId
            && !q.c.value.like(notLikeChildValue)
        }).orderBy(q => [
            q.p.id.desc(),
            q.c.id.desc()
        ]))
    static selectWithChildren: (
           parentId: number,
           notLikeChildValue: string
       ) => Promise<Parent[]>;
}

Here are the reasons for adding this functionality:

  • Allows schema publisher to lock down which queries can be performed against their schema.
  • Removes the need for including the bulk of Airport client code in client applications, a very minimal stub can be generated instead
  • Allows to quickly prepare a statement, without subsequent Javascript execution or additional statement for keeping track of statement ids
  • Makes the where clause more readable by using native boolean and comparison operators.

I have no plans for adding it right now, since I'm focusing on pushing out a basic working version. However I'm expecting this issue to land in the GA version.