xavierlacot / joli.js

joli.js is an Activerecord-like javascript ORM, particularly suited for being used in the Appcelerator Titanium Mobile framework.
MIT License
267 stars 60 forks source link

Feature request: Query model tables and curry query functions #8

Closed RoelWKramer closed 13 years ago

RoelWKramer commented 13 years ago

In django's ORM it is possible to chain query functions and query model tables immediately. Example:

Entry.objects.filter(headline__startswith='What').exclude(pub_date__gte=datetime.now()).filter(pub_date__gte=datetime(2005, 1, 1))

Example 2:

    q1 = Entry.objects.filter(headline__startswith="What")
    q2 = q1.exclude(pub_date__gte=datetime.now())
    q3 = q1.filter(pub_date__gte=datetime.now())

Now you have to use joli.query().select().from('dbtable_name').where('name', 'Roel'); Which is quite long and also introduces where, select and query functions. Using this also has little benefits over using the SQL language.

It would be nice if it is possible to chain query functions and query tables immediately like this: dbtable_name.findBy('name', 'Roel').findBy('lastname', 'kramer') or like this: dbtable_name.where('name', 'Roel').where(lastname', 'kramer')

See the django docs for a better explanation. It uses other function names, which might inspire you, both for good new functionality and naming of functions. Docs: https://docs.djangoproject.com/en/dev/topics/db/queries/

xavierlacot commented 13 years ago

Hi Roel,

The query model offered by joli.js is rather consistant and almost allows what you are asking. For instance, it is possible to search records at a class-level:

// returns one 'City' record
models.city.findOneBy('name', 'Paris');

// returns a collection of 'Human' records
models.human.findBy('city_id', 12);

You can just not chain the findBy() calls, eg. models.human.findBy('city_id', 12).findBy('first_name', 'Michel'); For such needs, there are two ways in joli.js:

1- use the abstract query language:

// returns the humans living in the city 12 and with "Michel" as first name
var q = new joli.query().select().from('human').where('city_id = ?', 12).andWhere('first_name = ?', 'Michel');
var humans = q.execute();

Note that this approach as a major benefit over plain SQL: it allows to build queries over several methods / functions, and to progressively add restrictions on queries objects. This is particularly useful in the seek for code mutualisation.

2- use the class-level "all()" finder :

// returns the humans living in the city 12 and with "Michel" as first name
var humans = models.human.all({
  where: [
    'city_id = ?': 12,
    'first_name = ?': 'Michel',
  ]
});

Have a look at joli.js's code, or rather at the test suite, which provides a lot of useful examples: https://github.com/xavierlacot/joli.js-demo/tree/master/Resources/test