Выполнение SQL-подобных запросов над данными — как в браузере, так и на сервере

    Marak Squires выпустил в свет JSLINQ — реализацию LINQ для JavaScript, работающую как на стороне браузера, так и на стороне сервера (к примеру, node.js). Поддерживаются такие конструкции, как JOIN, UNION, RANGE, DISTINCT, COUNT etc.

    Смотрите:

    JSLINQ


    var sample = JSLINQ(sampleData).
     Where(function (item) {return item.FirstName == "Chris";}).
     Select(function (item) {return item.FirstName;}).
     OrderBy(function (item) {return item;});

    * This source code was highlighted with Source Code Highlighter.

    Кстати, XaocCPS когда-то рассказывал о проекте jLinq, а Карл Гертин упомянул о проекте JSINQ, которые также можно посмотреть.

    jLinq


    var results = jLinq.from(data.users)
      .startsWith("first", "a")
      .orEndsWith("y")
      .orderBy("admin", "age")
      .select();


    * This source code was highlighted with Source Code Highlighter.

    JSINQ


    var query = new jsinq.Query('\
      from order in $1 \
      group order by order.customerId into g \
      select {customerId: g.getKey(), items: g.sum(function(g) { return g.items; })} \
      into h \
      join customer in $0 on h.customerId equals customer.id \
      where h.items > 10 \
      orderby h.items descending \
      select {lastname: customer.lastname, items: h.items} \
    '
    );

    query.setValue(0, customers);
    query.setValue(1, orders);
    var result = query.execute();


    * This source code was highlighted with Source Code Highlighter.

    Комментарии 21

      +1
      Не знаю. Мне все-таки ближе реализации функционала хранилища на подобие Ext.Data или TaffyDB. SQL на стороне клиента, на мой взгляд не нужен.
        0
        Мне тоже интереснее этот функционал на сервере. Благо на node.js он работает :)
        0
        Было бы здорово, иметь возможность рендерить скомпилированные LINQ (.net) запросы в подобный JS код. Один раз написал запрос, и пользуйся им потом и на клиенте, и в кеш сервере, и в БД.

        Технически возможность есть…
          +8
          По-моему синтаксис получается нереально раздутым. Понимаю, конечно, что иначе наверное никак, но каждый раз писать

          OrderBy( function(item) { return item.name } )

          вместо

          order by name

          мне бы очень быстро надоело.
            –3
            Сперва

                var ItemName = function(item) { return item.name; }

            Затем

                OrderBy(ItemName)
              0
              Это если сортировать по одному и тому же параметру многократно. А если всего один раз, то получается еще длиннее
              0
              можно реализовать JSON-QL
              структура
              Book = {id:'int', name:'string', price:'float', publish:'datetime'}
              Shop = {id:'int', books:'list<Book>'}

              выборка
              var criteria = {books:{lt:{price:100},gt:{publish:'2010-04-01 10:20:00'}}};
              select('Shop', criteria)

              на обычном SQL это длинный запрос с JOIN

              пример реализации
              +7
              Я бы относился к этому не как к «SQL» а как к удобной библиотеке функционального стиля для работы с коллекциями. И это очень удобно!
                –2
                То ли пример неудачный, то ли задумка какая-то странная. Синтаксис вывернут наизнанку: сначала Where, затем Select. И логика примера тоже подозрительная — какой смысл искать FirstName, если мы его уже знаем. На нормальном SQL, я так понимаю, это будет:
                select FirstName
                from sampleData
                where FirstName = 'Chris'
                order by 1


                Во втором случае вообще замес страшный. Затрудняюсь в нормальный SQL перевести.
                Имхо, стоит сделать обертку — парсер из нормального SQL в этот SQL-like, и только тогда начинать пользоваться. Тогда в приложениях можно будет писать запросы на переносимом SQL без всяких вывертов.
                  +1
                  Упоминание SQL совершенно неуместно в этой статье, это обычные функции высшего порядка на Javascript, только и всего.
                    +2
                    Да вот тоже подумал, что с SQL общего только названия конструкций — select, where, order и т.п. В принципе, это даже хорошо — назначение функции понятно. Но одни названия не дают права называться SQL.
                    +1
                    На самом деле, порядок операторов LINQ не очень читаем, зато полностью соответствует порядку их выполнения базой данных. Инструкция select выполняется в самую последнюю очередь, когда все остальные параметры уже заданы.
                      +1
                      Спасибо, это многое объясняет. По сути собирается конвейер обработки JS объекта.
                    +1
                    Если присмотреться к исходникам проекта, то можно обнаружить, что операторы являются энергичными, а не ленивыми как в LINQ. Where сразу бежит по массиву, рожая новый, то есть совсем другой behavior по сравнению LINQ…

                    Кстати, где-то видел анонимные функции в JS из одного expression в такой вот записи (ну прямо лямбды), вроде даже тестировал и вроде даже где-то работало:
                    var sample = JSLINQ(sampleData)
                    .Where(function (x) x.FirstName == "Chris")
                    .Select(function (x) x.FirstName)
                    .OrderBy(function (x) x);


                    Если такое существует, то может кто подкинет ссылку, с каких версий, в каких бразуерах и т.п.
                      0
                      Существует в Firefox 3+
                      Насчет других браузеров — не натыкался, вроде нет.
                        –2
                        Парсер Хабрахабра заменил «c» в слове «script», так что гиперссылка Ваша неработоспособна.
                          +1
                          Ох, уж этот хабрапарсер… :) Спасибо за замечание.
                          Ссылка: New in Javascript 1.8: Expression closures
                            0
                            Благодарю. Жаль, что фича не распространена…
                              0
                              вот интересное решение osteele.com/sources/javascript/functional/
                                0
                                вроде в jLinq подобное имеется, можно лямбды в стиле C# писать:
                                .select('x => x * 2')
                                Оно тупо парсит текст на аргументы и тело, а потом конструирует функцию конструктором Function(args, body). Из минусов — кавычки литералов, потеря подсветки кода и невозможность замкнуться на что-либо…
                                  0
                                  А оно нужно только для простых вроде этих функций когда лень писать :)

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                    Самое читаемое