npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@chego/chego

v2.1.7

Published

Chego core module

Downloads

25

Readme

chego

Chego is a lightweight Javascript library written in TypeScript. The goal of this project is to provide tools to create an easy-to-use, portable, and readable code of database application. 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.

Check the following database drivers:

Table of contents

Install

npm install --save @chego/chego

Usage

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.

const { newChego, newQuery } = require("@chego/chego");
const { <databaseDriver> } = require("@chego/chego-<database>");

const chego = newChego(<databaseDriver> ,{ 
    ...database config... 
});
const query = newQuery().select('*').from('superheroes','villains').where('origin').is.eq('Gotham City').limit(10);

await chego.connect();

chego.execute(query)
.then(result => { 
    console.log('RESULT:', JSON.stringify(result));
    chego.disconnect();
})
.catch(error => { 
    console.log('ERROR:', error);
    chego.disconnect();
});

Tips

Choosing columns/properties

select().from('superheroes'); // selects all columns/properties
select('*').from('superheroes'); // selects all columns/properties
select('name', 'origin').from('superheroes'); // selects only 'name' and 'origin'

Selecting from multiple tables

select().from('superheroes','villains') ...

Using table.key pattern

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.

In single table queries or MySQL driver this is not an issue but in other cases, you should consider using it.

select().from('superheroes','villains').where('superheroes.name')

Multiple properties in where clause

By default all properties in where clause are wrapped with and().

where('name', 'foo', 'bar')
// will become in the further stage of processing the query
where(and('name', 'foo', 'bar'))

Use and() and or() helpers

With and() and or() helpers you can sinplify your queries

where(or('foo','bar')).are.eq(1) === where('foo').or.where('bar').are.eq(1)

where(and('foo','bar')).are.eq(or(1,2)) === where('foo').and.where('bar').are.eq(1).or.eq(2)

Nesting LogicalOperatorScope objects

It is possible to create LogicalOperatorScope objects inside another LogicalOperatorScope object, which allows you to use more complex conditions.

where(and('foo', or('bar','baz'))).are.eq('cool')
// will be parsed to
(foo === 'cool' && (bar === 'cool' || baz === 'cool'))

Logical operators

Write queries the way you want.

// query with logical operator
query.select('*').from('comics').where('writer').is.eq('Stan Lee', or('Bob Kane'));

// query without logical operator
query.select('*').from('comics').where('writer').is.eq('Stan Lee').or.is.eq('Bob Kane');

Use logical operators to simplify your queries.

// query with logical operator
query.select('*').from('comics').where('writer', or('editor')).is.eq('Stan Lee');

// queries without logical operator
query.select('*').from('comics').where('writer').or.where('editor').are.eq('Stan Lee');

query.select('*').from('comics').where('writer').is.eq('Stan Lee').or.where('editor').is.eq('Stan Lee');

Grouping results

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.

The default sort order is set in ascending order.

groupBy('foo ASC')
// or
groupBy('foo')

// multiple values
groupBy('foo DESC', 'bar ASC', 'baz')

Sorting results

Like in MySQL it is possible to sort a query results by a single column or multiple columns in ascending or descending order.

orderBy('foo ASC')
// or
orderBy('foo')

// multiple values
orderBy('foo DESC', 'bar ASC', 'baz')

Alias expression

It is possible to create alias property with "alias expression" ('<key> AS <alias>').

query.select('alterEgo AS knownAs').from('superheroes');

Although using "alias expression" is less efficient because in the end it is parsed to alias property.

Wrapping query parts

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.

query.select('name').from('superheroes').where('origin').is.equalTo('New York City').and.inParentheses(
    (query) => query.where('teamAffiliation').is.equalTo("Avengers")
    .or.where('teamAffiliation').is.equalTo('Defenders')
).limit(10)

// conditions formula
// (origin === 'New York City' && (teamAffiliation === 'Avengers' || teamAffiliation === 'Defenders'))

Running multiple queries in one call

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.

...
const query1 = newQuery().insert({
            name: "Thanos",
            alterEgo: "",
            origin: "Titan",
            publisher: "mcUT642",
            createdBy: [
                "jsTR612"
            ],
            firstAppearance: "tiIM771"
        }).to('villains');
        
const query2 = newQuery().select('*').from('villains').limit(10);

chego.execute(query1, query2)
.then(result => { 
   ...
})
.catch(error => { 
    ...
});

Testing subqueries with Exists operator

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.

More information about MySQL EXISTS operator can be found here

Setting filter condition for groups of rows with Having clause

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. In chego, having clause is available only as a succession of the groupBy clause.

Unions

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:

  • union: which imitates MySQLs UNION DISTINCT default UNION
  • unionAll: which imitates MySQLs UNION ALL

More information about MySQL UNION operator can be found here

Checking if specified value matches any value with In operator

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

Testing values with Like operator

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 _.

  • The percentage ( % ) wildcard matches any string of zero or more characters.
  • The underscore ( _ ) wildcard matches any single character.

More information about MySQL LIKE operator can be found here

API

IChego

execute(...queries: IQuery[]): Promise<any> - uses defined database driver to parse and execute given queries. It returns Promise with query results or Error.

connect(): Promise<any> - establishes a connection.

disconnect(): Promise<any> - terminates a connection.

IQuery

It extends IQueryMethods to provide fluent interface for builder. More details can be found here.

scheme: IQueryScheme - returns query scheme object. More details can be found here.

Primary functions

newChego

newChego(driver:Fn, config:object): IChego

Initializes database driver and returns new Chego object.

newQuery

newQuery(): IQuery

Returns new query scheme builder.

Helpers

rowId

rowId(table?:string, alias?: string): Property

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.

The default value for the argument alias is 'id'

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.

In the on() clause, rowId has a default value for the table argument, which is valid for keyA or keyB.

query.select('*').from('superheroes').where('publisher').is.eq((query) => { query.select(rowId()).from('publishers').where('name').is.eq('Marvel Comics') });

alias

alias(name: string, alias: string): Property

It is used to give the property a temporary name.

query.select(alias('alterEgo', 'knownAs')).from('superheroes');

and/or

and/or(...properties: AnyButFunction[]): LogicalOperatorScope

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.

where(or('foo', 'bar')).is.eq(1)
// will be parsed to
(foo === 1 || bar === 1)

and(), or() can be used in the where clause and within the conditions: eq, lt and gt.

withCustomId

withCustomId("custom id", {foo:"bar"}): ItemWithCustomId

Currently implemented for Firebase. Use this if you want to add an entry under the defined id.

query.insert(withCustomId("Foo", { foo:"bar" })).to('...');

MySQL Functions

In Chego you can use some of the functions - list - known from MySQL.

Examples

Selecting data

query.select('title', 'nr).from('comics').orderBy('published DESC');

Updating data

query.update('superheroes').set({superPowers:[]}).where('name').is.eq('Punisher');

Removing rows

query.delete().from('villains').where('origin').is.not.eq('Gotham City');

Inserting data

query.insert({
    name: "Batman",
            alterEgo: "Bruce Wayne",
            origin: "Gotham City",
            publisher: "dcZP373",
            createdBy: [
                "bkOO872",
                "bfOU542"
            ],
            firstAppearance: "acUW996"
},{
    name: "Spiderman",
            alterEgo: "Peter Benjamin Parker",
            origin: "New York City",
            publisher: "mcUT642",
            createdBy: [
                "plTW543",
                "ghIO920"
            ],
            firstAppearance: "afUQ256"
}).to('superheroes');

Nested queries

query.select('*').from('superheroes').where('publisher').is.eq(
    (query) => query.select('id').from('publishers')
    .where('name').is.eq('Marvel Comics')
).limit(100);

Joining queries

// join
query.select('*').from('comics').join('publishers').on('publishers.id', 'comics.publisher').limit(10);
// left join
query.select('*').from('comics').leftJoin('publishers').on('publishers.id', 'comics.publisher').limit(10);
// right join
query.select('*').from('comics').rightJoin('publishers').on('publishers.id', 'comics.publisher').limit(10);
// full join
query.select('*').from('comics').fullJoin('publishers').on('publishers.id', 'comics.publisher').limit(10);

// using
query.select('*').from('superheroes').join('villains').using('id').limit(10);

Like

// like
query.select('*').from('superheroes').where('name').is.like('%man'); // Batman, Superman ...
query.select('*').from('superheroes').where('name').is.like('Iron%'); // Ironman, Iron fist ...
query.select('*').from('superheroes').where('name').is.like('Hu__'); // Hulk
query.select('*').from('superheroes').where('name').is.like('S%n'); // Spiderman, Superman ...

// not like
query.select('*').from('superheroes').where('name').is.not.like('%man'); // Batman, Superman ...

Unions

// union - distinct
query.select('name').from('superheroes').union((q)=>q.select('name).from('villains'));
// union - all
query.select('name').from('superheroes').unionAll((q)=>q.select('name).from('villains'));

In

// in
query.select('*').from('publishers').where('country').is.in('US');
// not in
query.select('*').from('publishers').where('country').is.not.in('US');

Having

// having
query.select('*').from('superheroes').groupBy('origin').having('superpowers').like('%flying%');
// not having
query.select('*').from('superheroes').groupBy('origin').having('superpowers').not.like('%flying%');

Exists

// exists
query.select('*').from('superheroes').where('publisher').exists(
    (query) => query.select('id').from('publishers')
    .where('name').is.eq('Marvel Comics')
);
// not exists
query.select('*').from('superheroes').where('publisher').not.exists(
    (query) => query.select('id').from('publishers')
    .where('name').is.eq('Marvel Comics')
);

Contribute

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. Whether you find a bug or have a feature request, please contact us. With your help, we'll make it a great tool.

How to contribute

Follow our kanban boards to be up to date

Kanban boards

Join the team, feel free to catch any task or suggest a new one.

License

Copyright (c) 2019 Chego Team

Licensed under the MIT license.