New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

monstrous

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

monstrous - npm Package Compare versions

Comparing version 0.1.1 to 0.1.2

7

CHANGELOG.md

@@ -5,2 +5,9 @@ # Changelog

## [0.1.2](https://gitlab.com/monstrous/monstrous/compare/v0.1.1...v0.1.2) (2023-02-19)
### Bug Fixes
* projection clones set #to_array ([4409912](https://gitlab.com/monstrous/monstrous/commit/4409912f37fcd557bb0268297a0ed6d7d94801d6))
## [0.1.1](https://gitlab.com/monstrous/monstrous/compare/v0.1.0...v0.1.1) (2023-02-17)

@@ -7,0 +14,0 @@

2

lib/statement/project.js

@@ -205,3 +205,3 @@ import pgp from 'pg-promise';

clone() {
const clone = new Projection(this.#key, this.#columns);
const clone = new Projection(this.#key, this.#columns, this.#to_array);

@@ -208,0 +208,0 @@ for (const [name, p] of Object.entries(this.#projections)) {

{
"name": "monstrous",
"version": "0.1.1",
"version": "0.1.2",
"description": "a lightweight SQL composer for Node.js and PostgreSQL",

@@ -9,2 +9,3 @@ "main": "index.js",

"snap": "c8 tap -R list --no-cov",
"coverage": "c8 report --reporter=text-lcov | coveralls",
"release": "commit-and-tag-version"

@@ -74,2 +75,3 @@ },

"commit-and-tag-version": "^11.1.0",
"coveralls": "^3.1.1",
"tap": "^16.3.0"

@@ -76,0 +78,0 @@ },

@@ -5,2 +5,4 @@ # monstrous

[![Coverage Status](https://coveralls.io/repos/gitlab/monstrous/monstrous/badge.svg?branch=main)](https://coveralls.io/gitlab/monstrous/monstrous?branch=main)
```javascript

@@ -45,3 +47,3 @@ await db.select(

## on composition and reuse
## relations, composition, and reuse

@@ -52,4 +54,6 @@ monstrous is additionally inspired by the Clojure library [Penkala](https://github.com/retro/penkala) and the ["Relations as First-Class Citizen" principle](https://try-alf.org/blog/2013-10-21-relations-as-first-class-citizen) elucidated in Ruby by alf/bmg (although, like Penkala, it sticks to SQL instead of implementing a full relational algebra).

`db.select()` has one required argument: the bare minimum query is `db.select(db.libraries)`. What's inside those parentheses looks like a relation, has a `db.libraries.primary_key` and `qualified` columns, but in fact is -- when it matters -- a statement representing the retrieval of all records and all columns in `libraries`. All the detail of query _building_ happens on and to statements, with fluent functions like `join`, `filter`, `limit`, and `project`. Query builder functions can be used in any order and combination as long as references are preserved: you can't `filter` a column in `authors` before you `join(db.authors)` into your statement.
`db.select()` has one required argument: the bare minimum query is `db.select(db.libraries)`. Inside those parentheses is a relation, with a `db.libraries.primary_key` and `qualified` columns, which can be transformed into (essentially) another relation, and another, and another, through fluent functions like `join`, `filter`, `limit`, and `project`. Each relation-builder function returns a _new_ relation -- intermediary relations can be used and built off of repeatedly.
Relations' columns are dollar-prefixed properties: `db.libraries.$id`, `db.authors.$name`. Use these properties instead of strings -- while you can get away with un- or partially-qualified names much of the time, you also lose out on some of monstrous' automatic resolution on the fully-qualified and quoted name returned by `db.libraries.$id`, and risk ambiguous column names appearing in the final query. Keys as in criteria objects can be specified `{[db.libraries.$id]: 2}`. Spreading an object (`[...db.libraries]`) returns all columns, useful in projections.
Fluent functions come in two flavors:

@@ -61,3 +65,3 @@

- `join` will declare and attach a single new join relation
- `join` will declare a single new join relation and its join conditions
- `filter` will augment an existing or create a new `where` clause

@@ -72,2 +76,4 @@ - `group` will append its field(s) to the `group by` clause

Functions can be used in any order and combination as long as references are preserved: you can't `filter` a column in `authors` before you `join(db.authors)` into your statement.
```javascript

@@ -91,18 +97,18 @@ await db.select(db.libraries

```javascript
const books_near_me = db.libraries
const ipsum = db.libraries
.join(db.holdings)
.join(db.books)
.filter({[db.libraries.$postcode]: '12345'});
.join(db.authors)
.filter({[`${db.authors.$name} ilike`]: 'lauren%ipsum'});
db.attach( // don't do this on an application hot path!
books_near_me
.join(db.authors)
.filter({[`${db.authors.$name} ilike`]: 'lauren%ipsum'})
['saved_queries', 'ipsum']
// don't do this on an application hot path!
db.attach(ipsum, ['saved_queries', 'ipsum']);
// elsewhere....
const result = await db.select(
db.saved_queries.ipsum.filter({[db.libraries.$postcode]: '12345'})
);
await db.select(db.saved_queries.ipsum);
```
Furthermore, other attached or ad-hoc queries can use `books_near_me` as a base without altering its future executions. Every fluent function returns an updated clone of its base statement.
Furthermore, other attached or ad-hoc queries can use `ipsum` as a base without altering its future executions. Every fluent function returns an updated clone of its base statement.

@@ -127,3 +133,6 @@ ## connect

```javascript
db.expr(`extract(years from justify_interval($1 - ${db.employees.hired_at}))`, [new Date()])
db.expr(
`extract(years from justify_interval($1 - ${db.employees.hired_at}))`,
[new Date()]
).as('tenure') // alias only required in projection!
```

@@ -170,3 +179,3 @@

The `on` criteria map the columns of the newly joined relation to, usually, fully qualified columns (exposed as dollar-prefixed properties) of any already-joined relation. There is no "handedness" to criteria, so the division into criteria keys and values is a matter of taste. Literals and `expr`s are also valid `on` criteria values only.
The `on` criteria map the columns of the newly joined relation to, usually, fully qualified columns of any already-joined relation. There is no "handedness" to criteria, so the division into criteria keys and values is a matter of taste. Literals and `expr`s are also valid `on` criteria values only.

@@ -191,2 +200,4 @@ Results are automatically projected as `new_relname: [record object, record object]` to the most recently joined relation referenced in the `on`, but you can also override with your own projection.

Spreading a relation with `...` yields all columns:
```javascript

@@ -230,3 +241,3 @@ [...db.employees, db.libraries.$postcode] // add library postcode to all employee fields

Libraries and patrons also use the `$columns` field to specify fields without renaming them. `$columns` is processed similarly to the array form of the projection. In the example, the `director` instead specifies only a subset of fields one by one, and `tenure` is a raw SQL expression which will be interpolated into the query. As always, raw SQL is a potential vector for SQL injection; use it carefully!
`libraries` and `patrons` also use the `$columns` field to specify fields without renaming them. `$columns` is processed similarly to the array form of the projection. In the example, the `director` instead specifies only a subset of fields one by one, and `tenure` is a raw SQL expression which will be interpolated into the query. As always, raw SQL is a potential vector for SQL injection; use it carefully!

@@ -432,2 +443,3 @@ `db.expr`s may be included in a `$columns` array, but must be aliased. In other words, the `director` could be constructed thus:

- ad-hoc CTEs?
- lateral join exprs?
- set operations (`union [all]`, `intersect`, `except`)

@@ -434,0 +446,0 @@ - wrapped tasks with connection settings?

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc