Skip to content

Commit

Permalink
Update library design
Browse files Browse the repository at this point in the history
  • Loading branch information
jinhduong committed Apr 24, 2018
1 parent 6ad29e4 commit eedd993
Show file tree
Hide file tree
Showing 33 changed files with 207 additions and 108 deletions.
54 changes: 29 additions & 25 deletions src/demo/test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { Queryable } from "../implements/queryable";

const queryable = new Queryable<{ name, nationId, overall, skills }>();

let promiseApi = new Promise((resolve, reject) => {
// skills: attack, stamia, speed, shoot
setTimeout(() => {
Expand All @@ -16,34 +14,40 @@ let promiseApi = new Promise((resolve, reject) => {
}, 1000);
})

let nations = [
{ id: 1, name: 'Portugal', areaId: 1 },
{ id: 2, name: 'Argentina', areaId: 2 },
{ id: 3, name: 'France', areaId: 1 },
{ id: 4, name: 'Egypt', areaId: 3 }
]
let nations: Promise<{ id, name, areaId }[]> = new Promise(resolve => {
setTimeout(() => {
resolve([
{ id: 1, name: 'Portugal', areaId: 1 },
{ id: 2, name: 'Argentina', areaId: 2 },
{ id: 3, name: 'France', areaId: 1 },
{ id: 4, name: 'Egypt', areaId: 3 }
]);
}, 1000);
})

let continents = new Promise<{ id, areaName }[]>(resolve => {
setTimeout(() => {
resolve([
{ id: 1, areaName: 'Euro' },
{ id: 2, areaName: 'South America' },
]);
}, 1000);
})

let continents = [
{ id: 1, areaName: 'Euro' },
{ id: 2, areaName: 'South America' },
]

function main() {
// Just query not execute query
console.time('querytime');
let query = queryable
.from(promiseApi)
.groupJoin(nations, (x, y) => x.nationId === y.id, x => x.y.name)
.select(x => {
return {
area: x.key,
players: new Queryable().from(x.items).select((pl: { x, y }) => {
return {
playerName: pl.x.name
}
}).toList()
}
})
let query =
Queryable
.from(nations)
.join(continents, (x, y) => x.areaId === y.id)
.select(o => {
return {
nation: o.x.name,
area: o.y.areaName
}
});

console.timeEnd('querytime');

Expand Down
17 changes: 17 additions & 0 deletions src/implements/base.iterator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { IIterator } from "../intefaces/iterator.interface";

export class BaseIterator<T> implements IIterator<T> {
nextSource: any[] | Promise<any>;

replaceBySyncSource?(syncSource: T[]) {
this.nextSource = syncSource;
}

hasSource(): boolean {
return this.nextSource !== null && this.nextSource !== undefined;
}

execute(source: T[]) {
throw new Error("Method not implemented.");
}
}
78 changes: 49 additions & 29 deletions src/implements/methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ export class IteratorMethods<T> implements Methods<T> {
_iteratorCollection: Array<IIterator<T>> = [];

// Contains initial source
_source: any[] | Promise<any> | T[] | Promise<T> = [];
_source: T[] | Promise<T[]>;

_data: any[];

constructor(iteratorCollection: Array<IIterator<T>>, source: any[] | Promise<any> | T[] | Promise<T>) {
constructor(iteratorCollection: Array<IIterator<T>>, source: T[] | Promise<T[]>) {
this._iteratorCollection = iteratorCollection;
this._source = source;
}
Expand Down Expand Up @@ -87,26 +87,7 @@ export class IteratorMethods<T> implements Methods<T> {
}

toList<S>(): Promise<S[]> {

// From cache
if (this._data) {
let _result = this.runIterators(this._data);
return Promise.resolve(_result as S[]);
}
// From promise
else if (Utils.isPromise(this._source)) {
return (this._source as Promise<T[]>).then(data => {
let _result = this.runIterators(data);
this._data = data;
return _result as S[];
});
}
// From static data
else if (this._source) {
let _result = this.runIterators(this._source as T[]);
return Promise.resolve(_result as S[]);
}
return null;
return this.runIterators() as any;
}

first(iterator?: (entity: T) => boolean): Promise<T> {
Expand Down Expand Up @@ -209,16 +190,55 @@ export class IteratorMethods<T> implements Methods<T> {
});
}

// Private funstions
// Private functions

private runIterators(syncSource: T[]) {
private runIterators(): Promise<T[]> {

let _result = Object.assign([], syncSource);
let _result: T[] = [];
let _nextSources = {};
let _promises = [];

this._iteratorCollection.forEach((ite: IIterator<T>) => {
_result = ite.execute(_result) as T[];
});
for (let i = 0, li = this._iteratorCollection.length; i < li; i++) {

let _iterator = this._iteratorCollection[i];

if (!_iterator.hasSource()) continue;

if (Utils.isPromise(_iterator.nextSource))
_promises.push(_iterator.nextSource);
else
_promises.push(Promise.resolve(_iterator.nextSource));
}

return _result;
if (Utils.isPromise(this._source))
_promises.unshift(this._source);
else
_promises.unshift(Promise.resolve(this._source));

return new Promise(resolve => {
Promise.all(_promises).then((responseDatas: any[]) => {
let _index = 0;

// Set from method's source
_result = responseDatas[0];

for (let i = 0, li = this._iteratorCollection.length; i < li; i++) {

let _iterator = this._iteratorCollection[i];

if (_iterator.hasSource()) {
_iterator.replaceBySyncSource(responseDatas[_index + 1]);
_index += 1;
}
}

this._iteratorCollection.forEach((ite: IIterator<T>) => {
_result = ite.execute(_result) as T[];
});

resolve(_result);

});
});
}
}
9 changes: 4 additions & 5 deletions src/implements/queryable.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { Utils } from "../utils/object";
import { IQueryable } from "../intefaces/iqueryable.interface";
import { IIterator } from "../intefaces/iterator.interface";
import { IteratorMethods } from "./methods";
import { Methods } from "../intefaces/methods.interface";

export class Queryable<T> implements IQueryable<T> {
_iteratorCollection: Array<IIterator<T>> = [];
export class Queryable {

from(source: Promise<any> | T[] | Promise<T> | any[]): Methods<T> {
private static _iteratorCollection: Array<IIterator<any>> = [];

static from<T>(source: T[] | Promise<T[]>): Methods<T> {
return new IteratorMethods(this._iteratorCollection, source);
}
}
6 changes: 0 additions & 6 deletions src/intefaces/iqueryable.interface.ts

This file was deleted.

11 changes: 10 additions & 1 deletion src/intefaces/iterator.interface.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
export interface IIterator<T> {
execute(source: Array<T> | Array<any>): Array<T> | T | any;

// Contains the source if this iterator need itself
nextSource?: any[] | Promise<any[]>;

replaceBySyncSource?(syncSource: T[]);

hasSource(): boolean;

// Call this clause
execute(source: T[]): any;
}
17 changes: 11 additions & 6 deletions src/intefaces/methods.interface.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export interface Methods<T> {

// Query methods
where(iterator: (entity: T) => boolean): Methods<T>;
select<S>(iterator: (entity: T) => S): Methods<S>;
Expand All @@ -16,17 +17,21 @@ export interface Methods<T> {

// Execute methods
toList<S extends T>(): Promise<S[]>;

sum<S>(iterator: (entity: T) => S): Promise<number>;
min<S>(iterator: (entity: T) => S): Promise<number>;
max<S>(iterator: (entity: T) => S): Promise<number>;
avarage<S>(iterator: (entity: T) => S): Promise<number>;
any<T>(iterator: (entity: T) => boolean): Promise<boolean>;
contains(entity: T): Promise<boolean>;

// Methods with optional iterator
first(iterator?: (entity: T) => boolean): Promise<T>;
firstOrDefault(iterator?: (entity: T) => boolean): Promise<T>;
last(iterator?: (entity: T) => boolean): Promise<T>;
lastOrDefault(iterator?: (entity: T) => boolean): Promise<T>;
single(iterator?: (entity: T) => boolean): Promise<T>;
singleOrDefault(iterator?: (entity: T) => boolean): Promise<T>;
count(iterator?: (entity: T) => boolean): Promise<number>;
sum<S>(iterator: (entity: T) => S): Promise<number>;
min<S>(iterator: (entity: T) => S): Promise<number>;
max<S>(iterator: (entity: T) => S): Promise<number>;
avarage<S>(iterator: (entity: T) => S): Promise<number>;
any<T>(iterator: (entity: T) => boolean): Promise<boolean>;
contains(entity: T): Promise<boolean>;

}
4 changes: 3 additions & 1 deletion src/methods/any.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { IIterator } from "../intefaces/iterator.interface";
import { BaseIterator } from "../implements/base.iterator";

export class AnyClause<T> implements IIterator<T> {
export class AnyClause<T> extends BaseIterator<T> implements IIterator<T> {

_iterator: (item: T) => boolean;

Expand All @@ -14,6 +15,7 @@ export class AnyClause<T> implements IIterator<T> {
}

constructor(func: (item: T) => boolean) {
super();
this._iterator = func;
}
}
4 changes: 3 additions & 1 deletion src/methods/average.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { IIterator } from "../intefaces/iterator.interface";
import { SelectClause } from "./select";
import { BaseIterator } from "../implements/base.iterator";

export class AvarageClause<T> implements IIterator<T> {
export class AvarageClause<T> extends BaseIterator<T> implements IIterator<T> {

_iterator: (item: T) => any;

Expand All @@ -18,6 +19,7 @@ export class AvarageClause<T> implements IIterator<T> {
}

constructor(func?: (item: T) => any) {
super();
this._iterator = func;
}
}
4 changes: 3 additions & 1 deletion src/methods/contains.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { IIterator } from "../intefaces/iterator.interface";
import { BaseIterator } from "../implements/base.iterator";

export class ContainsClause<T> implements IIterator<T> {
export class ContainsClause<T> extends BaseIterator<T> implements IIterator<T> {

_entity: T;

Expand All @@ -20,6 +21,7 @@ export class ContainsClause<T> implements IIterator<T> {
}

constructor(entity: T) {
super();
this._entity = entity;
}
}
4 changes: 3 additions & 1 deletion src/methods/count.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { IIterator } from "../intefaces/iterator.interface";
import { BaseIterator } from "../implements/base.iterator";

export class CountClause<T> implements IIterator<T> {
export class CountClause<T> extends BaseIterator<T> implements IIterator<T> {

_iterator: (item: T) => boolean;

Expand All @@ -14,6 +15,7 @@ export class CountClause<T> implements IIterator<T> {
}

constructor(func?: (item: T) => boolean) {
super();
this._iterator = func;
}
}
4 changes: 3 additions & 1 deletion src/methods/first.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { IIterator } from "../intefaces/iterator.interface";
import { BaseIterator } from "../implements/base.iterator";

export class FirstClause<T> implements IIterator<T> {
export class FirstClause<T> extends BaseIterator<T> implements IIterator<T> {

_iterator: (item: T) => boolean;

Expand All @@ -16,6 +17,7 @@ export class FirstClause<T> implements IIterator<T> {
}

constructor(func?: (item: T) => boolean) {
super();
this._iterator = func;
}
}
4 changes: 3 additions & 1 deletion src/methods/groupBy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { IIterator } from "../intefaces/iterator.interface";
import { SelectClause } from "./select";
import { BaseIterator } from "../implements/base.iterator";

export class GroupByClause<T> implements IIterator<T> {
export class GroupByClause<T> extends BaseIterator<T> implements IIterator<T> {

_iterator: (item: T) => any;

Expand Down Expand Up @@ -48,6 +49,7 @@ export class GroupByClause<T> implements IIterator<T> {
}

constructor(func: (item: T) => any) {
super();
this._iterator = func;
}

Expand Down

0 comments on commit eedd993

Please sign in to comment.