├── .gitignore ├── .prettierrc ├── CONTRIBUTING.md ├── LICENSE ├── MYSQL_FUNCTIONS.md ├── README.md ├── TODO.md ├── jestconfig.json ├── package-lock.json ├── package.json ├── src ├── chego.ts ├── functions.ts ├── index.ts ├── query.ts ├── queryScheme.ts └── utils.ts ├── tsconfig.json └── tslint.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | lib/ 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # Bower dependency directory (https://bower.io/) 29 | bower_components 30 | 31 | # node-waf configuration 32 | .lock-wscript 33 | 34 | # Compiled binary addons (http://nodejs.org/api/addons.html) 35 | build/Release 36 | 37 | # Dependency directories 38 | node_modules/ 39 | jspm_packages/ 40 | 41 | # Typescript v1 declaration files 42 | typings/ 43 | 44 | # Optional npm cache directory 45 | .npm 46 | 47 | # Optional eslint cache 48 | .eslintcache 49 | 50 | # Optional REPL history 51 | .node_repl_history 52 | 53 | # Output of 'npm pack' 54 | *.tgz 55 | 56 | # Yarn Integrity file 57 | .yarn-integrity 58 | 59 | # dotenv environment variables file 60 | .env 61 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "trailingComma": "all", 4 | "singleQuote": true 5 | } -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | We love your input! We want to make contributing to this project as easy and transparent as possible so here are some guidelines: 4 | 5 | ## Reporting issues 6 | 7 | When submitting an issue please take the following steps: 8 | 9 | 1. Ensure the issue was not already reported by searching on GitHub under Issues 10 | 2. Create an isolated and reproducible test case. 11 | 3. To help us solve the problem, please describe it in detail. 12 | 13 | ## Contributing Changes 14 | 15 | If you are a team member, don't forget to update kanban boards. 16 | 17 | 1. Fork the repo and create your branch from `master`. 18 | 2. If you've added code that should be tested, add tests. 19 | 3. If you've changed APIs, update the documentation. 20 | 4. Ensure the test suite passes. 21 | 5. Make sure your code lints. 22 | 6. Issue that pull request! 23 | 24 | ## Quickie Code Style Guide 25 | 26 | - Use 4 spaces for tabs, never tab characters. 27 | - No trailing whitespace, blank lines should have no whitespace. 28 | - Always favor strict equals `===` unless you *need* to use type coercion. 29 | - Follow conventions already in the code, and listen to tslint. 30 | - Ensure changes are tslint validated. 31 | 32 | ## License 33 | By contributing, you agree that your contributions will be licensed under its MIT License. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 chegojs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MYSQL_FUNCTIONS.md: -------------------------------------------------------------------------------- 1 | # MySQL Functions 2 | 3 | [back to readme](https://github.com/chegojs/chego/blob/master/README.md#MySQL-Functions) 4 | 5 | ## List 6 | 7 | * [MySQL functions](#mysql-functions) 8 | * [`greatest`](#greatest) 9 | * [`least`](#least) 10 | * [`coalesce`](#coalesce) 11 | * [`count`](#count) 12 | * [`max`](#max) 13 | * [`min`](#min) 14 | * [`sum`](#sum) 15 | * [`avg`](#avg) 16 | * [`sqrt`](#sqrt) 17 | * [`pow`](#pow) 18 | * [`abs`](#abs) 19 | * [`acos`](#acos) 20 | * [`asin`](#asin) 21 | * [`atan`](#atan) 22 | * [`atan2`](#atan2) 23 | * [`ceil`](#ceil) 24 | * [`cos`](#cos) 25 | * [`cot`](#cot) 26 | * [`degrees`](#degrees) 27 | * [`div`](#div) 28 | * [`exp`](#exp) 29 | * [`floor`](#floor) 30 | * [`ln`](#ln) 31 | * [`log`](#log) 32 | * [`log10`](#log10) 33 | * [`log2`](#log2) 34 | * [`mod`](#mod) 35 | * [`pi`](#pi) 36 | * [`radians`](#radians) 37 | * [`rand`](#rand) 38 | * [`round`](#round) 39 | * [`sign`](#sign) 40 | * [`sin`](#sin) 41 | * [`tan`](#tan) 42 | * [`truncate`](#truncate) 43 | * [`ascii`](#ascii) 44 | * [`charLength`](#charLength) 45 | * [`concat`](#concat) 46 | * [`concatWs`](#concatWs) 47 | * [`field`](#field) 48 | * [`findInSet`](#findInSet) 49 | * [`format`](#format) 50 | * [`insert`](#insert) 51 | * [`instr`](#instr) 52 | * [`lcase`](#lcase) 53 | * [`left`](#left) 54 | * [`length`](#length) 55 | * [`lpad`](#lpad) 56 | * [`ltrim`](#ltrim) 57 | * [`mid`](#mid) 58 | * [`position`](#position) 59 | * [`repeat`](#repeat) 60 | * [`replace`](#replace) 61 | * [`reverse`](#reverse) 62 | * [`right`](#right) 63 | * [`rpad`](#rpad) 64 | * [`rtrim`](#rtrim) 65 | * [`space`](#space) 66 | * [`strcmp`](#strcmp) 67 | * [`substr`](#substr) 68 | * [`substrIndex`](#substrIndex) 69 | * [`trim`](#trim) 70 | * [`ucase`](#ucase) 71 | * [`bin`](#bin) 72 | * [`binary`](#binary) 73 | 74 | 75 | ## MySQL Functions 76 | 77 | #### `greatest` 78 | With two or more arguments, returns the maximum-valued argument. 79 | 80 | Default alias is `GREATEST()` 81 | ``` 82 | // greatest(keys: StringOrProperty[], alias?: string): FunctionData 83 | select(greatest([1,3,5,88,2])) ... 84 | ``` 85 | 86 | #### `least` 87 | Returns the smallest value of the list of given arguments. 88 | 89 | Default alias is `LEAST()` 90 | ``` 91 | // least(keys: StringOrProperty[], alias?: string): FunctionData 92 | select(least([1,2,3,4,5,6)) ... 93 | ``` 94 | 95 | #### `coalesce` 96 | Returns the first non-NULL argument. In case all arguments are NULL, the COALESCE function returns NULL. 97 | 98 | Default alias is `COALESCE()` 99 | ``` 100 | // coalesce(keys: StringOrProperty[], alias?: string): FunctionData 101 | select(coalesce(['foo','bar'])) ... 102 | ``` 103 | 104 | #### `count` 105 | Returns the number of rows in a table. 106 | 107 | Default alias is `COUNT()` 108 | ``` 109 | // count(key: StringOrProperty, alias?: string): FunctionData 110 | select(count(['publishers'])) ... 111 | ``` 112 | 113 | #### `max` 114 | Returns the maximum value in a set of values. 115 | 116 | Default alias is `MAX()` 117 | ``` 118 | // max(key: StringOrProperty, alias?: string): FunctionData 119 | select(max(['points'])) ... 120 | ``` 121 | 122 | #### `min` 123 | Returns the minimum value in a set of values. 124 | 125 | Default alias is `MIN()` 126 | ``` 127 | // min(key: StringOrProperty, alias?: string): FunctionData 128 | select(min(['points'])) ... 129 | ``` 130 | 131 | #### `sum` 132 | Returns the sum of a set of values. 133 | 134 | Default alias is `SUM()` 135 | ``` 136 | // sum(key: StringOrProperty, alias?: string): FunctionData 137 | select(sum(['points'])) ... 138 | ``` 139 | 140 | #### `avg` 141 | Returns the average value of a set of values 142 | 143 | Default alias is `AVG()` 144 | ``` 145 | // avg(key: StringOrProperty, alias?: string): FunctionData 146 | select(avg(['points'])) ... 147 | ``` 148 | 149 | #### `sqrt` 150 | Returns the square root of value 151 | 152 | Default alias is `SQRT()` 153 | ``` 154 | // sqrt(key: StringOrProperty, alias?: string): FunctionData 155 | select(sqrt(['points'])) ... 156 | ``` 157 | 158 | #### `pow` 159 | Returns the argument raised to the specified power. 160 | 161 | Default alias is `POW()` 162 | ``` 163 | // pow(key: StringOrProperty, exponent: number, alias?: string): FunctionData 164 | select(pow(['points'],5)) ... 165 | ``` 166 | 167 | #### `abs` 168 | Return the absolute value of a number. 169 | 170 | Default alias is `ABS()` 171 | ``` 172 | // abs(value: any, alias?: string): AbsData 173 | select(abs(123.12)) ... 174 | ``` 175 | 176 | #### `acos` 177 | Return the arc cosine of a number. 178 | 179 | Default alias is `ACOS()` 180 | ``` 181 | // acos(value: any, alias?: string): AcosData 182 | select(acos(0.5)) ... 183 | ``` 184 | 185 | #### `asin` 186 | Return the arc sine of a number. 187 | 188 | Default alias is `ASIN()` 189 | ``` 190 | // asin(value: any, alias?: string): AsinData 191 | select(asin(0.5)) ... 192 | ``` 193 | 194 | #### `atan` 195 | Return the arc tangent of a number. 196 | 197 | Default alias is `ATAN()` 198 | ``` 199 | // atan(value: any, alias?: string): AtanData 200 | select(atan(0.5)) ... 201 | ``` 202 | 203 | #### `atan2` 204 | Return the arc tangent of two values. 205 | 206 | Default alias is `ATAN2()` 207 | ``` 208 | // atan2(y: any, x: any, alias?: string): Atan2Data 209 | select(atan2(0.5, 1)) ... 210 | ``` 211 | 212 | #### `ceil` 213 | Return the smallest integer value that is greater than or equal to the number 214 | 215 | Default alias is `CEIL()` 216 | ``` 217 | // ceil(value: any, alias?: string): CeilData 218 | select(ceil(34.56)) 219 | ``` 220 | 221 | #### `cos` 222 | Return the cosine of a number 223 | 224 | Default alias is `COS()` 225 | ``` 226 | // cos(value: any, alias?: string): CosData 227 | select(cos(12)) ... 228 | ``` 229 | 230 | #### `cot` 231 | Return the cotangent of a number 232 | 233 | Default alias is `COT()` 234 | ``` 235 | // cot(value: any, alias?: string): CotData 236 | select(cot(12)) ... 237 | ``` 238 | 239 | #### `degrees` 240 | Convert the radian value into degrees 241 | 242 | Default alias is `DEGREES()` 243 | ``` 244 | // degrees(value: any, alias?: string): DegreesData 245 | select(degrees(1.5)) ... 246 | ``` 247 | 248 | #### `div` 249 | Integer division 250 | 251 | Default alias is `DIV()` 252 | ``` 253 | // div(x: any, y: any, alias?: string): DivData 254 | select(div(4, 2)) ... 255 | ``` 256 | 257 | #### `exp` 258 | Return e raised to the power of the number 259 | 260 | Default alias is `EXP()` 261 | ``` 262 | // exp(value: any, alias?: string): ExpData 263 | select(exp(1)) ... 264 | ``` 265 | 266 | #### `floor` 267 | Return the largest integer value that is less than or equal to the number 268 | 269 | Default alias is `FLOOR()` 270 | ``` 271 | // floor(value: any, alias?: string): FloorData 272 | select(floor(123.456)) ... 273 | ``` 274 | 275 | #### `ln` 276 | Return the natural logarithm of the number 277 | 278 | Default alias is `LN()` 279 | ``` 280 | // ln(value: any, alias?: string): LnData 281 | select(ln(4)) ... 282 | ``` 283 | 284 | #### `log` 285 | Return the natural logarithm of the number 286 | 287 | Default alias is `LOG()` 288 | ``` 289 | // log(value: any, alias?: string): LogData 290 | select(log(2)) ... 291 | ``` 292 | 293 | #### `log10` 294 | Return the base-10 logarithm of the number 295 | 296 | Default alias is `LOG110()` 297 | ``` 298 | // log10(value: any, alias?: string): Log10Data 299 | select(log10(2)) ... 300 | ``` 301 | 302 | #### `log2` 303 | Return the base-2 logarithm of the number 304 | 305 | Default alias is `LOG2()` 306 | ``` 307 | // log2(value: any, alias?: string): Log2Data 308 | select(log2(6)) ... 309 | ``` 310 | 311 | #### `mod` 312 | Return the remainder of x/y 313 | 314 | Default alias is `MOD()` 315 | ``` 316 | // mod(x: any, y: any, alias?: string): ModData 317 | select(mod(4, 2)) ... 318 | ``` 319 | 320 | #### `pi` 321 | Return the value of PI 322 | 323 | Default alias is `PI()` 324 | ``` 325 | // pi(alias?: string): PiData 326 | select(pi()) ... 327 | ``` 328 | 329 | #### `radians` 330 | Convert a degree value into radians 331 | 332 | Default alias is `RADIANS()` 333 | ``` 334 | // radians(value: any, alias?: string): RadiansData 335 | select(radians(125)) ... 336 | ``` 337 | 338 | #### `rand` 339 | Return a random decimal number between 0 and 1 340 | 341 | Default alias is `RAND()` 342 | ``` 343 | // rand(value: any, alias?: string): RandData 344 | select(rand()) ... 345 | ``` 346 | 347 | #### `round` 348 | Round the number to `n` decimal places 349 | 350 | Default alias is `ROUND()` 351 | ``` 352 | // round(value: any, decimal: number, alias?: string): RoundData 353 | select(round(123.456, 2)) ... 354 | ``` 355 | 356 | #### `sign` 357 | Return the sign of a number 358 | 359 | Default alias is `SIGN()` 360 | ``` 361 | // sign(value: any, alias?: string): SignData 362 | select(sign(221.24)) ... 363 | ``` 364 | 365 | #### `sin` 366 | Return the sine of a number 367 | 368 | Default alias is `SIN()` 369 | ``` 370 | // sin(value: any, alias?: string): SinData 371 | select(sin(5)) ... 372 | ``` 373 | 374 | #### `tan` 375 | Return the tangent of a number 376 | 377 | Default alias is `TAN()` 378 | ``` 379 | // tan(value: any, alias?: string): TanData 380 | select(tan(1.75)) ... 381 | ``` 382 | 383 | #### `truncate` 384 | Return a number truncated to `n` decimal places 385 | 386 | Default alias is `TRUNCATE()` 387 | ``` 388 | // truncate(value: any, alias?: string): TruncateData 389 | select(truncate(135.375, 2)) ... 390 | ``` 391 | 392 | #### `ascii` 393 | Return the ASCII value of the first character in string 394 | 395 | Default alias is `ASCII()` 396 | ``` 397 | // ascii(value: any, alias?: string): AsciiData 398 | select(ascii("Hulk")) ... 399 | ``` 400 | 401 | #### `charLength` 402 | Return the length of the string 403 | 404 | Default alias is `CHAR_LENGTH()` 405 | ``` 406 | // charLength(value: any, alias?: string): CharLengthData 407 | select(charLength("LUKE CAGE")) ... 408 | ``` 409 | 410 | #### `concat` 411 | Add several strings together 412 | 413 | Default alias is `CONCAT()` 414 | ``` 415 | // concat(values: any[], alias?: string): ConcatData 416 | select(concat("Spider","-","man")) ... 417 | ``` 418 | 419 | #### `concatWs` 420 | Add several expressions together, and add a separator between them 421 | 422 | Default alias is `CONCAT_WS()` 423 | ``` 424 | // concatWs(separator: string, values: any[], alias?: string): ConcatWsData 425 | select(concatWs("-", "Spider","man")) ... 426 | ``` 427 | 428 | #### `field` 429 | Return the index position of the substring in the string list 430 | 431 | Default alias is `FIELD()` 432 | ``` 433 | // field(search: any, values: any[], alias?: string): FieldData 434 | select(field("Wonder", "Batgirl", "Wonderwoman", "Supergirl")) ... 435 | ``` 436 | 437 | #### `findInSet` 438 | Search for the substring within the list of strings 439 | 440 | Default alias is `FIND_IN_SET()` 441 | ``` 442 | // findInSet(search: any, set: string, alias?: string): FindInSetData 443 | select(findInSet("Wonder", "Batgirl, Wonderwoman, Supergirl")) ... 444 | ``` 445 | 446 | #### `format` 447 | Format the number as "#,###,###.##" 448 | 449 | Default alias is `FORMAT()` 450 | ``` 451 | // format(value: any, decimal: number, alias?: string): FormatData 452 | select(format(250500.5634, 2)) ... 453 | ``` 454 | 455 | #### `insert` 456 | Insert the string into the another string. Replace the `n` characters 457 | 458 | Default alias is `INSERT()` 459 | ``` 460 | // insert(value: string, position: number, length: number, toInsert: any, alias?: string): InsertData 461 | select(insert("Superman", 1, 5, "Bat")) ... 462 | ``` 463 | 464 | #### `instr` 465 | Search for substring in string, and return position 466 | 467 | Default alias is `INSTR()` 468 | ``` 469 | // instr(value: any, search: any, alias?: string): InstrData 470 | select(instr("Ironman", "man")) ... 471 | ``` 472 | 473 | #### `lcase` 474 | Convert the text to lower-case 475 | 476 | Default alias is `LCASE()` 477 | ``` 478 | // lcase(value: any, alias?: string): LcaseData 479 | select(lcase("KEEP CALM AND CALL BATMAN")) ... 480 | ``` 481 | 482 | #### `left` 483 | Extract `n` characters from a string (starting from left) 484 | 485 | Default alias is `LEFT()` 486 | ``` 487 | // left(value: any, charsCount: number, alias?: string): LeftData 488 | select(left("Batgirl", 3)) ... 489 | ``` 490 | 491 | #### `length` 492 | Return the length of the string, in bytes 493 | 494 | Default alias is `LENGTH()` 495 | ``` 496 | // length(value: any, alias?: string): LengthData 497 | select(length("Loki")) ... 498 | ``` 499 | 500 | #### `lpad` 501 | Left-pad the string with string, to a total length of `n` 502 | 503 | Default alias is `LPAD()` 504 | ``` 505 | // lpad(value: any, length: number, value2: any, alias?: string): LPadData 506 | select(lpad("Why so serious?", 40, "Ha ")) ... 507 | ``` 508 | 509 | #### `ltrim` 510 | Remove leading spaces from a string 511 | 512 | Default alias is `LTRIM()` 513 | ``` 514 | // ltrim(value: any, alias?: string): LTrimData 515 | select(ltrim(" Hawkeye")) ... 516 | ``` 517 | 518 | #### `mid` 519 | Extract a substring from a string 520 | 521 | Default alias is `MID()` 522 | ``` 523 | // mid(value: any, start: number, length: number, alias?: string): MidData 524 | select(mid("The amazing spiderman", 5, 7)) ... 525 | ``` 526 | 527 | #### `position` 528 | Search for a substring in string, and return position 529 | 530 | Default alias is `POSITION()` 531 | ``` 532 | // position(substring: any, value: any, alias?: string): PositionData 533 | select(position("girls", "Gotham girls")) ... 534 | ``` 535 | 536 | #### `repeat` 537 | Repeat a string `n` times 538 | 539 | Default alias is `REPEAT()` 540 | ``` 541 | // repeat(value: any, count: number, alias?: string): RepeatData 542 | select(repeat("POW",3)) ... 543 | ``` 544 | 545 | #### `replace` 546 | Replace a string 547 | 548 | Default alias is `REPLACE()` 549 | ``` 550 | // replace(value: any, from: any, to: any, alias?: string): ReplaceData 551 | select(replace("Iron fist"," fist", "man")) ... 552 | ``` 553 | 554 | #### `reverse` 555 | Reverse a string 556 | 557 | Default alias is `REVERSE()` 558 | ``` 559 | // reverse(value: any, alias?: string): ReverseData 560 | select(reverse("Thor")) ... 561 | ``` 562 | 563 | #### `right` 564 | Extract 4 characters from a string (starting from right) 565 | 566 | Default alias is `RIGHT()` 567 | ``` 568 | // right(value: any, charsCount: number, alias?: string): RightData 569 | select(right("Batman is cool",4)) ... 570 | ``` 571 | 572 | #### `rpad` 573 | Right-pad the string with "NA NA NA", to a total length of 30 574 | 575 | Default alias is `RPAD()` 576 | ``` 577 | // rpad(value: any, length: number, value2: any, alias?: string): RPadData 578 | select(rpad("BATMAN", 30, "NA NA NA")) ... 579 | ``` 580 | 581 | #### `rtrim` 582 | Remove trailing spaces from a string 583 | 584 | Default alias is `RTRIM()` 585 | ``` 586 | // rtrim(value: any, alias?: string): RTrimData 587 | select(rtrim("Robin is ")) ... 588 | ``` 589 | 590 | #### `space` 591 | Return a string with `n` space characters 592 | 593 | Default alias is `SPACE()` 594 | ``` 595 | // space(value: number, alias?: string): SpaceData 596 | select(space(5)) ... 597 | ``` 598 | 599 | #### `strcmp` 600 | Compare two strings 601 | 602 | Default alias is `STRCMP()` 603 | ``` 604 | // strcmp(value: any, value2: any, alias?: string): StrcmpData 605 | select(strcmp("wakanda", "forever")) ... 606 | ``` 607 | 608 | #### `substr` 609 | Extract a substring from a string 610 | 611 | Default alias is `SUBSTR()` 612 | ``` 613 | // substr(value: any, start: number, length: number, alias?: string): SubstrData 614 | select(substr("Dr. Strange", 1, 3)) ... 615 | ``` 616 | 617 | #### `substrIndex` 618 | Return a substring of a string before a specified number of delimiter occurs 619 | 620 | Default alias is `SUBSTRING_INDEX()` 621 | ``` 622 | // substrIndex(value: any, delimiter: string, count: number, alias?: string): SubstrIndexData 623 | select(substrIndex("spider-man", "-", 1)) ... 624 | ``` 625 | 626 | #### `trim` 627 | Remove leading and trailing spaces from a string 628 | 629 | Default alias is `TRIM()` 630 | ``` 631 | // trim(value: any, alias?: string): TrimData 632 | select(trim(" HULK SMASH ")) ... 633 | ``` 634 | 635 | #### `ucase` 636 | Convert the text to upper-case 637 | 638 | Default alias is `UCASE()` 639 | ``` 640 | // ucase(value: any, alias?: string): UcaseData 641 | select(ucase("i am ironman")) ... 642 | ``` 643 | 644 | #### `bin` 645 | Return a binary representation of the value. 646 | 647 | Default alias is `BIN()` 648 | ``` 649 | // bin(value: any, alias?: string): BinData 650 | select(bin("Ironman")) ... 651 | ``` 652 | 653 | #### `binary` 654 | Convert a value to a binary string. 655 | 656 | Default alias is `BINARY()` 657 | ``` 658 | // binary(value: any, alias?: string): BinaryData 659 | select(binary("Batman")) ... 660 | ``` 661 | 662 | *Soon there will be more, the list is still growing.* 663 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # chego 2 | 3 | Chego is a lightweight Javascript library written in TypeScript. 4 | The goal of this project is to provide tools to create an easy-to-use, portable, and readable code of database application. 5 | All the magic is just using one of the defined database drivers and its config. The rest of the code is independent of the selected database type. 6 | 7 | Check the following database drivers: 8 | * [MySQL](https://github.com/chegojs/chego-mysql) 9 | * [Firebase](https://github.com/chegojs/chego-firebase) 10 | * [MongoDB](https://github.com/chegojs/chego-mongodb) 11 | * [PostgreSQL](https://github.com/chegojs/chego-postgresql) 12 | * [SQLite](https://github.com/chegojs/chego-sqlite) 13 | 14 | ## Table of contents 15 | 16 | * [Install](#install) 17 | * [Usage](#usage) 18 | * [Tips](#tips) 19 | * [Choosing columns/properties](#choosing-columns/properties) 20 | * [Selecting from multiple tables](#Selecting-from-multiple-tables) 21 | * [Using `table.key` pattern](#Using-table.key-pattern) 22 | * [Multiple properties in `where` clause](#Multiple-properties-in-where-clause) 23 | * [Use `and()` and `or()` helpers](#use-and()-and-or()-helpers) 24 | * [Nesting `LogicalOperatorScope` objects](#Nesting-LogicalOperatorScope-objects) 25 | * [Logical operators](#Logical-operators) 26 | * [Grouping results](#Grouping-results) 27 | * [Sorting results](#Sorting-results) 28 | * [Alias expression](#Alias-expression) 29 | * [Wrapping query parts](#Wrapping-query-parts) 30 | * [Testing subqueries with `Exists` operator](#Testing-subqueries-with-Exists-operator) 31 | * [Setting filter condition for groups of rows with `Having` clause](#Setting-filter-condition-for-groups-of-rows-with-Having-clause) 32 | * [Unions](#unions) 33 | * [Checking if specified value matches any value with `In` operator](#Checking-if-specified-value-matches-any-value-with-In-operator) 34 | * [Testing values with `Like` operator](#Testing-values-with-Like-operator) 35 | * [API](#api) 36 | * [`IChego`](#ichego) 37 | * [`IQuery`](#iquery) 38 | * [Primary functions](#primary-functions) 39 | * [`newChego`](#newChego) 40 | * [`newQuery`](#newQuery) 41 | * [Helpers](#helpers) 42 | * [`rowId`](#rowId) 43 | * [`alias`](#alias) 44 | * [`and/or`](#and/or) 45 | * [`withCustomId`](#withCustomId) 46 | * [MySQL functions](#mysql-functions) 47 | * [Examples](#examples) 48 | * [Selecting data](#Selecting-data) 49 | * [Updating data](#Updating-data) 50 | * [Removing rows](#Removing-rows) 51 | * [Inserting data](#Inserting-data) 52 | * [Joining queries](#Joining-queries) 53 | * [Like](#Like) 54 | * [Unions](#Unions) 55 | * [In](#In) 56 | * [Having](#Having) 57 | * [Exists](#Exists) 58 | * [Contribute](#Contribute) 59 | * [License](#License) 60 | 61 | ## Install 62 | ``` 63 | npm install --save @chego/chego 64 | ``` 65 | 66 | ## Usage 67 | 68 | Usage is very simple once you decide which type of database you want to use, just pass it to `newChego()` function with its config and voila! You can create queries with `newQuery` and execute them using `chego` object. 69 | 70 | ``` 71 | const { newChego, newQuery } = require("@chego/chego"); 72 | const { } = require("@chego/chego-"); 73 | 74 | const chego = newChego( ,{ 75 | ...database config... 76 | }); 77 | const query = newQuery().select('*').from('superheroes','villains').where('origin').is.eq('Gotham City').limit(10); 78 | 79 | await chego.connect(); 80 | 81 | chego.execute(query) 82 | .then(result => { 83 | console.log('RESULT:', JSON.stringify(result)); 84 | chego.disconnect(); 85 | }) 86 | .catch(error => { 87 | console.log('ERROR:', error); 88 | chego.disconnect(); 89 | }); 90 | 91 | ``` 92 | 93 | ## Tips 94 | 95 | #### Choosing columns/properties 96 | ``` 97 | select().from('superheroes'); // selects all columns/properties 98 | select('*').from('superheroes'); // selects all columns/properties 99 | select('name', 'origin').from('superheroes'); // selects only 'name' and 'origin' 100 | ``` 101 | #### Selecting from multiple tables 102 | ``` 103 | select().from('superheroes','villains') ... 104 | ``` 105 | 106 | #### Using `table.key` pattern 107 | If you are referring to different tables in your query - in non MySQL database. It's better to use the `table.key` patteny then. This will save time and trouble, as any property without a defined table, will be filled with the first table defined in the `from` clause - in the further stage of processing the query. 108 | 109 | In single table queries or MySQL driver this is not an issue but in other cases, you should consider using it. 110 | ``` 111 | select().from('superheroes','villains').where('superheroes.name') 112 | ``` 113 | 114 | #### Multiple properties in `where` clause 115 | By default all properties in `where` clause are wrapped with `and()`. 116 | ``` 117 | where('name', 'foo', 'bar') 118 | // will become in the further stage of processing the query 119 | where(and('name', 'foo', 'bar')) 120 | ``` 121 | 122 | #### Use `and()` and `or()` helpers 123 | With `and()` and `or()` helpers you can sinplify your queries 124 | ``` 125 | where(or('foo','bar')).are.eq(1) === where('foo').or.where('bar').are.eq(1) 126 | 127 | where(and('foo','bar')).are.eq(or(1,2)) === where('foo').and.where('bar').are.eq(1).or.eq(2) 128 | ``` 129 | 130 | #### Nesting `LogicalOperatorScope` objects 131 | It is possible to create `LogicalOperatorScope` objects inside another `LogicalOperatorScope` object, which allows you to use more complex conditions. 132 | ``` 133 | where(and('foo', or('bar','baz'))).are.eq('cool') 134 | // will be parsed to 135 | (foo === 'cool' && (bar === 'cool' || baz === 'cool')) 136 | ``` 137 | 138 | #### Logical operators 139 | Write queries the way you want. 140 | ``` 141 | // query with logical operator 142 | query.select('*').from('comics').where('writer').is.eq('Stan Lee', or('Bob Kane')); 143 | 144 | // query without logical operator 145 | query.select('*').from('comics').where('writer').is.eq('Stan Lee').or.is.eq('Bob Kane'); 146 | ``` 147 | Use logical operators to simplify your queries. 148 | ``` 149 | // query with logical operator 150 | query.select('*').from('comics').where('writer', or('editor')).is.eq('Stan Lee'); 151 | 152 | // queries without logical operator 153 | query.select('*').from('comics').where('writer').or.where('editor').are.eq('Stan Lee'); 154 | 155 | query.select('*').from('comics').where('writer').is.eq('Stan Lee').or.where('editor').is.eq('Stan Lee'); 156 | ``` 157 | 158 | #### Grouping results 159 | Like in *MySQL* the `groupBy` clause groups a set of rows into a set of summary rows by values of columns. It returns one row for each group. Also like in *MySQL* it is possible to sort the groups in ascending or descending orders. 160 | 161 | The default sort order is set in ascending order. 162 | ``` 163 | groupBy('foo ASC') 164 | // or 165 | groupBy('foo') 166 | 167 | // multiple values 168 | groupBy('foo DESC', 'bar ASC', 'baz') 169 | ``` 170 | 171 | #### Sorting results 172 | Like in *MySQL* it is possible to sort a query results by a single column or multiple columns in ascending or descending order. 173 | ``` 174 | orderBy('foo ASC') 175 | // or 176 | orderBy('foo') 177 | 178 | // multiple values 179 | orderBy('foo DESC', 'bar ASC', 'baz') 180 | ``` 181 | #### Alias expression 182 | It is possible to create `alias` property with *"alias expression"* (`' AS '`). 183 | ``` 184 | query.select('alterEgo AS knownAs').from('superheroes'); 185 | ``` 186 | Although using *"alias expression"* is less efficient because in the end it is parsed to `alias` property. 187 | 188 | #### Wrapping query parts 189 | `Chego` API contains a specific `inParentheses()` clause. You can use it to place selected parts of the query in parentheses. It has been implemented for complex conditions. 190 | ``` 191 | query.select('name').from('superheroes').where('origin').is.equalTo('New York City').and.inParentheses( 192 | (query) => query.where('teamAffiliation').is.equalTo("Avengers") 193 | .or.where('teamAffiliation').is.equalTo('Defenders') 194 | ).limit(10) 195 | 196 | // conditions formula 197 | // (origin === 'New York City' && (teamAffiliation === 'Avengers' || teamAffiliation === 'Defenders')) 198 | ``` 199 | 200 | #### Running multiple queries in one call 201 | You can pass a set of queries and execute them synchronously in one call, but will return results only from the last query. For this reason, you should not combine the `SELECT` query set. This function has been designed to run `transactions` in` chego-mysql`. In `firebase` it is only synchronized calls without the possibility of rollback in case of failure of one of the queries. 202 | ``` 203 | ... 204 | const query1 = newQuery().insert({ 205 | name: "Thanos", 206 | alterEgo: "", 207 | origin: "Titan", 208 | publisher: "mcUT642", 209 | createdBy: [ 210 | "jsTR612" 211 | ], 212 | firstAppearance: "tiIM771" 213 | }).to('villains'); 214 | 215 | const query2 = newQuery().select('*').from('villains').limit(10); 216 | 217 | chego.execute(query1, query2) 218 | .then(result => { 219 | ... 220 | }) 221 | .catch(error => { 222 | ... 223 | }); 224 | ``` 225 | #### Testing subqueries with `Exists` operator 226 | 227 | The *MySQL EXISTS* operator is a Boolean operator that returns either true or false. The *EXISTS* operator is often used the in a subquery to test for an *exist* condition. 228 | 229 | More information about *MySQL EXISTS* operator can be found [here](http://www.mysqltutorial.org/mysql-exists/) 230 | 231 | #### Setting filter condition for groups of rows with `Having` clause 232 | 233 | The `having` clause is often used with the `groupBy` clause to filter groups based on a specified condition. More information about *MySQL HAVING* clause can be found [here](http://www.mysqltutorial.org/mysql-having.aspx). In `chego`, `having` clause is available only as a succession of the `groupBy` clause. 234 | 235 | #### Unions 236 | 237 | Known from *MySQL UNION* operator allows you to combine two or more result sets of queries into a single result set. `Chego` API contains two union methods: 238 | * `union`: which imitates *MySQLs* `UNION DISTINCT` default `UNION` 239 | * `unionAll`: which imitates *MySQLs* `UNION ALL` 240 | 241 | More information about *MySQL UNION* operator can be found [here](http://www.mysqltutorial.org/sql-union-mysql.aspx) 242 | 243 | #### Checking if specified value matches any value with `In` operator 244 | 245 | The *MySQL IN* operator allows you to determine if a specified value matches any value in a set of values or returned by a subquery. More information about *MySQL IN* operator can be found [here](http://www.mysqltutorial.org/sql-in.aspx) 246 | 247 | #### Testing values with `Like` operator 248 | 249 | The *MySQL LIKE* operator is a logical operator that tests whether a string contains a specified pattern or not. MySQL provides two wildcard characters for constructing patterns: percentage `%` and underscore `_`. 250 | * The percentage ( % ) wildcard matches any string of zero or more characters. 251 | * The underscore ( _ ) wildcard matches any single character. 252 | 253 | More information about *MySQL LIKE* operator can be found [here](http://www.mysqltutorial.org/mysql-like/) 254 | 255 | ## API 256 | 257 | #### `IChego` 258 | `execute(...queries: IQuery[]): Promise` - uses defined database driver to parse and execute given queries. It returns `Promise` with query results or `Error`. 259 | 260 | `connect(): Promise` - establishes a connection. 261 | 262 | `disconnect(): Promise` - terminates a connection. 263 | 264 | #### `IQuery` 265 | It extends `IQueryMethods` to provide fluent interface for builder. More details can be found [here](https://github.com/chegojs/chego-api/blob/master/src/interfaces.ts#L9). 266 | 267 | `scheme: IQueryScheme` - returns query scheme object. More details can be found [here](https://github.com/chegojs/chego-api/blob/master/src/interfaces.ts#L9). 268 | 269 | ## Primary functions 270 | 271 | #### `newChego` 272 | ``` 273 | newChego(driver:Fn, config:object): IChego 274 | ``` 275 | Initializes database driver and returns new `Chego` object. 276 | 277 | #### `newQuery` 278 | ``` 279 | newQuery(): IQuery 280 | ``` 281 | Returns new query scheme builder. 282 | 283 | ## Helpers 284 | 285 | #### `rowId` 286 | ``` 287 | rowId(table?:string, alias?: string): Property 288 | ``` 289 | Some NoSQL data stores do not contain a primary key inside records. With `rowId` you can get the record key and attach it to the schema. You can also search / filter records by primary key. 290 | 291 | The default value for the argument `alias` is `'id'` 292 | 293 | The default `table` is the first table used in clause `to()`, `update()` or `from()`. You will need to define `table`, if you want to use a primary keys from different tables in your query. 294 | 295 | In the `on()` clause, rowId has a default value for the table argument, which is valid for `keyA` or `keyB`. 296 | 297 | ``` 298 | query.select('*').from('superheroes').where('publisher').is.eq((query) => { query.select(rowId()).from('publishers').where('name').is.eq('Marvel Comics') }); 299 | ``` 300 | 301 | #### `alias` 302 | ``` 303 | alias(name: string, alias: string): Property 304 | ``` 305 | It is used to give the property a temporary name. 306 | 307 | ``` 308 | query.select(alias('alterEgo', 'knownAs')).from('superheroes'); 309 | ``` 310 | 311 | #### `and/or` 312 | ``` 313 | and/or(...properties: AnyButFunction[]): LogicalOperatorScope 314 | ``` 315 | Creates new logical operator scope, which means that all given properties will be set in an "scope" array. In the further stage of processing the query, this array is parsed - with given values - to conditional expression. 316 | ``` 317 | where(or('foo', 'bar')).is.eq(1) 318 | // will be parsed to 319 | (foo === 1 || bar === 1) 320 | ``` 321 | 322 | `and()`, `or()` can be used in the `where` clause and within the conditions: `eq`, `lt` and` gt`. 323 | 324 | #### `withCustomId` 325 | ``` 326 | withCustomId("custom id", {foo:"bar"}): ItemWithCustomId 327 | ``` 328 | **Currently implemented for Firebase.** Use this if you want to add an entry under the defined id. 329 | ``` 330 | query.insert(withCustomId("Foo", { foo:"bar" })).to('...'); 331 | ``` 332 | 333 | ## MySQL Functions 334 | 335 | In `Chego` you can use some of the functions - [list](https://github.com/chegojs/chego/blob/master/MYSQL_FUNCTIONS.md) - known from MySQL. 336 | 337 | ## Examples 338 | 339 | #### Selecting data 340 | ``` 341 | query.select('title', 'nr).from('comics').orderBy('published DESC'); 342 | ``` 343 | #### Updating data 344 | ``` 345 | query.update('superheroes').set({superPowers:[]}).where('name').is.eq('Punisher'); 346 | ``` 347 | #### Removing rows 348 | ``` 349 | query.delete().from('villains').where('origin').is.not.eq('Gotham City'); 350 | ``` 351 | #### Inserting data 352 | ``` 353 | query.insert({ 354 | name: "Batman", 355 | alterEgo: "Bruce Wayne", 356 | origin: "Gotham City", 357 | publisher: "dcZP373", 358 | createdBy: [ 359 | "bkOO872", 360 | "bfOU542" 361 | ], 362 | firstAppearance: "acUW996" 363 | },{ 364 | name: "Spiderman", 365 | alterEgo: "Peter Benjamin Parker", 366 | origin: "New York City", 367 | publisher: "mcUT642", 368 | createdBy: [ 369 | "plTW543", 370 | "ghIO920" 371 | ], 372 | firstAppearance: "afUQ256" 373 | }).to('superheroes'); 374 | ``` 375 | 376 | #### Nested queries 377 | ``` 378 | query.select('*').from('superheroes').where('publisher').is.eq( 379 | (query) => query.select('id').from('publishers') 380 | .where('name').is.eq('Marvel Comics') 381 | ).limit(100); 382 | ``` 383 | 384 | #### Joining queries 385 | ``` 386 | // join 387 | query.select('*').from('comics').join('publishers').on('publishers.id', 'comics.publisher').limit(10); 388 | // left join 389 | query.select('*').from('comics').leftJoin('publishers').on('publishers.id', 'comics.publisher').limit(10); 390 | // right join 391 | query.select('*').from('comics').rightJoin('publishers').on('publishers.id', 'comics.publisher').limit(10); 392 | // full join 393 | query.select('*').from('comics').fullJoin('publishers').on('publishers.id', 'comics.publisher').limit(10); 394 | 395 | // using 396 | query.select('*').from('superheroes').join('villains').using('id').limit(10); 397 | ``` 398 | #### Like 399 | ``` 400 | // like 401 | query.select('*').from('superheroes').where('name').is.like('%man'); // Batman, Superman ... 402 | query.select('*').from('superheroes').where('name').is.like('Iron%'); // Ironman, Iron fist ... 403 | query.select('*').from('superheroes').where('name').is.like('Hu__'); // Hulk 404 | query.select('*').from('superheroes').where('name').is.like('S%n'); // Spiderman, Superman ... 405 | 406 | // not like 407 | query.select('*').from('superheroes').where('name').is.not.like('%man'); // Batman, Superman ... 408 | ``` 409 | 410 | #### Unions 411 | ``` 412 | // union - distinct 413 | query.select('name').from('superheroes').union((q)=>q.select('name).from('villains')); 414 | // union - all 415 | query.select('name').from('superheroes').unionAll((q)=>q.select('name).from('villains')); 416 | ``` 417 | 418 | #### In 419 | ``` 420 | // in 421 | query.select('*').from('publishers').where('country').is.in('US'); 422 | // not in 423 | query.select('*').from('publishers').where('country').is.not.in('US'); 424 | ``` 425 | 426 | #### Having 427 | ``` 428 | // having 429 | query.select('*').from('superheroes').groupBy('origin').having('superpowers').like('%flying%'); 430 | // not having 431 | query.select('*').from('superheroes').groupBy('origin').having('superpowers').not.like('%flying%'); 432 | ``` 433 | 434 | #### Exists 435 | ``` 436 | // exists 437 | query.select('*').from('superheroes').where('publisher').exists( 438 | (query) => query.select('id').from('publishers') 439 | .where('name').is.eq('Marvel Comics') 440 | ); 441 | // not exists 442 | query.select('*').from('superheroes').where('publisher').not.exists( 443 | (query) => query.select('id').from('publishers') 444 | .where('name').is.eq('Marvel Comics') 445 | ); 446 | ``` 447 | 448 | ## Contribute 449 | There is still a lot to do, so if you want to be part of the Chego project and make it better, it's great. 450 | Whether you find a bug or have a feature request, please contact us. With your help, we'll make it a great tool. 451 | 452 | [How to contribute](https://github.com/orgs/chegojs/chego/CONTRIBUTING.md) 453 | 454 | Follow our kanban boards to be up to date 455 | 456 | [Kanban boards](https://github.com/orgs/chegojs/projects/1) 457 | 458 | Join the team, feel free to catch any task or suggest a new one. 459 | 460 | ## License 461 | 462 | Copyright (c) 2019 [Chego Team](https://github.com/orgs/chegojs/people) 463 | 464 | Licensed under the [MIT license](LICENSE). 465 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # To-Do Lists 2 | 3 | * [chego/chego-api/chego-tools Tasks](https://github.com/orgs/chegojs/projects/1) 4 | * [chego-firebase Tasks](https://github.com/orgs/chegojs/projects/2) 5 | * [chego-mysql Tasks](https://github.com/orgs/chegojs/projects/3) 6 | -------------------------------------------------------------------------------- /jestconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "transform": { 3 | "^.+\\.(t|j)sx?$": "ts-jest" 4 | }, 5 | "testRegex": "(/tests/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", 6 | "moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"], 7 | "modulePathIgnorePatterns": ["(/tests/__mock__/.*)\\.*$"] 8 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@chego/chego", 3 | "version": "2.1.7", 4 | "description": "Chego core module", 5 | "main": "lib/index.js", 6 | "files": [ 7 | "lib/**/*" 8 | ], 9 | "types": "lib/index.d.ts", 10 | "scripts": { 11 | "build": "tsc", 12 | "format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"", 13 | "lint": "tslint -p tsconfig.json", 14 | "test": "jest --config jestconfig.json" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/chegojs/chego.git" 19 | }, 20 | "keywords": [ 21 | "chego", 22 | "database", 23 | "fluent interface", 24 | "universal", 25 | "query", 26 | "mysql", 27 | "firebase", 28 | "mongodb", 29 | "postgresql", 30 | "dynamodb", 31 | "couchdb" 32 | ], 33 | "author": "Radoslaw Kamysz", 34 | "license": "MIT", 35 | "bugs": { 36 | "url": "https://github.com/chegojs/chego/issues" 37 | }, 38 | "homepage": "https://github.com/chegojs/chego#readme", 39 | "devDependencies": { 40 | "@types/jest": "^24.0.11", 41 | "jest": "^24.7.1", 42 | "prettier": "^1.16.4", 43 | "ts-jest": "^24.0.2", 44 | "tslint": "^5.15.0", 45 | "tslint-config-prettier": "^1.18.0", 46 | "typescript": "^3.4.3" 47 | }, 48 | "dependencies": { 49 | "@chego/chego-api": "^2.1.5", 50 | "@chego/chego-tools": "^2.1.5" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/chego.ts: -------------------------------------------------------------------------------- 1 | import { Fn, IChego, IQuery, IDatabaseDriver } from '@chego/chego-api'; 2 | 3 | export const newChego = (driver:Fn, config:object):IChego => { 4 | const dbDriver:IDatabaseDriver = driver(); 5 | dbDriver.initialize(config); 6 | 7 | return { 8 | execute: async (...queries:IQuery[]): Promise => dbDriver.execute(queries), 9 | connect:(): Promise => dbDriver.connect(), 10 | disconnect:(): Promise => dbDriver.disconnect() 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/functions.ts: -------------------------------------------------------------------------------- 1 | 2 | import { parseStringToTempPropertyIfRequired, ifStringThenParseToProperty } from './utils'; 3 | import { GreatestData, QuerySyntaxEnum, LeastData, CoalesceData, CountData, MaxData, MinData, SumData, AvgData, SqrtData, 4 | PowData, AbsData, AcosData, AsinData, Atan2Data, AtanData, CeilData, CosData, CotData, DegreesData, DivData, ExpData, 5 | FloorData, LnData, LogData, Log10Data, Log2Data, ModData, PiData, RadiansData, RandData, RoundData, SignData, SinData, 6 | TanData, TruncateData, AsciiData, CharLengthData, ConcatData, ConcatWsData, Property, FieldData, FindInSetData, 7 | FormatData, InsertData, InstrData, LcaseData, LeftData, LengthData, LTrimData, MidData, PositionData, RepeatData, 8 | ReplaceData, ReverseData, RightData, RTrimData, SpaceData, StrcmpData, SubstrData, SubstrIndexData, TrimData, 9 | UcaseData, BinData, BinaryData, LPadData, RPadData } from '@chego/chego-api'; 10 | 11 | export const greatest = (values: any[], alias?: string): GreatestData => ({ 12 | type: QuerySyntaxEnum.Greatest, 13 | param: values.reduce((result: Property[], curent: any) => (result.push(parseStringToTempPropertyIfRequired(curent)), result), []), 14 | alias: (alias ? alias : `GREATEST(${values.join(',')})`) 15 | }); 16 | export const least = (values: any[], alias?: string): LeastData => ({ 17 | type: QuerySyntaxEnum.Least, 18 | param: values.reduce(ifStringThenParseToProperty, []), 19 | alias: (alias ? alias : `LEAST(${values.join(',')})`) 20 | }); 21 | export const coalesce = (values: any[], alias?: string): CoalesceData => ({ 22 | type: QuerySyntaxEnum.Coalesce, 23 | param: values.reduce(ifStringThenParseToProperty, []), 24 | alias: (alias ? alias : `COALESCE(${values.join(',')})`) 25 | }); 26 | export const count = (value: any, alias?: string): CountData => ({ 27 | type: QuerySyntaxEnum.Count, 28 | param: parseStringToTempPropertyIfRequired(value), 29 | alias: (alias ? alias : `COUNT(${value})`) 30 | }); 31 | export const max = (value: any, alias?: string): MaxData => ({ 32 | type: QuerySyntaxEnum.Max, 33 | param: parseStringToTempPropertyIfRequired(value), 34 | alias: (alias ? alias : `MAX(${value})`) 35 | }); 36 | export const min = (value: any, alias?: string): MinData => ({ 37 | type: QuerySyntaxEnum.Min, 38 | param: parseStringToTempPropertyIfRequired(value), 39 | alias: (alias ? alias : `MIN(${value})`) 40 | }); 41 | 42 | export const sum = (value: any, alias?: string): SumData => ({ 43 | type: QuerySyntaxEnum.Sum, 44 | param: parseStringToTempPropertyIfRequired(value), 45 | alias: (alias ? alias : `SUM(${value})`) 46 | }); 47 | export const avg = (value: any, alias?: string): AvgData => ({ 48 | type: QuerySyntaxEnum.Avg, 49 | param: parseStringToTempPropertyIfRequired(value), 50 | alias: (alias ? alias : `AVG(${value})`) 51 | }); 52 | export const sqrt = (value: any, alias?: string): SqrtData => ({ 53 | type: QuerySyntaxEnum.Sqrt, 54 | param: parseStringToTempPropertyIfRequired(value), 55 | alias: (alias ? alias : `SQRT(${value})`) 56 | }); 57 | export const pow = (value: any, exponent: number, alias?: string): PowData => ({ 58 | type: QuerySyntaxEnum.Pow, 59 | param: { 60 | value: parseStringToTempPropertyIfRequired(value), 61 | exponent 62 | }, 63 | alias: (alias ? alias : `POW(${value})`) 64 | }); 65 | 66 | export const abs = (value: any, alias?: string): AbsData => ({ 67 | type: QuerySyntaxEnum.Abs, 68 | param: parseStringToTempPropertyIfRequired(value), 69 | alias: (alias ? alias : `ABS(${value})`) 70 | }); 71 | 72 | export const acos = (value: any, alias?: string): AcosData => ({ 73 | type: QuerySyntaxEnum.Acos, 74 | param: parseStringToTempPropertyIfRequired(value), 75 | alias: (alias ? alias : `ACOS(${value})`) 76 | }); 77 | 78 | export const asin = (value: any, alias?: string): AsinData => ({ 79 | type: QuerySyntaxEnum.Asin, 80 | param: parseStringToTempPropertyIfRequired(value), 81 | alias: (alias ? alias : `ASIN(${value})`) 82 | }); 83 | 84 | export const atan = (value: any, alias?: string): AtanData => ({ 85 | type: QuerySyntaxEnum.Atan, 86 | param: parseStringToTempPropertyIfRequired(value), 87 | alias: (alias ? alias : `ATAN(${value})`) 88 | }); 89 | 90 | export const atan2 = (y: any, x: any, alias?: string): Atan2Data => ({ 91 | type: QuerySyntaxEnum.Atan2, 92 | param: { 93 | x: parseStringToTempPropertyIfRequired(x), 94 | y: parseStringToTempPropertyIfRequired(y) 95 | }, 96 | alias: (alias ? alias : `ATAN2(${y},${x})`) 97 | }); 98 | 99 | export const ceil = (value: any, alias?: string): CeilData => ({ 100 | type: QuerySyntaxEnum.Ceil, 101 | param: parseStringToTempPropertyIfRequired(value), 102 | alias: (alias ? alias : `CEIL(${value})`) 103 | }); 104 | 105 | export const cos = (value: any, alias?: string): CosData => ({ 106 | type: QuerySyntaxEnum.Cos, 107 | param: parseStringToTempPropertyIfRequired(value), 108 | alias: (alias ? alias : `COS(${value})`) 109 | }); 110 | 111 | export const cot = (value: any, alias?: string): CotData => ({ 112 | type: QuerySyntaxEnum.Cot, 113 | param: parseStringToTempPropertyIfRequired(value), 114 | alias: (alias ? alias : `COT(${value})`) 115 | }); 116 | 117 | export const degrees = (value: any, alias?: string): DegreesData => ({ 118 | type: QuerySyntaxEnum.Degrees, 119 | param: parseStringToTempPropertyIfRequired(value), 120 | alias: (alias ? alias : `DEGREES(${value})`) 121 | }); 122 | 123 | export const div = (x: any, y: any, alias?: string): DivData => ({ 124 | type: QuerySyntaxEnum.Div, 125 | param: { 126 | x: parseStringToTempPropertyIfRequired(x), 127 | y: parseStringToTempPropertyIfRequired(y) 128 | }, 129 | alias: (alias ? alias : `${x} DIV ${y}`) 130 | }); 131 | 132 | export const exp = (value: any, alias?: string): ExpData => ({ 133 | type: QuerySyntaxEnum.Exp, 134 | param: parseStringToTempPropertyIfRequired(value), 135 | alias: (alias ? alias : `EXP(${value})`) 136 | }); 137 | 138 | export const floor = (value: any, alias?: string): FloorData => ({ 139 | type: QuerySyntaxEnum.Floor, 140 | param: parseStringToTempPropertyIfRequired(value), 141 | alias: (alias ? alias : `FLOOR(${value})`) 142 | }); 143 | 144 | export const ln = (value: any, alias?: string): LnData => ({ 145 | type: QuerySyntaxEnum.Ln, 146 | param: parseStringToTempPropertyIfRequired(value), 147 | alias: (alias ? alias : `LN(${value})`) 148 | }); 149 | 150 | export const log = (value: any, alias?: string): LogData => ({ 151 | type: QuerySyntaxEnum.Log, 152 | param: parseStringToTempPropertyIfRequired(value), 153 | alias: (alias ? alias : `LOG(${value})`) 154 | }); 155 | 156 | export const log10 = (value: any, alias?: string): Log10Data => ({ 157 | type: QuerySyntaxEnum.Log10, 158 | param: parseStringToTempPropertyIfRequired(value), 159 | alias: (alias ? alias : `LOG10(${value})`) 160 | }); 161 | 162 | export const log2 = (value: any, alias?: string): Log2Data => ({ 163 | type: QuerySyntaxEnum.Log2, 164 | param: parseStringToTempPropertyIfRequired(value), 165 | alias: (alias ? alias : `LOG2(${value})`) 166 | }); 167 | 168 | export const mod = (x: any, y: any, alias?: string): ModData => ({ 169 | type: QuerySyntaxEnum.Mod, 170 | param: { 171 | x: parseStringToTempPropertyIfRequired(x), 172 | y: parseStringToTempPropertyIfRequired(y) 173 | }, 174 | alias: (alias ? alias : `MOD(${x},${y})`) 175 | }); 176 | 177 | export const pi = (alias?: string): PiData => ({ 178 | type: QuerySyntaxEnum.Pi, 179 | param: null, 180 | alias: (alias ? alias : `PI()`) 181 | }); 182 | 183 | export const radians = (value: any, alias?: string): RadiansData => ({ 184 | type: QuerySyntaxEnum.Radians, 185 | param: parseStringToTempPropertyIfRequired(value), 186 | alias: (alias ? alias : `RADIANS(${value})`) 187 | }); 188 | 189 | export const rand = (value: any, alias?: string): RandData => ({ 190 | type: QuerySyntaxEnum.Rand, 191 | param: parseStringToTempPropertyIfRequired(value), 192 | alias: (alias ? alias : `RAND(${value})`) 193 | }); 194 | 195 | export const round = (value: any, decimal: number, alias?: string): RoundData => ({ 196 | type: QuerySyntaxEnum.Round, 197 | param: { 198 | value: parseStringToTempPropertyIfRequired(value), 199 | decimal 200 | }, 201 | alias: (alias ? alias : `ROUND(${value},${decimal})`) 202 | }); 203 | 204 | export const sign = (value: any, alias?: string): SignData => ({ 205 | type: QuerySyntaxEnum.Sign, 206 | param: parseStringToTempPropertyIfRequired(value), 207 | alias: (alias ? alias : `SIGN(${value})`) 208 | }); 209 | 210 | export const sin = (value: any, alias?: string): SinData => ({ 211 | type: QuerySyntaxEnum.Sin, 212 | param: parseStringToTempPropertyIfRequired(value), 213 | alias: (alias ? alias : `SIN(${value})`) 214 | }); 215 | 216 | export const tan = (value: any, alias?: string): TanData => ({ 217 | type: QuerySyntaxEnum.Tan, 218 | param: parseStringToTempPropertyIfRequired(value), 219 | alias: (alias ? alias : `TAN(${value})`) 220 | }); 221 | 222 | export const truncate = (value: any, alias?: string): TruncateData => ({ 223 | type: QuerySyntaxEnum.Truncate, 224 | param: parseStringToTempPropertyIfRequired(value), 225 | alias: (alias ? alias : `TRUNCATE(${value})`) 226 | }); 227 | 228 | export const ascii = (value: any, alias?: string): AsciiData => ({ 229 | type: QuerySyntaxEnum.Ascii, 230 | param: parseStringToTempPropertyIfRequired(value), 231 | alias: (alias ? alias : `ASCII(${value})`) 232 | }); 233 | 234 | export const charLength = (value: any, alias?: string): CharLengthData => ({ 235 | type: QuerySyntaxEnum.CharLength, 236 | param: parseStringToTempPropertyIfRequired(value), 237 | alias: (alias ? alias : `CHAR_LENGTH(${value})`) 238 | }); 239 | 240 | export const concat = (values: any[], alias?: string): ConcatData => ({ 241 | type: QuerySyntaxEnum.Concat, 242 | param: values.reduce(ifStringThenParseToProperty, []), 243 | alias: (alias ? alias : `CONCAT(${values.join(',')})`) 244 | }); 245 | 246 | export const concatWs = (separator: string, values: any[], alias?: string): ConcatWsData => ({ 247 | type: QuerySyntaxEnum.ConcatWs, 248 | param: { 249 | separator, 250 | values: values.reduce(ifStringThenParseToProperty, []) 251 | }, 252 | alias: (alias ? alias : `CONCAT_WS(${values.join(',')})`) 253 | }); 254 | 255 | export const field = (search: any, values: any[], alias?: string): FieldData => ({ 256 | type: QuerySyntaxEnum.Field, 257 | param: { 258 | search: parseStringToTempPropertyIfRequired(search), 259 | values: values.reduce(ifStringThenParseToProperty, []) 260 | }, 261 | alias: (alias ? alias : `FIELD(${search},${values.join(',')})`) 262 | }); 263 | 264 | export const findInSet = (search: any, set: string, alias?: string): FindInSetData => ({ 265 | type: QuerySyntaxEnum.FindInSet, 266 | param: { 267 | search: parseStringToTempPropertyIfRequired(search), 268 | set 269 | }, 270 | alias: (alias ? alias : `FIND_IN_SET(${search}, ${set})`) 271 | }); 272 | 273 | export const format = (value: any, decimal: number, alias?: string): FormatData => ({ 274 | type: QuerySyntaxEnum.Format, 275 | param: { 276 | value: parseStringToTempPropertyIfRequired(value), 277 | decimal 278 | }, 279 | alias: (alias ? alias : `FORMAT(${value}, ${decimal})`) 280 | }); 281 | 282 | export const insert = (value: string, position: number, length: number, toInsert: any, alias?: string): InsertData => ({ 283 | type: QuerySyntaxEnum.InsertString, 284 | param: { 285 | value: parseStringToTempPropertyIfRequired(value), 286 | position, 287 | length, 288 | toInsert: parseStringToTempPropertyIfRequired(toInsert) 289 | }, 290 | alias: (alias ? alias : `INSERT(${value})`) 291 | }); 292 | 293 | export const instr = (value: any, search: any, alias?: string): InstrData => ({ 294 | type: QuerySyntaxEnum.Instr, 295 | param: { 296 | value: parseStringToTempPropertyIfRequired(value), 297 | search: parseStringToTempPropertyIfRequired(search) 298 | }, 299 | alias: (alias ? alias : `INSTR(${value}, ${search})`) 300 | }); 301 | 302 | export const lcase = (value: any, alias?: string): LcaseData => ({ 303 | type: QuerySyntaxEnum.Lcase, 304 | param: parseStringToTempPropertyIfRequired(value), 305 | alias: (alias ? alias : `LCASE(${value})`) 306 | }); 307 | 308 | export const left = (value: any, charsCount: number, alias?: string): LeftData => ({ 309 | type: QuerySyntaxEnum.Left, 310 | param: { 311 | value: parseStringToTempPropertyIfRequired(value), 312 | charsCount 313 | }, 314 | alias: (alias ? alias : `LEFT(${value},${charsCount})`) 315 | }); 316 | 317 | export const length = (value: any, alias?: string): LengthData => ({ 318 | type: QuerySyntaxEnum.Length, 319 | param: parseStringToTempPropertyIfRequired(value), 320 | alias: (alias ? alias : `LENGTH(${value})`) 321 | }); 322 | 323 | export const lpad = (value: any, length: number, value2: any, alias?: string): LPadData => ({ 324 | type: QuerySyntaxEnum.Lpad, 325 | param: { 326 | value: parseStringToTempPropertyIfRequired(value), 327 | length, 328 | value2: parseStringToTempPropertyIfRequired(value2) 329 | }, 330 | alias: (alias ? alias : `LPAD(${value},${length},${value2})`) 331 | }); 332 | 333 | export const ltrim = (value: any, alias?: string): LTrimData => ({ 334 | type: QuerySyntaxEnum.Ltrim, 335 | param: parseStringToTempPropertyIfRequired(value), 336 | alias: (alias ? alias : `LTRIM(${value})`) 337 | }); 338 | 339 | export const mid = (value: any, start: number, length: number, alias?: string): MidData => ({ 340 | type: QuerySyntaxEnum.Mid, 341 | param: { 342 | value: parseStringToTempPropertyIfRequired(value), 343 | start, 344 | length 345 | }, 346 | alias: (alias ? alias : `MID(${value},${start},${length})`) 347 | }); 348 | 349 | export const position = (substring: any, value: any, alias?: string): PositionData => ({ 350 | type: QuerySyntaxEnum.Position, 351 | param: { 352 | value: parseStringToTempPropertyIfRequired(value), 353 | substring: parseStringToTempPropertyIfRequired(substring) 354 | }, 355 | alias: (alias ? alias : `POSITION(${substring} IN ${value})`) 356 | }); 357 | export const repeat = (value: any, count: number, alias?: string): RepeatData => ({ 358 | type: QuerySyntaxEnum.Repeat, 359 | param: { 360 | value: parseStringToTempPropertyIfRequired(value), 361 | count 362 | }, 363 | alias: (alias ? alias : `REPEAT(${value},${count})`) 364 | }); 365 | 366 | export const replace = (value: any, from: any, to: any, alias?: string): ReplaceData => ({ 367 | type: QuerySyntaxEnum.ReplaceString, 368 | param: { 369 | value: parseStringToTempPropertyIfRequired(value), 370 | from: parseStringToTempPropertyIfRequired(from), 371 | to: parseStringToTempPropertyIfRequired(to) 372 | }, 373 | alias: (alias ? alias : `REPALCE(${value},${from},${to})`) 374 | }); 375 | 376 | export const reverse = (value: any, alias?: string): ReverseData => ({ 377 | type: QuerySyntaxEnum.Reverse, 378 | param: parseStringToTempPropertyIfRequired(value), 379 | alias: (alias ? alias : `REVERSE(${value})`) 380 | }); 381 | 382 | export const right = (value: any, charsCount: number, alias?: string): RightData => ({ 383 | type: QuerySyntaxEnum.Right, 384 | param: { 385 | value: parseStringToTempPropertyIfRequired(value), 386 | charsCount 387 | }, 388 | alias: (alias ? alias : `RIGHT(${value},${charsCount})`) 389 | }); 390 | 391 | export const rpad = (value: any, length: number, value2: any, alias?: string): RPadData => ({ 392 | type: QuerySyntaxEnum.Rpad, 393 | param: { 394 | value: parseStringToTempPropertyIfRequired(value), 395 | length, 396 | value2: parseStringToTempPropertyIfRequired(value2) 397 | }, 398 | alias: (alias ? alias : `RPAD(${value},${length},${value2})`) 399 | }); 400 | 401 | export const rtrim = (value: any, alias?: string): RTrimData => ({ 402 | type: QuerySyntaxEnum.Rtrim, 403 | param: parseStringToTempPropertyIfRequired(value), 404 | alias: (alias ? alias : `RTRIM(${value})`) 405 | }); 406 | 407 | export const space = (value: number, alias?: string): SpaceData => ({ 408 | type: QuerySyntaxEnum.Space, 409 | param: value, 410 | alias: (alias ? alias : `SPACE(${value})`) 411 | }); 412 | 413 | export const strcmp = (value: any, value2: any, alias?: string): StrcmpData => ({ 414 | type: QuerySyntaxEnum.Strcmp, 415 | param: { 416 | value: parseStringToTempPropertyIfRequired(value), 417 | value2: parseStringToTempPropertyIfRequired(value2) 418 | }, 419 | alias: (alias ? alias : `STRCMP(${value}, ${value2})`) 420 | }); 421 | 422 | export const substr = (value: any, start: number, length: number, alias?: string): SubstrData => ({ 423 | type: QuerySyntaxEnum.Substr, 424 | param: { 425 | value: parseStringToTempPropertyIfRequired(value), 426 | start, 427 | length 428 | }, 429 | alias: (alias ? alias : `SUBSTR(${value},${start},${length})`) 430 | }); 431 | 432 | export const substrIndex = (value: any, delimiter: string, count: number, alias?: string): SubstrIndexData => ({ 433 | type: QuerySyntaxEnum.SubstringIndex, 434 | param: { 435 | value: parseStringToTempPropertyIfRequired(value), 436 | delimiter, 437 | count 438 | }, 439 | alias: (alias ? alias : `SUBSTRING_INDEX(${value})`) 440 | }); 441 | 442 | export const trim = (value: any, alias?: string): TrimData => ({ 443 | type: QuerySyntaxEnum.Trim, 444 | param: parseStringToTempPropertyIfRequired(value), 445 | alias: (alias ? alias : `TRIM(${value})`) 446 | }); 447 | 448 | export const ucase = (value: any, alias?: string): UcaseData => ({ 449 | type: QuerySyntaxEnum.Ucase, 450 | param: parseStringToTempPropertyIfRequired(value), 451 | alias: (alias ? alias : `UCASE(${value})`) 452 | }); 453 | 454 | 455 | export const bin = (value: any, alias?: string): BinData => ({ 456 | type: QuerySyntaxEnum.Bin, 457 | param: parseStringToTempPropertyIfRequired(value), 458 | alias: (alias ? alias : `BIN(${value})`) 459 | }); 460 | 461 | 462 | export const binary = (value: any, alias?: string): BinaryData => ({ 463 | type: QuerySyntaxEnum.Binary, 464 | param: parseStringToTempPropertyIfRequired(value), 465 | alias: (alias ? alias : `Binary(${value})`) 466 | }); 467 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export { newChego } from './chego' 2 | export { newQuery } from './query' 3 | export * from './functions'; 4 | export * from './utils'; -------------------------------------------------------------------------------- /src/query.ts: -------------------------------------------------------------------------------- 1 | import { 2 | IQuery, IQueryScheme, QuerySyntaxEnum, IQueryNot, IQueryEqualTo, IQueryLike, IQueryGT, IQueryLT, 3 | IQueryBetween, IQueryWhere, IQueryInParentheses, IQueryNull, IQueryLimit, IQueryAnd, IQueryOr, Fn, 4 | IQueryAndWhere, IQueryOrWhere, IQueryLeftJoin, IQueryRightJoin, IQueryJoin, IQueryFullJoin, 5 | IQueryTo, IQueryGroupBy, IQuerySet, IQueryFrom, StringOrProperty, IQueryUnion, 6 | QueryBuildFunction, IQueryOn, CommandProp, IQueryUsing, 7 | IQueryHaving, IQueryExists, IQueryOrderBy, IQueryWhereNot, IQueryHavingAndLite, 8 | IQueryHavingOrLite, IQueryHavingEqualTo, IQueryHavingLT, IQueryHavingGT, IQueryHavingBetween, 9 | IQueryHavingNot, IQueryHavingNull, IQueryHavingInParentheses, IQueryWhereIs, IQueryWhereAre, IQueryUnionAll, IQueryIn 10 | } from '@chego/chego-api'; 11 | import { newQueryScheme } from './queryScheme'; 12 | import { isFunction, isQueryScheme, newCustomCondition } from '@chego/chego-tools'; 13 | 14 | const containsQueryScheme = (obj: any): obj is IQuery => 15 | isQueryScheme((obj).scheme); 16 | 17 | const updateScheme = (scheme: IQueryScheme, type: QuerySyntaxEnum, query: IQuery) => (arg: any) => { 18 | if (isFunction(arg)) { 19 | if (type === QuerySyntaxEnum.WrapInParentheses) { 20 | scheme.add(QuerySyntaxEnum.OpenParentheses); 21 | arg(query); 22 | scheme.add(QuerySyntaxEnum.CloseParentheses); 23 | } else if (type === QuerySyntaxEnum.Where) { 24 | scheme.add(type, newCustomCondition(arg, null)); 25 | } else { 26 | const temp = scheme; 27 | scheme = newQueryScheme(); 28 | arg(query); 29 | temp.add(type, scheme); 30 | scheme = temp; 31 | } 32 | } else if (containsQueryScheme(arg)) { 33 | scheme.add(type, arg.scheme); 34 | } else { 35 | scheme.add(type, arg); 36 | } 37 | } 38 | 39 | export const newQuery = (): IQuery => { 40 | const pScheme: IQueryScheme = newQueryScheme(); 41 | const add = (type: QuerySyntaxEnum, ...args: any[]): void => { 42 | args.forEach(updateScheme(pScheme, type, query)); 43 | } 44 | 45 | const query: IQuery = { 46 | get scheme(): IQueryScheme { 47 | return pScheme; 48 | }, 49 | get or(): IQueryNot & IQueryEqualTo & IQueryLike & IQueryGT & IQueryLT & IQueryIn & IQueryBetween & IQueryWhere & IQueryInParentheses { 50 | pScheme.add(QuerySyntaxEnum.Or); 51 | return query; 52 | }, 53 | 54 | get is(): IQueryNot & IQueryEqualTo & IQueryLike & IQueryGT & IQueryLT & IQueryBetween & IQueryNull { 55 | pScheme.add(QuerySyntaxEnum.Is); 56 | return query; 57 | }, 58 | get and(): IQueryNot & IQueryEqualTo & IQueryLike & IQueryGT & IQueryLT & IQueryIn & IQueryBetween & IQueryWhere & IQueryInParentheses { 59 | pScheme.add(QuerySyntaxEnum.And); 60 | return query; 61 | }, 62 | get are(): IQueryNot & IQueryEqualTo & IQueryLike & IQueryGT & IQueryLT & IQueryBetween & IQueryNull { 63 | pScheme.add(QuerySyntaxEnum.Are); 64 | return query; 65 | }, 66 | get null(): IQueryGroupBy & IQueryOrderBy & IQueryLimit & IQueryAnd & IQueryOr { 67 | pScheme.add(QuerySyntaxEnum.Null); 68 | return query; 69 | }, 70 | get not(): IQueryNot { 71 | pScheme.add(QuerySyntaxEnum.Not); 72 | return query; 73 | }, 74 | exists(fn: Fn): IQueryOrderBy & IQueryGroupBy & IQueryLimit & IQueryAndWhere & IQueryOrWhere { 75 | add(QuerySyntaxEnum.Exists, fn); 76 | return query; 77 | }, 78 | to(...tables: string[]): IQueryLeftJoin & IQueryRightJoin & IQueryJoin & IQueryFullJoin & IQueryOrderBy & IQueryWhere & IQueryLimit & IQueryInParentheses { 79 | add(QuerySyntaxEnum.To, ...tables); 80 | return query; 81 | }, 82 | set(data: any): IQueryOrderBy & IQueryWhere & IQueryLimit & IQueryInParentheses { 83 | add(QuerySyntaxEnum.Set, data); 84 | return query; 85 | }, 86 | insert(...args: any[]): IQueryTo { 87 | add(QuerySyntaxEnum.Insert, ...args); 88 | return query; 89 | }, 90 | where(...values: any[]): IQueryWhereIs & IQueryWhereAre & IQueryAndWhere & IQueryOrWhere & IQueryWhereNot & IQueryExists { 91 | add(QuerySyntaxEnum.Where, ...values); 92 | return query; 93 | }, 94 | update(...tables: any[]): IQueryLeftJoin & IQueryRightJoin & IQueryJoin & IQueryFullJoin & IQuerySet { 95 | add(QuerySyntaxEnum.Update, ...tables); 96 | return query; 97 | }, 98 | select(...args: any[]): IQueryFrom { 99 | add(QuerySyntaxEnum.Select, ...args); 100 | return query; 101 | }, 102 | delete(): IQueryFrom { 103 | pScheme.add(QuerySyntaxEnum.Delete); 104 | return query; 105 | }, 106 | orderBy(...values: any[]): IQueryGroupBy & IQueryLimit { 107 | add(QuerySyntaxEnum.OrderBy, ...values); 108 | return query; 109 | }, 110 | lt(...values: CommandProp[]): IQueryGroupBy & IQueryOrderBy & IQueryLimit & IQueryAnd & IQueryOr { 111 | add(QuerySyntaxEnum.LT, ...values); 112 | return query; 113 | }, 114 | limit(offsetOrCount: number, count?: number): IQueryGroupBy & IQueryOrderBy { 115 | pScheme.add(QuerySyntaxEnum.Limit, offsetOrCount, count); 116 | return query; 117 | }, 118 | like(...values: CommandProp[]): IQueryGroupBy & IQueryOrderBy & IQueryLimit & IQueryAnd & IQueryOr { 119 | add(QuerySyntaxEnum.Like, ...values); 120 | return query; 121 | }, 122 | gt(...values: CommandProp[]): IQueryGroupBy & IQueryOrderBy & IQueryLimit & IQueryAnd & IQueryOr { 123 | add(QuerySyntaxEnum.GT, ...values); 124 | return query; 125 | }, 126 | eq(...values: CommandProp[]): IQueryGroupBy & IQueryOrderBy & IQueryLimit & IQueryAnd & IQueryOr { 127 | add(QuerySyntaxEnum.EQ, ...values); 128 | return query; 129 | }, 130 | between(min: number, max: number): IQueryGroupBy & IQueryOrderBy & IQueryLimit & IQueryAnd & IQueryOr { 131 | pScheme.add(QuerySyntaxEnum.Between, min, max); 132 | return query; 133 | }, 134 | from(...tables: CommandProp[]): IQueryGroupBy & IQueryUnion & IQueryUnionAll & IQueryLeftJoin & IQueryRightJoin & IQueryJoin & IQueryFullJoin & IQueryOrderBy & IQueryWhere & IQueryLimit & IQueryInParentheses { 135 | add(QuerySyntaxEnum.From, ...tables); 136 | return query; 137 | }, 138 | union(...fns: Array>): IQueryGroupBy & IQueryOrderBy & IQueryLimit { 139 | add(QuerySyntaxEnum.Union, ...fns); 140 | return query; 141 | }, 142 | unionAll(...fns: Array>): IQueryGroupBy & IQueryOrderBy & IQueryLimit { 143 | add(QuerySyntaxEnum.UnionAll, ...fns); 144 | return query; 145 | }, 146 | inParentheses(fn: QueryBuildFunction): IQueryGroupBy & IQueryOrderBy & IQueryLimit & IQueryAnd & IQueryOr { 147 | add(QuerySyntaxEnum.WrapInParentheses, fn); 148 | return query; 149 | }, 150 | on(keyA: StringOrProperty, keyB: StringOrProperty): IQueryLeftJoin & IQueryRightJoin & IQueryJoin & IQueryFullJoin & IQueryOrderBy & IQueryWhere & IQueryLimit & IQueryInParentheses { 151 | pScheme.add(QuerySyntaxEnum.On, keyA, keyB); 152 | return query; 153 | }, 154 | using(key: string): IQueryLeftJoin & IQueryRightJoin & IQueryJoin & IQueryFullJoin & IQueryOrderBy & IQueryWhere & IQueryLimit & IQueryInParentheses { 155 | pScheme.add(QuerySyntaxEnum.Using, key); 156 | return query; 157 | }, 158 | leftJoin(table: string): IQueryOn & IQueryUsing { 159 | pScheme.add(QuerySyntaxEnum.LeftJoin, table); 160 | return query; 161 | }, 162 | rightJoin(table: string): IQueryOn & IQueryUsing { 163 | pScheme.add(QuerySyntaxEnum.RightJoin, table); 164 | return query; 165 | }, 166 | join(table: string): IQueryOn & IQueryUsing { 167 | pScheme.add(QuerySyntaxEnum.Join, table); 168 | return query; 169 | }, 170 | fullJoin(table: string): IQueryOn & IQueryUsing { 171 | pScheme.add(QuerySyntaxEnum.FullJoin, table); 172 | return query; 173 | }, 174 | groupBy(...values: any[]): IQueryOrderBy & IQueryLimit & IQueryHaving { 175 | add(QuerySyntaxEnum.GroupBy, ...values); 176 | return query; 177 | }, 178 | having(...values: CommandProp[]): IQueryHavingAndLite & IQueryHavingOrLite & IQueryHavingEqualTo & IQueryHavingLT & IQueryHavingGT & IQueryHavingBetween & IQueryHavingNot & IQueryHavingNull & IQueryHavingInParentheses { 179 | add(QuerySyntaxEnum.Having, ...values); 180 | return query; 181 | }, 182 | in(...values: CommandProp[]): IQueryOrderBy & IQueryGroupBy & IQueryLimit & IQueryAndWhere & IQueryOrWhere { 183 | add(QuerySyntaxEnum.In, ...values); 184 | return query; 185 | }, 186 | intersect(...fns: Array>) { 187 | add(QuerySyntaxEnum.Intersect, ...fns); 188 | return query; 189 | }, 190 | minus(...fns: Array>) { 191 | add(QuerySyntaxEnum.Minus, ...fns); 192 | return query; 193 | }, 194 | replace(...values: CommandProp[]) { 195 | add(QuerySyntaxEnum.Replace, ...values); 196 | return query; 197 | } 198 | } 199 | return query; 200 | } 201 | -------------------------------------------------------------------------------- /src/queryScheme.ts: -------------------------------------------------------------------------------- 1 | 2 | import { parseStringToTable, parseStringToProperty, clone } from '@chego/chego-tools'; 3 | import { QuerySyntaxEnum, Property, Table, IQueryScheme, IQuerySchemeArray, QuerySchemeEntry, IQuerySchemeElement } from '@chego/chego-api'; 4 | 5 | const parsers = new Map Property | Table>([ 6 | [QuerySyntaxEnum.From, (value: string) => parseStringToTable(value)], 7 | [QuerySyntaxEnum.To, (value: string) => parseStringToTable(value)], 8 | [QuerySyntaxEnum.Update, (value: string) => parseStringToTable(value)], 9 | [QuerySyntaxEnum.Select, (value: string) => parseStringToProperty(value)], 10 | [QuerySyntaxEnum.Delete, (value: string) => parseStringToProperty(value)], 11 | [QuerySyntaxEnum.Where, (value: string) => parseStringToProperty(value)], 12 | [QuerySyntaxEnum.Having, (value: string) => parseStringToProperty(value)], 13 | [QuerySyntaxEnum.Join, (value: string) => parseStringToTable(value)], 14 | [QuerySyntaxEnum.FullJoin, (value: string) => parseStringToTable(value)], 15 | [QuerySyntaxEnum.LeftJoin, (value: string) => parseStringToTable(value)], 16 | [QuerySyntaxEnum.RightJoin, (value: string) => parseStringToTable(value)], 17 | [QuerySyntaxEnum.On, (value: string) => parseStringToProperty(value)], 18 | [QuerySyntaxEnum.Using, (value: string) => parseStringToProperty(value)], 19 | ]); 20 | 21 | type Parser = (value: string, index: number) => Property | Table; 22 | 23 | const parseStringIfRequired = (parser: Parser) => (keys: any[], data: any, i: number) => 24 | (keys.push( 25 | (typeof data === 'string' && parser) 26 | ? parser(data, i) 27 | : data), keys); 28 | 29 | const newQuerySchemeElement = (index: number, type: QuerySyntaxEnum, params?: any[]): IQuerySchemeElement => ({ 30 | index, 31 | type, 32 | params 33 | }); 34 | 35 | export const newQueryScheme = (): IQueryScheme => { 36 | const pSchemeArr: IQuerySchemeArray = []; 37 | return { 38 | add(type: QuerySyntaxEnum, ...args: any[]): void { 39 | const parser: Parser = parsers.get(type); 40 | const params: any[] = args.reduce(parseStringIfRequired(parser), []); 41 | pSchemeArr.push(newQuerySchemeElement(pSchemeArr.length, type, params)); 42 | }, 43 | get(index: number): QuerySchemeEntry { 44 | return index < 0 ? pSchemeArr[pSchemeArr.length + index] : pSchemeArr[index]; 45 | }, 46 | toArray(): IQuerySchemeArray { 47 | return clone(pSchemeArr); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | import { parseStringToProperty, newProperty, newTable, newLogicalOperatorScope } from '@chego/chego-tools'; 2 | import {StringOrProperty, Property, QuerySyntaxEnum, ScopeContent, LogicalOperatorScope, AnyButFunction, ItemWithCustomId} from '@chego/chego-api'; 3 | 4 | export const rowId = (table?:string, alias?: string): Property => 5 | newProperty({ type: QuerySyntaxEnum.RowId, table: table ? newTable(table) : null, alias: alias || 'id' }); 6 | 7 | export const alias = (name: string, alias: string): Property => { 8 | const property: Property = parseStringToProperty(name); 9 | property.alias = alias; 10 | property.type = QuerySyntaxEnum.Alias; 11 | return property; 12 | } 13 | 14 | export const parseStringToPropertyIfRequired = (key: StringOrProperty) => typeof key === 'string' ? parseStringToProperty(key) : key; 15 | export const parseStringToTempPropertyIfRequired = (key: StringOrProperty) => typeof key === 'string' ? parseStringToProperty(key, null, true) : key; 16 | 17 | export const ifStringThenParseToProperty = (keys: ScopeContent[], key: any): ScopeContent[] => 18 | keys.concat((typeof key === 'string') ? parseStringToProperty(key) : key); 19 | 20 | export const ifStringThenParseToTempProperty = (keys: ScopeContent[], key: any): ScopeContent[] => 21 | keys.concat((typeof key === 'string') ? parseStringToProperty(key, null, true) : key); 22 | 23 | export const or = (...properties: AnyButFunction[]): LogicalOperatorScope => { 24 | const list:ScopeContent[] = (properties).reduce(ifStringThenParseToProperty, []) 25 | return newLogicalOperatorScope(QuerySyntaxEnum.Or, list); 26 | } 27 | export const and = (...properties: AnyButFunction[]): LogicalOperatorScope => { 28 | const list:ScopeContent[] = (properties).reduce(ifStringThenParseToProperty, []) 29 | return newLogicalOperatorScope(QuerySyntaxEnum.And, list); 30 | } 31 | 32 | export const withCustomId = (id:string, item:object):ItemWithCustomId => ({ id, item, type:QuerySyntaxEnum.ItemWithCustomId }); -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "lib", 4 | "target": "esnext", 5 | "lib": ["esnext", "dom"], 6 | "module": "commonjs", 7 | "moduleResolution": "node", 8 | "declaration": true, 9 | "noImplicitAny": true, 10 | "sourceMap": true, 11 | "inlineSources": true, 12 | "experimentalDecorators": true, 13 | "emitDecoratorMetadata": true, 14 | "importHelpers": true, 15 | "noEmit" : false, 16 | "noEmitOnError": true 17 | }, 18 | "include": [ 19 | "./src/**/*" 20 | ], 21 | "exclude": [ 22 | "node_modules", 23 | "lib" 24 | ] 25 | } -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["tslint:recommended", "tslint-config-prettier"], 3 | "rules": { 4 | "ordered-imports": false, 5 | "no-console" : false, 6 | "no-var-requires": false, 7 | "forin" : false, 8 | "object-literal-sort-keys":false, 9 | "interface-over-type-literal" : false, 10 | "no-angle-bracket-type-assertion": false, 11 | "no-string-literal": false, 12 | "no-shadowed-variable": false 13 | } 14 | } --------------------------------------------------------------------------------