Git Product home page Git Product logo

functional-orm's Introduction

Gostek

Build Greenkeeper badge

Gostek is a completely typesafe querybuilder written in TypeScript

Fancy, huh?

Goals of the project

Typesafe queries

One of the main design goals of this library is to be able to provide completely typesafe queries. It means that when you do SELECT id, name you actually get { id: number, age: string } without the need to write any types manually 😎

Generating types based on DB structure

What makes this library unique is the fact that you don't have to write any types or models manually. They're all generated based on your database structure and provide 100% typesafety!

Examples (draft syntax)

Gostek generates types and models based on your DB schema, for example:

const User = {
  name: 'user',
  columns: {
    id: { type: 'int4', notNull: true },
    name: { type: 'text', notNull: false },
  },
} as const;

Immutable query

Each function returns an immutable query representation:

const query1 = db.from(User).select(['id']);

The following query selects age and id from User:

const query2 = db.from(User).select(['id', 'age']);

It would be a compile-time error to try to select columns which don't exist:

const query3 = db.from(User).select(['id', 'foo']);
// Argument of type '"foo"' is not assignable to parameter of type '"*" | ("age" | "id")[]'.

All queries are typesafe! Executing it returns only fields which are selected:

const result1 = await db.from(User).select(['id']).execute();
// {
//   readonly id: number;
// }[]

Mind that nullability of name was taken into account as well.

There's a shorthand notation for selecting all properties and it's also typesafe:

const result2 = await db.from(User).select('*').execute();
// {
//   readonly id: number;
//   readonly name: string | null;
// }[]

Typesafe operators

Operators are also typesafe! In this case, Gostek knows that types of User.name and name have to match:

db.from(User).select(['name']).where(['name', Op.$eq, 'Kasia']);

The library is also aware of the operator you're using:

db.from(User)
  .select(['name'])
  .where(['id', Op.$in, [1, 2, 3]]);
// $in requires an array!

This would be a compile-time TypeScript error:

db.from(User).select(['name']).where(['name', Op.$eq, 123]);
// Type 'number' is not assignable to type 'string | null'.

This is also an error because $in requires the argument to be an array of values:

db.from(User).select(['name']).where(['name', Op.$in, 'Michał']);
// Type 'string' is not assignable to type '(string | null)[]'.

0.1.0 plan

  • finish generator which outputs safely-typed models for simple tables
  • support PostgreSQL
  • make sure all queries from the README work on a real database

0.2.0 plan

  • allow for more complex where conditions (and, or)

functional-orm's People

Contributors

dependabot-preview[bot] avatar greenkeeper[bot] avatar kozikkam avatar typeofweb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

kozikkam

functional-orm's Issues

Support shorthand where definitions

Right now it's necessary to always write full where syntax:

.where({ [WhereOp.$and]: [['id', Op.$in, [1, 2, 3]]] })

it should be possible to write just

.where({ [WhereOp.$and]: ['id', Op.$in, [1, 2, 3]] })

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on Greenkeeper branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet.
We recommend using:

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please click the 'fix repo' button on account.greenkeeper.io.

Add tests

  • Add library such as mocha, sinon, and chai for testing
  • Make sure it works with TypeScript
  • Add fast-check for property based testing

Add mock tables and data

  • use pg or pg-promise
  • add SQL in raw SQL files
  • create tables in beforeEach and drop in afterEach

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on Greenkeeper branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet.
We recommend using:

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please click the 'fix repo' button on account.greenkeeper.io.

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on Greenkeeper branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet.
We recommend using:

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please click the 'fix repo' button on account.greenkeeper.io.

Various (random) questions about the syntax

Hi @mmiszy I really like your approach! Would you be willing to clarify your vision a bit further? Here are some random, unorganized questions that arrived in my mind when evaluating your library.

  1. why did you decide to use the columns prefix ? i.e. why User.columns.id instead of a simpler User.id ?
  2. how did you imagine a SQL join ? e.g. a query to get comments for a particular post
  3. have you thought about merging the querying with side effects under the same syntax? i.e. how did you imagine an insert statement
  4. since in SQL processing, the table is always logically first (cf. SQL queries don't start with SELECT maybe the from could be put on a level «higher» (syntactically) and serve for both: queries (select) and mutations (insert, update) ?

Support nested WHERE clauses

It should be possible to write more complicated WHERE clauses, such as

WHERE waga < 50 AND (name = 'jason' OR (age > 3 AND age < 18))

Refactor connection create

Refactor DB connection is the connection is created and maintained by this library instead of requiring an external connection to be passed to execute.

  • automatically create a connection
  • use pools
  • make sure no multiple connections to the same DB are created

Implement simple queries

  • Implement from and select
  • Make sure it works with PostgreSQL
  • Add tests
  • Make sure it's typesafe

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on Greenkeeper branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet.
We recommend using:

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please click the 'fix repo' button on account.greenkeeper.io.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.