Comparing version 0.3.0 to 1.0.0
module.exports = | ||
{ | ||
extends: './node_modules/js-outlander/outlander.eslint.js' | ||
extends: './node_modules/js-outlander/outlander.eslint.js', | ||
env: | ||
{ | ||
es6: true | ||
} | ||
} |
/* @flow */ | ||
module.exports = function count (rows /* :Array<*> */) /* :number */ | ||
module.exports = function count /* ::<T> */ (rows /* :Array<T> */) /* :number */ | ||
{ | ||
return rows.length | ||
} |
{ | ||
"name": "knexed", | ||
"version": "0.3.0", | ||
"version": "1.0.0", | ||
"description": "knex utilities", | ||
"description": "Knex utilities", | ||
"license": "MIT", | ||
"author": "Strider <teamfortresslife@gmail.com>", | ||
"license": "MIT", | ||
"repository": "StreetStrider/knexed", | ||
"keywords": | ||
[ | ||
"knex", "query-builder", "query builder", | ||
"sql", "sql-query", "query", "database", | ||
"postgresql", "sqlite3", | ||
"mysql", "mariadb", | ||
"oracle", "mssql" | ||
], | ||
"engines": | ||
{ | ||
"node": ">= 4" | ||
}, | ||
"peerDependencies": | ||
@@ -18,3 +33,3 @@ { | ||
{ | ||
"st": "eslint ./*.js test/", | ||
"st": "eslint *.js tx/ join/ test/", | ||
"flow": "flow", | ||
@@ -26,3 +41,3 @@ | ||
"check": "npm run st && npm run flow", | ||
"all": "npm run check && npm test", | ||
"all": "npm run check && npm run cover", | ||
@@ -29,0 +44,0 @@ "coveralls": "istanbul-coveralls" |
@@ -9,3 +9,3 @@ /* @flow */ | ||
return (rows /* :Array<Object> */) /* :Projection */ => | ||
return /* ::<T: Object> */ (rows /* :Array<T> */) /* :Projection */ => | ||
{ | ||
@@ -12,0 +12,0 @@ if (! rows.length) |
@@ -9,4 +9,14 @@ # knexed | ||
Utilities for [Knex](http://knexjs.org/) library. | ||
Adds some neatness to [Knex](http://knexjs.org/) library. Utilities for tables, joins, transactions and other. | ||
### why? | ||
There're three ways to work with relational DB on an application side: raw SQL, query builders, ORMs. | ||
I prefer query builders over other two and find it a perfect balance. | ||
* **why not raw SQL**: I love SQL and plain queries, but it lacks two main features from application's view: *composability* and *type control*. By *composability* I mean that I can create query with multiple variative clauses and not bother with string glueing, putting spaces and commas here and there. By *type control* I mean bi-directional type conversions and data escaping. Both theese issues are perfectly solved by query builders. | ||
* **why not ORM**: I dislike ORMs because they compel me for specific application structure, to use special type-wrappers and stateful data workflow. They often have ugly verbose API, poor performance, crazy output queries and bring no benefits comparing to query builders. On the other hand query builders work with native language types and encourage functional data-flow instead of «statefulness». | ||
The lead query builder in JS ecosystem is **Knex**. I don't like it much for poor code style & architecture, not so good API. Yes, Knex is not perfect, however this is the leading project in this area and it tends to stay so. It working, it will receive updates, fixes and improves. I decided to build a better abstractions over it with composability and much more JS/Lispy-crazy-science-style in mind. The only restriction is not to fall into ORM-ish style. So this library contains only simple helpers and composable abstractions. Feel free to use another good solutions (like [Bluebird's Promise extensions](http://bluebirdjs.com/docs/api-reference.html) which is built-in for Knex, [Lodash/fp](https://github.com/lodash/lodash/wiki/FP-Guide), [Ramda & lenses](http://ramdajs.com/) etc) along the way. | ||
## API | ||
@@ -27,3 +37,3 @@ ### dataset helpers | ||
### table helpers | ||
### table helpers (`table/table`) | ||
```js | ||
@@ -33,13 +43,16 @@ /* create init point for this table queries: */ | ||
/* then use it */ | ||
/* `accounts()` creates new query at every invocation */ | ||
accounts().select() | ||
accounts(trx).select() /* as a part of transaction `trx` */ | ||
accounts.as('alias').select() | ||
accounts.as('alias').select() /* with alias */ | ||
accounts.as('alias', trx).select() | ||
/* then build query … */ | ||
/* … then build query … */ | ||
``` | ||
### transaction helpers (`tx/method`) | ||
```js | ||
/* create method */ | ||
var create = method(knex, (trx, name) => | ||
{ | ||
return accounts(trx).insert({ name: name }) | ||
return accounts(trx).insert({ name: name }) | ||
}) | ||
@@ -53,2 +66,41 @@ | ||
### join helpers (`table/join`) | ||
Use `join` helper for symmetric-looking joins. `table` is used as basis. | ||
```js | ||
/* prepare two tables: */ | ||
var accounts = table(knex, 'accounts') | ||
var messages = table(knex, 'messages') | ||
/* join by accounts.id = messages.user_id: */ | ||
var accounts$messages = join(accounts, messages, [ 'id', 'user_id' ]) | ||
/* `accounts$messages()` creates new query at every invocation */ | ||
/* then use as simple table */ | ||
accounts$messages() | ||
.select('user_id', 'text') | ||
.where('user_id', user_id) | ||
/* as a part of transaction `trx` */ | ||
accounts$messages(trx).select() | ||
/* supported join types: */ | ||
join.left(accounts, messages, [ 'id', 'user_id' ]) | ||
join.right(messages, accounts, [ 'id', 'user_id' ]) | ||
join.full(table_a, table_b, [ 'id', 'user_id' ]) | ||
join.cross(table_a, table_b) | ||
/* pick predicate: */ | ||
join(accounts, messages, [ 'id', '=', 'user_id' ]) | ||
join.left(accounts, messages, [ 'id', '<>', 'user_id' ]) | ||
/* join by accounts.id = messages.id, like NATURAL JOIN: */ | ||
join(accounts, messages, 'id') | ||
/* join with aliases */ | ||
/* accounts as A, messages as M, | ||
this will also pick proper aliases on join predicate | ||
*/ | ||
join([ accounts, 'A' ], [ messages, 'M' ], [ 'id', 'user_id' ]) | ||
``` | ||
## flow | ||
@@ -55,0 +107,0 @@ We're providing built-in [Flow](https://flowtype.org/) type definitions. |
/* @flow */ | ||
/* :: | ||
type RetPromise<T> = ( ...args: Array<any>) => Promise<T>; | ||
type RetPromiseTx<T> = (tx: Transaction, ...args: Array<any>) => Promise<T>; | ||
type RetPromise<T> = ( ...args: Array<any>) => Promise<T>; | ||
type TxRetPromise<T> = (tx: Transaction, ...args: Array<any>) => Promise<T>; | ||
*/ | ||
@@ -16,3 +16,3 @@ | ||
kx /* :Knex */, | ||
fn /* :RetPromiseTx<T> */ | ||
fn /* :TxRetPromise<T> */ | ||
) | ||
@@ -19,0 +19,0 @@ /* :RetPromise<T> */ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
1
108
13753
16
311
1