Skip to content
/ linqxy Public

TypeScript LINQ - Write LINQ and get query objects of different kinds for different processors

License

Notifications You must be signed in to change notification settings

Hookyns/linqxy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 

Repository files navigation

LINQxy /linkzē/ (LINQ Proxy)

Write LINQ and get query objects of different kinds for different processors.

What is LINQxy for?

LINQxy is a standard for data querying in TypeScript. It's a proxy translating LINQ queries into different query objects for different libraries (depends on plugins). You can write LINQ and use it to query MongoDB, TypeORM, ZangoDB (IndexDB) or anything else.

Related Projects

How the LINQxy Looks Like?

Lets have an interface of the data record we want to query.

enum Gender {
  Female,
  Male,
  Unspecified,
}

interface IPerson {
  name: string;
  age: number;
  xp: number;
}

interface IEmployee extends IPerson {
  work: string;
  salary: number;
}

And a generic usage.

import { Queryable } from "linqxy";

const someFilterObject = { workDescKeywords: [ "javascript", "typescript" ] };

const empQuery = Queryable.create<IEmployee>()
  .filter(emp => emp.xp > 5 && !emp.name.startsWith("Jo"))
  .filterIf(emp => someFilterObject.workDescKeywords.contains(emp.work), !!someFilterObject.workDescKeywords)
  .map(emp => ({
    name: emp.name,
    xp: emp.xp
  }));

Result of the empQuery variable is Queryable object which can be build into eg. TypeORM. Same example with TypeORM plugin will look like:

import { Queryable } from "linqxy-typeorm";
import Employee from "./Employee";

const someFilterObject = { workDescKeywords: [ "javascript", "typescript" ] };

const emps = await Queryable.create(Employee)
  .filter(emp => emp.xp >= 5 && !emp.name.startsWith("Jo"))
  .filterIf(emp => someFilterObject.workDescKeywords.contains(emp.work), !!someFilterObject.workDescKeywords)
  .map(emp => ({
    name: emp.name,
    xp: emp.xp
  }))
  .find();

Which is translated into query:

await connection.getRepository(Employee).find({
    xp: MoreThanOrEqual(5),
    name: Not(Like("Jo%")),
    work: In(["javascript", "typescript"])
});

How Does It Work?

Sorry to JavaScript users, but LINQxy uses TypeScript transformer typescript-expression-transformer. See the repo of the expression transformer for more information.

Is there a volunteer to create the Babel transform plugin?

Synopsis

class Queryable<TRecord> 
{
  filter(Expresson<(r: TRecord) => boolean> expression): Queryable<TRecord> {}
  
  filterIf(Expresson<(r: TRecord) => boolean> expression, condition: boolean): Queryable<TRecord> {}
  
  innerJoin<T, R>(
    target: T[] | Queryable<T>, 
    on: Expression<(first: TRecord, second: T) => boolean>, 
    result: Expression<(first: TRecord, second: T) => R>
  ): Queryable<TRecord> {}
  
  map<R>(Expresson<(r: TRecord) => R> expression): Queryable<R> {}
}

Plugins

Plugins must implement IQueryGenerator interface. See wiky. TODO

Optionaly, it can extend Queryable object and provide some extra functionality. Eg. like TypeORM plugin:

import { Queryable as BaseQueryable} from "linqxy";
import { Generator as TypeORMGenerator } from "./Generator";

class Queryable<TRecord> extends BaseQueryable
{
  static create<TEntity>(type: typeof T): Queryable<TRecord> {}
  
  async find(): Promise<Array<TRecord>> {
    return await connection.getRepository(this.RecordType).find(this.build(TypeORMGenerator));
  }
  
  async findOne(): Promise<TRecord> {}
}

About

TypeScript LINQ - Write LINQ and get query objects of different kinds for different processors

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published