Requête de type sql sur un objet javascrip complexe

Description

Bonjour,

Cette fois-ci je poste un script qui permet, à partir de n'importe quel tableau d'objets complexes et hétérogènes, d'effectuer une sélection d'objets en utilisant une syntaxe proche du SQL.
Le script est hébergé à l'adresse :
http://svn.openihs.org/jsprojects/trunk/toolkit/js/array.js
si vous avez un 404 not found, vérifiez qu'il n'y a pas d'espaces dans l'URL !

Ce script ajoute une méthode query à tous les tableau (plus exactement au prototype Array).

Fonction :
Array.prototype.query(request[, arg1..N])

Arguments :
request de type String et dont le format est REQUEST (voir ci-dessous)
arg1..N de tout type qui sont les éléments référencés dans la requête

Grammaire (la flemme de traduire) :
  • REQUEST := select FIELD_LIST [where CLAUSE_LIST] [limit [OFFSET,]LIMIT]
  • FIELD_LIST := * | FIELD[, FIELD[, FIELD[, etc.]]]
  • FIELD := PATH [as ALIAS]
  • PATH := object path foo.bar (must match with /[\w\.]+/)
  • ALIAS := result field name (must match with /\w+/)
  • CLAUSE_LIST := CLAUSE [EXP_OP CLAUSE [EXP_OP CLAUSE [etc]]]
  • parenthesis are allowed eg (CLAUSE EXP_OP CLAUSE) EXP_OP CLAUSE, etc.
  • EXP_OP := and | or
  • CLAUSE := PATH OP VALUE
  • OP := =(equals)|<>(not equals)|!=(not equals)|~(match)|!~(don't match)
  • VALUE := true|false|null|NUMBER|STRING|TAG
  • NUMBER := a number (must match with /\d+/)
  • STRING := a string (must match with /("[\"]+")|('[\']+')/)
  • WARNING: escaped quotes or double quotes is not supported: use TAG instead
  • TAG := %1..n refer to arg1..N
  • OFFSET := offset index
  • LIMIT := number of returned occurrences beginning at OFFSET index.


NOTES :
1. C'est une fonctionnalité que j'ai codé assez rapidement, en grande partie le matin dans le TGV en allant au boulot, donc soyez indulgent :-)
2. Bien entendu mon script n'a pas vocation de faire un SGBD en javascript
3. Les seuls opérateurs logiques supportés (entre les expressions) sont le "and" et le "or" (pas de "not")

Exemples d'utilisation.
On part du tableau suivant :

Source / Exemple :


addressBook = [
  {
    name: "Paul Durant",
    phone: [
      {type: "work", number: "0123456789"},
      {type: "cellular", prefered: true, number: "0654321987"}
    ],
    addresses: [
      {type: "work", street: "123 rue Truck", postal_code: "92000", city: "Nanterre"}
    ]
  }, {
    name: "Jean Dupont",
    phone: [
      {type: "home", prefered: true, number: "0987654321"},
      { type: "cellular", number: "0789456123"}
    ],
    addresses: [
      {type: "home",  street: "403 rue Inconnue", postal_code: "99999", city: "Laville"}
    ]
  }, {
    name: "Nicolas Duchmole",
    phone: [
      {type: "home", prefered: true, number: "0258147369"},
      {type: "cellular", number: "0639528417"}
    ]
  }, {
    name: "Jean Durant",
    phone: [
      {type: "home", number: "0545654582"},
      {type: "cellular", prefered: true, number: "0654123987"}
    ],
    addresses: [
      {type: "home", street: "le coin paumé", postal_code: "11111", city: "La ville perdue"}
    ]
  }
];

Conclusion :


Maintenant, quelques exemples de requêtes...
dans les cas suivants je sélectionne des champs précis mais il y a la possibilité de récupérer les objets dans leur ensemble en mettant "select * [...]"

addressBook.query("select name, addresses.city where addresses.type = \"home\"") donne :
[{"name":"Jean Dupont","city":"Laville"},{"name":"Jean Durant","city":"La ville perdue"}]

addressBook.query("select name, phone.number as phoneNumber where (addresses.type = \"home\" or phone.type = \"work\") and name ~ %1", /Durant$/) donne :
[{"name":"Paul Durant","phoneNumber":"0123456789"},{"name":"Jean Durant","phoneNumber":"0545654582"}]

addressBook.query("select name, phone.number as phoneNumber where phone.prefered = true limit 1,2") donne :
[{"name":"Jean Dupont","phoneNumber":"0987654321"},{"name":"Nicolas Duchmole","phoneNumber":"0258147369"}]

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.