diff --git a/node-mysql-wrapper/node-mysql-wrapper-tests.ts b/node-mysql-wrapper/node-mysql-wrapper-tests.ts
index 869aa823e..3d26b6e8b 100644
--- a/node-mysql-wrapper/node-mysql-wrapper-tests.ts
+++ b/node-mysql-wrapper/node-mysql-wrapper-tests.ts
@@ -1,4 +1,7 @@
///
+///
+///
+
var express = require('express');
var app = express();
var server = require('http').createServer(app);
@@ -9,42 +12,37 @@ class User { //or interface
userId: number;
username: string;
mail: string;
+ password:string;
comments: Comment[];
+ myComments: Comment[];
+ info: UserInfo;
}
interface Comment {
commentId: number;
content: string;
+ likes: CommentLike[];
}
+interface CommentLike {
+ commentLikeId: number;
+ userId: number;
+ commentId: number;
+}
+
+interface UserInfo {
+ userInfoId: number;
+ userId: number;
+ hometown: string;
+}
db.ready(() => {
var usersDb = db.table("users");
- usersDb.rules.orderBy("userId", true);
-
+
+ //or var usersDb = db.table("users"); if you don't want intel auto complete from your ide/editor
- usersDb.findAll().then(users=> {
- users.forEach(user=> {
- console.log(user.userId);
- });
- });
-
-
- //define new table rules: usersDb.rules.clear().orderBy....limit....groupBy...
-
- //define rules but keep unchanged (table's rules) in find method:
- usersDb.find({ yearsOld: 22 }, (_users) => {
-
- console.log("-------------------------------------------------------");
- _users.forEach(_user=> {
- console.log(_user.userId + " " + _user.username + " found with limit 3 but this doesnt...");
-
- });
-
- }).limit(3).execute();
-
usersDb.findById(16, (_user) => {
console.log("TEST1: \n");
@@ -56,20 +54,27 @@ db.ready(() => {
}, (err) => { console.log("ERROR ON FETCHING FINDBY ID: " + err) });
*/
- usersDb.find({ userId: 18, comments: { userId: '=' } }, _users=> {
-
- var _user = _users[0];
-
- console.log("TEST2: \n");
- console.log(_user.username + " with ");
- console.log(_user.comments.length + " comments ");
- _user.comments.forEach(_comment=> {
- console.log("--------------\n" + _comment.content);
+ usersDb.findSingle(
+ {
+ userId: 18,
+ myComments: {
+ userId: '=',
+ tableRules: { //NEW: SET rules to joined tables too!
+ table: "comments", //NEW SET table name inside any property u want!
+ limit: 50,
+ orderByDesc: "commentId" //give me the first 50 comments ordered by -commentId (DESC) from table 'comments' and put them at 'myComments' property inside the result object.
+ }
+ }
+ }).then(_user=> { // to get this promise use : .promise()
+ console.log("\n-------------TEST 2 ------------\n");
+ console.log(_user.username + " with ");
+ console.log(_user.myComments.length + " comments ");
+ _user.myComments.forEach(_comment=> {
+ console.log("--------------\n" + _comment.content);
+ });
});
- }).execute();
-
- usersDb.safeRemove(5620, answer=> {
+ usersDb.remove(5620, answer=> {
console.log("TEST 3: \n");
console.log(answer.affectedRows + ' (1) has removed from table: ' + answer.table);
@@ -86,8 +91,107 @@ db.ready(() => {
});
+
+ usersDb.find(
+ {
+ yearsOld: 22,
+ comments: {
+ userId: "=",
+ tableRules: {
+ limit: 2
+ }
+ }
+
+ }, (_users) => {
+
+ console.log("---------------TEST 6----------------------------------------");
+ _users.forEach(_user=> {
+ console.log(_user.userId + " " + _user.username + " found with " + _user.comments.length + " comments");
+
+ });
+
+ });
+ //if no rules setted to find method it's uses the table's rules ( if exists)
+
+
+
+ let _criteriaFromBuilder = usersDb.criteria
+ .except("password") // or .exclude(...columns). the only column you cannot except/exclude is the primary key (because it is used at where clause), be careful.
+ .where("userId", 24)
+ .joinAs("info", "userInfos", "userId")
+ .at("info")
+ .limit(1) //because we make it limit 1 it will return this result as object not as array.
+ .parent()
+ .joinAs("myComments", "comments", "userId")
+ .at("myComments").limit(2)
+ .joinAs("likes", "commentLikes", "commentId")
+ .original().orderBy("userId", true).build();
+
+ /* console.dir(_criteriaFromBuilder);
+ prints this object: ( of course you can create your own in order to pass it on .find table methods )
+ {
+ userId:23,
+
+ myComments:{
+ userId: '=',
+
+ tableRules:{
+ table: 'comments',
+ limit:2
+
+ },
+
+ likes:{
+ commentId: '=',
+
+ tableRules:{
+ table: 'commentLikes'
+ }
+
+ }
+ },
+
+ tableRules:{
+ orderByDesc: 'userId',
+ except: ['password']
+ }
+
+ }
+
+
+ */
+
+
+
+ usersDb.find(_criteriaFromBuilder).then(_users=> {
+ console.log("\n----------------\nTEST ADVANCED 1\n-------------------\n ");
+ _users.forEach(_user=> {
+ console.log(_user.userId + " " + _user.username);
+
+ if (_user.info !== undefined) {
+ console.log(' from ' + _user.info.hometown);
+ //console.dir(_user.userInfos);
+ }
+
+ if (_user.myComments !== undefined) {
+ _user.myComments.forEach(_comment=> {
+ console.log(_comment.commentId + " " + _comment.content);
+
+ if (_comment.likes !== undefined) {
+ console.log(' with ' + _comment.likes.length + ' likes!');
+ }
+ });
+ }
+ });
+
+ });
+
+
});
+server.on('uncaughtException', function(err:any) {
+ console.log(err);
+})
var httpPort = 1193;//config.get('Server.port') || 1193;
server.listen(httpPort, function() {
diff --git a/node-mysql-wrapper/node-mysql-wrapper.d.ts b/node-mysql-wrapper/node-mysql-wrapper.d.ts
index 095038faa..af100bbf4 100644
--- a/node-mysql-wrapper/node-mysql-wrapper.d.ts
+++ b/node-mysql-wrapper/node-mysql-wrapper.d.ts
@@ -1,5 +1,5 @@
// Type definitions for node-mysql-wrapper
-// Project: https://github.com/kataras/node-mysql-wrapper
+// Project: https://github.com/nodets/node-mysql-wrapper
// Definitions by: Makis Maropoulos
// Definitions: https://github.com/borisyankov/DefinitelyTyped
@@ -12,11 +12,42 @@ declare module "node-mysql-wrapper" {
import {EventEmitter} from 'events';
var EQUAL_TO_PROPERTY_SYMBOL: string;
+ var TABLE_RULES_PROPERTY: string;
+
+ type DeleteAnswer = {
+ affectedRows: number;
+ table: string;
+ };
+
+ type RawRules = {
+ table: string,
+ begin: string,
+ orderBy: string,
+ orderByDesc: string,
+ groupBy: string,
+ limit: number, // limit = limitStart =0 and limitEnd = limit.
+ limitStart: number,
+ limitEnd: number,
+ end: string
+
+ };
+
+ type TableToSearchPart = { tableName: string, propertyName: string };
interface Map {
[index: string]: T;
}
+ interface IQuery {
+ _table: Table;
+ execute(rawCriteria: any, callback?: (_results: any) => any): Promise;
+ }
+
+ interface IQueryConstructor {
+ new (_table: Table): IQuery;
+ }
+
+
class Helper {
/**
* Callback like forEach
@@ -61,9 +92,7 @@ declare module "node-mysql-wrapper" {
* @return {string}
*/
static toRowProperty(objectKey: string): string;
-
-
/**
* Iterate object's keys and return their values to the callback.
* @param {Map} map the object.
@@ -80,17 +109,38 @@ declare module "node-mysql-wrapper" {
* @returnType {U}
* @return {U}
*/
+
static forEachKey(map: Map, callback: (key: string) => U): U;
+
+ /**
+ * Checks if anything is a function.
+ * @param {functionToCheck} the object or function to pass
+ * @return boolean
+ */
+ static isFunction(functionToCheck: any): boolean;
+
+ /**
+ * Checks if an object has 'tableRules' property.
+ * @param {obj} the object to pass
+ * @return boolean
+ */
+ static hasRules(obj: any): boolean;
}
- interface ICriteria {
+
+ interface ICriteriaParts {
rawCriteriaObject: any;
- tables: string[];
+ tables: TableToSearchPart[];
noDatabaseProperties: string[];
whereClause: string;
+
+ selectFromClause(_table: Table): string;
+
}
- class Criteria implements ICriteria {
+
+
+ class CriteriaParts implements ICriteriaParts {
/**
* The raw format of the criteria eg: {yearsOld:22}.
@@ -100,7 +150,7 @@ declare module "node-mysql-wrapper" {
/**
* Which tables to search after the find method of the proto table finish.
*/
- tables: string[];
+ tables: TableToSearchPart[];
/**
* The properties of the criteria which don't belong to the database's table.
@@ -112,10 +162,12 @@ declare module "node-mysql-wrapper" {
*/
whereClause: string;
- constructor(rawCriteriaObject: any, tables: string[], noDatabaseProperties: string[], whereClause: string);
+ constructor(rawCriteriaObject: any, tables: TableToSearchPart[], noDatabaseProperties: string[], whereClause: string);
+
+ selectFromClause(_table: Table): string;
}
- class CriteriaBuilder {
+ class CriteriaDivider {
private _table;
constructor(table: Table);
@@ -125,70 +177,131 @@ declare module "node-mysql-wrapper" {
* @returnType {Criteria}
* @return {Criteria}
*/
- build(rawCriteriaObject: any): Criteria;
+ build(rawCriteriaObject: any): CriteriaParts;
}
class SelectQueryRules {
- orderByClause: string;
- groupByClause: string;
- limitClause: string;
-
-
+ private lastPropertyClauseName: string;
+ manuallyEndClause: string;
+ manuallyBeginClause: string;
+ exceptColumns: string[];
+ orderByColumn: string;
+ orderByDescColumn: string;
+ groupByColumn: string;
+ limitStart: number;
+ limitEnd: number;
+ public tableName: string; //auto den benei oute sto last, oute sto from.
static build(): SelectQueryRules;
- static build(parentRule?: SelectQueryRules): SelectQueryRules;
+ private last(propertyClauseName);
+ except(...columns: string[]): SelectQueryRules;
+
+ /**
+ * Same as .except(...columns)
+ */
+ exclude(...columns: string[]): SelectQueryRules;
orderBy(columnKey: string, descending?: boolean): SelectQueryRules;
-
groupBy(columnKey: string): SelectQueryRules;
-
limit(limitRowsOrStart: number, limitEnd?: number): SelectQueryRules;
-
+ appendToBegin(manualAfterWhereString: string): SelectQueryRules;
+ appendToEnd(manualAfterWhereString: string): SelectQueryRules;
+ append(appendToCurrent: string): SelectQueryRules;
clearOrderBy(): SelectQueryRules;
-
clearGroupBy(): SelectQueryRules;
-
clearLimit(): SelectQueryRules;
-
+ clearEndClause(): SelectQueryRules;
+ clearBeginClause(): SelectQueryRules;
clear(): SelectQueryRules;
-
from(parentRule: SelectQueryRules): SelectQueryRules;
-
+ isEmpty(): boolean;
toString(): string;
+ toRawObject(): RawRules;
+ static toString(rules: SelectQueryRules): string;
+ static toRawObject(rules: SelectQueryRules): RawRules;
+ static fromRawObject(obj: RawRules): SelectQueryRules;
}
- class SelectQuery {
+ class CriteriaBuilder{
- private _rules: SelectQueryRules;
- private _table: Table;
- private _criteriaRawJsObject: any;
- private _callback: (_results: T[]) => any;
- private callback: (resolve?: (thenableOrResult?: T | Promise.Thenable) => void, reject?: (error?: any) => void) => void;
+ private rawCriteria: any;
+ private primaryTable: Table;
+ private parentBuilder: CriteriaBuilder;
- constructor(table: Table, criteriaRawJsObject: any, callback?: (_results: T[]) => any);
+ constructor(primaryTable: Table); //to arxiko apo to Table.ts 9a benei
+ constructor(primaryTable: Table, tableName: string, parentBuilder: CriteriaBuilder);// auta 9a benoun apo to parent select query.
+ constructor(primaryTable: Table, tablePropertyName?: string, parentBuilder?: CriteriaBuilder);
- orderBy(columnKey: string, descending?: boolean): SelectQuery;
+ except(...columns: string[]): CriteriaBuilder;
+
+ /**
+ * Same as .except(...columns)
+ */
+ exclude(...columns: string[]): CriteriaBuilder;
- groupBy(columnKey: string): SelectQuery;
+ where(key: string, value: any): CriteriaBuilder;
- limit(limitRowsOrStart: number, limitEnd?: number): SelectQuery;
+ private createRulesIfNotExists(): void;
+
+ orderBy(column: string, desceding?: boolean): CriteriaBuilder;
+
+ limit(start: number, end?: number): CriteriaBuilder;
+
+ join(realTableName: string, foreignColumnName: string): CriteriaBuilder;
+
+ joinAs(tableNameProperty: string, realTableName: string, foreignColumnName: string): CriteriaBuilder;
+
+ at(tableNameProperty: string): CriteriaBuilder;
+
+ parent(): CriteriaBuilder;
+
+ original(): CriteriaBuilder;
+
+ /**
+ * Auto kanei kuklous mexri na paei sto primary table kai ekei na epistrepsei to sunoliko raw criteria gia execute i kati allo.
+ */
+ build(): any;
+
+ static from(table: Table): CriteriaBuilder
+
+ }
+
+ class SelectQuery implements IQuery { // T for Table's result type.
+
+ _table: Table
+ constructor(_table: Table);
+
+ private parseQueryResult(result: any, criteria: ICriteriaParts): Promise;
/**
- * Executes the select and returns the Promise.
- */
- promise(): Promise;
-
+ * Executes the select and returns the Promise.
+ */
+ promise(rawCriteria: any, callback?: (_results: T[]) => any): Promise;
+
/**
* Exactly the same thing as promise().
* Executes the select and returns the Promise.
- */
- execute(): Promise;
-
- then(onFulfill: (value: any[]) => any|Promise.Thenable): Promise;
- then(onFulfill: (value: T[]) => U|Promise.Thenable, onReject: (error: any) => Promise.Thenable, onProgress?: (note: any) => any): Promise;
- then(onFulfill: (value: T[]) => U|Promise.Thenable, onReject?: (error: any) => U, onProgress?: (note: any) => any): Promise;
-
+ */
+ execute(rawCriteria: any, callback?: (_results: T[]) => any): Promise;
}
+ class SaveQuery implements IQuery {
+
+ _table: Table
+ constructor(_table: Table);
+
+ execute(criteriaRawJsObject: any, callback?: (_result: T | any) => any): Promise;
+ }
+
+ class DeleteQuery implements IQuery{
+
+ _table: Table
+ constructor(_table: Table);
+
+ execute(criteriaOrID: any | number | string, callback?: (_result: DeleteAnswer) => any): Promise;
+ }
+
+
+
class Connection extends EventEmitter {
/**
@@ -325,14 +438,17 @@ declare module "node-mysql-wrapper" {
}
class Table {
- private _name;
- private _connection;
- private _columns;
- private _primaryKey;
- private _criteriaBuilder;
- private _rules;
+ private _name: string;
+ private _connection: Connection;
+ private _columns: string[];
+ private _primaryKey: string;
+ private _criteriaDivider: CriteriaDivider;
+ private _rules: SelectQueryRules;
+ private _selectQuery: SelectQuery
+ private _saveQuery: SaveQuery;
+ private _deleteQuery: DeleteQuery;
constructor(tableName: string, connection: Connection);
-
+
/**
* An array of all columns' names inside this table.
*/
@@ -355,9 +471,23 @@ declare module "node-mysql-wrapper" {
/**
* Set of the query rules that will be applied after the 'where clause' on each select query executed by this table.
+ * @return {SelectQueryRules}
*/
rules: SelectQueryRules;
+ /**
+ * Returns this table's criteria divider class.
+ * @return {CriteriaDivider}
+ */
+ criteriaDivider: CriteriaDivider;
+
+ /**
+ * Returns new Criteria Builder each time.
+ * Helps you to make criteria raw js objects ready to use in find,remove and save methods.
+ * @return {CriteriaBuilder}
+ */
+ criteria: CriteriaBuilder;
+
/**
* Adds or turn on an event listener/watcher on a table for a 'database event'.
* @param {string} evtType the event type you want to watch, one of these: ["INSERT", "UPDATE", "REMOVE", "SAVE"].
@@ -424,48 +554,31 @@ declare module "node-mysql-wrapper" {
* @return {number | string}
*/
getPrimaryKeyValue(jsObject: any): number | string;
-
- parseQueryResult(result: any, criteria: ICriteria): Promise;
/**
*
*/
- find(criteriaRawJsObject: any): SelectQuery; // only criteria
- find(criteriaRawJsObject: any, callback: ((_results: T[]) => any)): SelectQuery; // criteria and callback
- find(criteriaRawJsObject: any, callback?: (_results: T[]) => any): SelectQuery;
+ find(criteriaRawJsObject: any): Promise; // only criteria
+ find(criteriaRawJsObject: any, callback: ((_results: T[]) => any)): Promise; // criteria and callback
+ find(criteriaRawJsObject: any, callback?: (_results: T[]) => any): Promise;
+
+ findSingle(criteriaRawJsObject: any, callback?: (_result: T) => any): Promise;
findById(id: number|string): Promise; // without callback
findById(id: number | string, callback?: (result: T) => any): Promise;
- findAll(): SelectQuery; // without callback
- findAll(callback?: (_results: T[]) => any): SelectQuery;
+ findAll(): Promise; // only criteria and promise
+ findAll(tableRules: RawRules): Promise // only rules and promise
+ findAll(tableRules?: RawRules, callback?: (_results: T[]) => any): Promise;
+
save(criteriaRawJsObject: any): Promise; //without callback
save(criteriaRawJsObject: any, callback?: (_result: any) => any): Promise;
- safeRemove(id: number | string): Promise<{
- affectedRows: number;
- table: string;
- }>; //withoutcallback
- safeRemove(id: number | string, callback?: (_result: {
- affectedRows: number;
- table: string;
- }) => any): Promise<{
- affectedRows: number;
- table: string;
- }>;
+ remove(id: number | string): Promise; // ID without callback
+ remove(criteriaRawObject: any): Promise; // criteria obj without callback
+ remove(criteriaOrID: any | number | string, callback?: (_result: DeleteAnswer) => any): Promise;
- remove(criteriaRawObject: any): Promise<{
- affectedRows: number;
- table: string;
- }>; // without callback
- remove(criteriaRawJsObject: any, callback?: (_result: {
- affectedRows: number;
- table: string;
- }) => any): Promise<{
- affectedRows: number;
- table: string;
- }>;
}
class Wrapper {