Giter Club home page Giter Club logo

squel's Introduction

NOTE: Squel is no longer actively maintained. I only have time for occasional bugfixes and small-scale work. If you are interested in helping with squel maintenance the help would be welcome. Alternatively, please use another library - we recommend knex.

squel - SQL query string builder

Build Status CDNJS NPM module NPM downloads Join the chat at https://discord.gg/PBAR2Bz Follow on Twitter

A flexible and powerful SQL query string builder for Javascript.

Full documentation (guide and API) at https://hiddentao.github.io/squel.

Features

  • Works in node.js and in the browser.
  • Supports the standard SQL queries: SELECT, UPDATE, INSERT and DELETE.
  • Supports non-standard commands for popular DB engines such as MySQL.
  • Supports paramterized queries for safe value escaping.
  • Can be customized to build any query or command of your choosing.
  • Uses method chaining for ease of use.
  • Small: ~7 KB minified and gzipped
  • And much more, see the guide..

WARNING: Do not ever pass queries generated on the client side to your web server for execution. Such a configuration would make it trivial for a casual attacker to execute arbitrary queries—as with an SQL-injection vector, but much easier to exploit and practically impossible to protect against.

Note: Squel is suitable for production use, but you may wish to consider more actively developed alternatives such as Knex

Installation

Install using npm:

$ npm install squel

Available files

  • squel.js - unminified version of Squel with the standard commands and all available non-standard commands added
  • squel.min.js - minified version of squel.js
  • squel-basic.js - unminified version of Squel with only the standard SQL commands
  • squel-basic.min.js - minified version of squel-basic.js

Examples

Before running the examples ensure you have squel installed and enabled at the top of your script:

var squel = require("squel");

SELECT

// SELECT * FROM table
squel.select()
    .from("table")
    .toString()

// SELECT t1.id, t2.name FROM table `t1` LEFT JOIN table2 `t2` ON (t1.id = t2.id) WHERE (t2.name <> 'Mark') AND (t2.name <> 'John') GROUP BY t1.id
squel.select()
    .from("table", "t1")
    .field("t1.id")
    .field("t2.name")
    .left_join("table2", "t2", "t1.id = t2.id")
    .group("t1.id")
    .where("t2.name <> 'Mark'")
    .where("t2.name <> 'John'")
    .toString()

// SELECT `t1`.`id`, `t1`.`name` as "My name", `t1`.`started` as "Date" FROM table `t1` WHERE age IN (RANGE(1, 1.2)) ORDER BY id ASC LIMIT 20
squel.select({ autoQuoteFieldNames: true })
    .from("table", "t1")
    .field("t1.id")
    .field("t1.name", "My name")
    .field("t1.started", "Date")
    .where("age IN ?", squel.str('RANGE(?, ?)', 1, 1.2))
    .order("id")
    .limit(20)
    .toString()

You can build parameterized queries:

/*
{
    text: "SELECT `t1`.`id`, `t1`.`name` as "My name", `t1`.`started` as "Date" FROM table `t1` WHERE age IN (RANGE(?, ?)) ORDER BY id ASC LIMIT 20",
    values: [1, 1.2]
}
*/
squel.select({ autoQuoteFieldNames: true })
    .from("table", "t1")
    .field("t1.id")
    .field("t1.name", "My name")
    .field("t1.started", "Date")
    .where("age IN ?", squel.str('RANGE(?, ?)', 1, 1.2))
    .order("id")
    .limit(20)
    .toParam()

You can use nested queries:

// SELECT s.id FROM (SELECT * FROM students) `s` INNER JOIN (SELECT id FROM marks) `m` ON (m.id = s.id)
squel.select()
    .from( squel.select().from('students'), 's' )
    .field('id')
    .join( squel.select().from('marks').field('id'), 'm', 'm.id = s.id' )
    .toString()

UPDATE

// UPDATE test SET f1 = 1
squel.update()
    .table("test")
    .set("f1", 1)
    .toString()

// UPDATE test, test2, test3 AS `a` SET test.id = 1, test2.val = 1.2, a.name = "Ram", a.email = NULL, a.count = a.count + 1
squel.update()
    .table("test")
    .set("test.id", 1)
    .table("test2")
    .set("test2.val", 1.2)
    .table("test3","a")
    .setFields({
        "a.name": "Ram",
        "a.email": null,
        "a.count = a.count + 1": undefined
    })
    .toString()

INSERT

// INSERT INTO test (f1) VALUES (1)
squel.insert()
    .into("test")
    .set("f1", 1)
    .toString()

// INSERT INTO test (name, age) VALUES ('Thomas', 29), ('Jane', 31)
squel.insert()
    .into("test")
    .setFieldsRows([
        { name: "Thomas", age: 29 },
        { name: "Jane", age: 31 }
    ])
    .toString()

DELETE

// DELETE FROM test
squel.delete()
    .from("test")
    .toString()

// DELETE FROM table1 WHERE (table1.id = 2) ORDER BY id DESC LIMIT 2
squel.delete()
    .from("table1")
    .where("table1.id = ?", 2)
    .order("id", false)
    .limit(2)

Paramterized queries

Use the useParam() method to obtain a parameterized query with a separate list of formatted parameter values:

// { text: "INSERT INTO test (f1, f2, f3, f4, f5) VALUES (?, ?, ?, ?, ?)", values: [1, 1.2, "TRUE", "blah", "NULL"] }
squel.insert()
    .into("test")
    .set("f1", 1)
    .set("f2", 1.2)
    .set("f3", true)
    .set("f4", "blah")
    .set("f5", null)
    .toParam()

Expression builder

There is also an expression builder which allows you to build complex expressions for WHERE and ON clauses:

// test = 3 OR test = 4
squel.expr()
    .or("test = 3")
    .or("test = 4")
    .toString()

// test = 3 AND (inner = 1 OR inner = 2) OR (inner = 3 AND inner = 4 OR (inner IN ('str1, 'str2', NULL)))
squel.expr()
    .and("test = 3")
    .and(
        squel.expr()
            .or("inner = 1")
            .or("inner = 2")
    )
    .or(
        squel.expr()
            .and("inner = ?", 3)
            .and("inner = ?", 4)
            .or(
                squel.expr()
                    .and("inner IN ?", ['str1', 'str2', null])
            )
    )
    .toString()

// SELECT * FROM test INNER JOIN test2 ON (test.id = test2.id) WHERE (test = 3 OR test = 4)
squel.select()
    .join( "test2", null, squel.expr().and("test.id = test2.id") )
    .where( squel.expr().or("test = 3").or("test = 4") )

Custom value types

By default Squel does not support the use of object instances as field values. Instead it lets you tell it how you want specific object types to be handled:

// handler for objects of type Date
squel.registerValueHandler(Date, function(date) {
  return date.getFullYear() + '/' + (date.getMonth() + 1) + '/' + date.getDate();
});

squel.update().
  .table('students')
  .set('start_date', new Date(2013, 5, 1))
  .toString()

// UPDATE students SET start_date = '2013/6/1'

Note that custom value handlers can be overridden on a per-instance basis (see the docs)

Custom queries

Squel allows you to override the built-in query builders with your own as well as create your own types of queries:

// ------------------------------------------------------
// Setup the PRAGMA query builder
// ------------------------------------------------------
var util = require('util');   // to use util.inherits() from node.js

var CommandBlock = function() {};
util.inherits(CommandBlock, squel.cls.Block);

// private method - will not get exposed within the query builder
CommandBlock.prototype._command = function(_command) {
  this._command = _command;
}

// public method - will get exposed within the query builder
CommandBlock.prototype.compress = function() {
  this._command('compress');
};

CommandBlock.prototype.buildStr = function() {
  return this._command.toUpperCase();
};


// generic parameter block
var ParamBlock = function() {};
util.inherits(ParamBlock, squel.cls.Block);

ParamBlock.prototype.param = function(p) {
  this._p = p;
};

ParamBlock.prototype.buildStr = function() {
  return this._p;
};


// pragma query builder
var PragmaQuery = function(options) {
  squel.cls.QueryBuilder.call(this, options, [
      new squel.cls.StringBlock(options, 'PRAGMA'),
      new CommandBlock(),
      new ParamBlock()
  ]);
};
util.inherits(PragmaQuery, squel.cls.QueryBuilder);


// convenience method (we can override built-in squel methods this way too)
squel.pragma = function(options) {
  return new PragmaQuery(options)
};


// ------------------------------------------------------
// Build a PRAGMA query
// ------------------------------------------------------

squel.pragma()
  .compress()
  .param('test')
  .toString();

// 'PRAGMA COMPRESS test'

Examples of custom queries in the wild:

Non-standard SQL

Squel supports the standard SQL commands and reserved words. However a number of database engines provide their own non-standard commands. To make things easy Squel allows for different 'flavours' of SQL to be loaded and used.

At the moment Squel provides mysql, mssql and postgres flavours which augment query builders with additional commands (e.g. INSERT ... RETURNING for use with Postgres).

To use this in node.js:

var squel = require('squel').useFlavour('postgres');

For the browser:

<script type="text/javascript" src="https://rawgithub.com/hiddentao/squel/master/squel.min.js"></script>
<script type="text/javascript">
  squel = squel.useFlavour('postgres');
</script>

(Internally the flavour setup method simply utilizes the custom query mechanism to effect changes).

Read the the API docs to find out available commands. Flavours of SQL which get added to Squel in the future will be usable in the above manner.

Building it

To build the code and run the tests:

$ npm install
$ npm test <-- this will build the code and run the tests

Releasing it

Instructions for creating a new release of squel are in RELEASE.md.

Contributing

Contributions are welcome! Please see CONTRIBUTING.md.

Older verions

Note: The latest Squel version only works on Node 0.12 or above. Please use Squel 4.4.1 for Node <0.12. The old 4.x docs are also still available.

Ports to other languages

License

MIT - see LICENSE.md

squel's People

Contributors

acroca avatar alexturek avatar bchociej avatar daawesomep avatar demurgos avatar diwu1989 avatar drewish avatar evansolomon avatar gokaygurcan avatar hiddentao avatar holm avatar idonman avatar jasonbaker avatar jbowes avatar llambeau avatar mtsr avatar munir131 avatar nikolaygalkin avatar nl0 avatar parisholley avatar pcothenet avatar pvnr0082t avatar return-none avatar saintsjd avatar schmod avatar serges avatar splattael avatar vavere avatar waterytowers avatar wms 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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

squel's Issues

SQL Injection attacks

In order to avoid SQL Injection attacks, we should use internally an escape function for all parameters.

What do you think ?

expr() doesn't support IN clause

I couldn't find any documentation on using IN or NOT IN. However, I did find a ticket about adding this feature. After mucking with things, it appears Expressions doesn't support IN clause:

> var s = require('squel');
undefined
> s.select().from('user').where('id in ?', [1, 2]).toString();
'SELECT * FROM user WHERE (id in (1, 2))'
> s.select().from('user').where(s.expr().and('id in ?', [1,2])).toString();
'SELECT * FROM user WHERE (id in ?)'
> 

per field usingValuePlaceholders?

Is it possible not to quote a single only?
Setting usingValuePlaceholders on the whole query forces me to add the quotes on each string variables which doesn't make much sense.

Question: How to write SQL INSERT INTO SELECT Statement?

I'm sure I'm not the only one but I can't find any documentation regarding this.
This SQL statement creates copies/duplicates.
How do I write SQL INSERT INTO SELECT Statement in Squel?

Example:
INSERT INTO table2
SELECT * FROM table1;

or

INSERT INTO table2
(column_name(s))
SELECT column_name(s)
FROM table1;

SQL Example taken from here:
http://www.w3schools.com/sql/sql_insert_into_select.asp

Squel insert() requires .set() and .set() requires 2 arguments which got me stuck.
Can this currently be converted from SQL to Squel?

Many Thanks

Use postgres function as second argument to set

I want to construct the following query:

UPDATE users SET password = crypt('my super awesome password', gen_salt('md5'))

and it is not obvious how I have to go in order to not have the crypt function to get interpreted as a string value. I do not want to use the usingValuePlaceholders option because it is deprecated. Is there any other way?

Feature Request: Fields

A little feature request:
Make it possible to not only specify a query's field by listing every field on its own but also to specify all fields at once:

squel.select().fields(['field1', 'field2']).from('myTable');

and for aliases:

squel.select().fields(['field1', 'field2', ['field3', 'myAlias']]).from('myTable');

I'd like to do a PR but I'm not really familiar with cs.
If you like the idea of a fields directive I'll use the chance to get into coffee script. :)

toString() method changes underlying object instance

Hi all,

we run into an issue, where calling the toString() method changed the underlying object instance for parametrised queries, i.e.
squel.select().from("students") .where("a = ? AND b = ?", "test", true);
When toString() is called first the parameters get resolved fine, but on the second call the parameters are gone.

Here is a JSFiddle to demonstrate the issue.
http://jsfiddle.net/3fWeH/

If you were to replace the squel library with version 2.0.0 the string would resolve fine both times.

Tracing back over the change logs, we think that this was introduced in version 3.11 where the parsing for parametrised calls changed. We haven't looked into the library in more detail, but we just wanted flag it up in case it wasn't known already.

All the best,
srgudevelopment

EXISTS support...?

Any suggestions how you would implement a EXISTS?.

i.e.

select id, course_file, status_package from publications_course c
 where exists(select 1 from configurations_courseinstance i where i.id=:idInstance and
 ((i.start_date is null and i.end_date is null)
 or (i.end_date is null and i.start_date <= now())
 or (i.start_date is null and i.end_date >= now())
 or (now() between i.start_date and end_date))
 and i.course_id=c.id and 
 exists(select 1 from configurations_userinstance where
 instance_id=i.id and exists(select 1 from                     
 academic_academicuser where id=student_id and username=:username)));

Regards

Parameter Support in Expr

My target SQL output is:

SELECT * FROM test INNER JOIN test2 ON (a = 12);

Where but the 12 is a user parameter. I've tried the following which I assumed could work:

coffee> squel.select().from('test').join('test2', null, (squel.expr().and "a = ?", 12)).toString()
'SELECT * FROM test INNER JOIN test2 ON (a = ?)'

Is there a currently supported way of doing this?
Thanks in advance, and I'm loving the library!!

squel.coffee as one giant file is hard to manage

squel.coffee as one giant file doesn't feel like good programming practice to me.
it should be broken out into 1 file per class

The tricky part is breaking the file apart and having the build process concat the files correctly.

set() is not working as expected

Hi,

does anybody have the same issues like I with the following code from the documentation?

alert(
    squel.update()
        .table("students")
        .setFields({ age: 23, name: 'Fred' })
);
/*  UPDATE students SET age = 23, name = 'Fred' */

It was not working in my project, but even alone within an mostly empty node test file is is not working like it should:

var squel = require('squel');

      console.log(
        squel.update()
          .table("students")
          .set("age = age + 1").toParam()
      );

is outputting:

{ text: 'UPDATE students SET age = age + 1 = ?',
  values: [ undefined ] }

I've tried it first with version 3.1, now I'm at 3.4.1 and the issue is the same.

Thanks for any further help ;-)!

800a01b6 problem: property or method unsopported

if i try to launch squelk inside a windows scriptng engine (wsh in this case by Wscript or Cscript) the engine give this error:
800a01b6 property or method unsopported
in this line:
return ((function() {
in the block QueryBuilder.prototype.toString

can you explain me some solution?

Thanks

Quoting does not work as expected.

Hi there,

I was trying out the npm module and got an output I did not expect, which I think is an issue.

The following code:
var query = squel.select({ autoQuoteTableNames: true, autoQuoteFieldNames: true });
query.field('tbl.name');
query.from('students', 'tbl');
query.field("GROUP_CONCAT(DISTINCT tbl.test_score ORDER BY tbl.test_score DESC SEPARATOR ' ')");
query.toString();

Gives this:
SELECT tbl.name, GROUP_CONCAT(DISTINCT tbl.test_score ORDER BY tbl.test_score DESC SEPARATOR ' ') FROM students tbl

But it should be:
SELECT tbl.name, GROUP_CONCAT(DISTINCT tbl.test_score ORDER BY tbl.test_score DESC SEPARATOR ' ') FROM students tbl

Feature Request: Clone Method for Chains

Just a small feature request for the API. I'd like a clone method that would take an existing chain and return a functional duplicate of the working SQL command.

My use-case is like this: I have a lib that's generating a SELECT statement for single items by ID, as well as the list of all in a collection. Having to specify my fields/tables/etc is kinda cumbersome and creating a wrapper function is not very elegant either.

For example:

var select = squel.select()
    .field("id")
    .field("name")
    .from("users", "u");

var single = select.clone()
    .where("id = ?")
    .toString();

var list = select.clone()
    .limit(10)
    .offset(0)
    .toString();

This is a trivial example, but after adding joins and other conditions, this becomes a much more friendly way to approach similar queries.

Escaping single quotes

I'm probably doing something silly but when I insert content with single quotes I get an SQL error.

If I manually escape single quotes the error goes away.

.set( 'title', this._data.title.replace( /'/g, "\\'" ) )

No option for built-in functions on Insert

The following query gives two examples where I'm having trouble with automatic quotes and I want to turn it off for one specifically.

squel.insert()
    .into "tasks"
        .set "orderid", "((#{squel.select()
            .field "COUNT(*)", "count"
            .from "tasks"
            .where "ticketid = ?", ticketId}) + 1)"
        .set "createdat", "GETDATE()"

Results in: (Note the quoted as string values)

INSERT INTO tasks (orderid, createdat)
VALUES ('((SELECT COUNT(*) AS count FROM tasks WHERE (ticketid = 4198)) + 1)', 'GETDATE()')

I found #46 but the docs state that his workaround is depreciated, is there any way I can tell squel NOT to quote a particular string in a set?

Upsert

I don't see a way to add an 'On duplicate key' for an upsert in the insert documentation. Is this currently possible?

Thanks.

SQLite Comaptibility

There don't seem to be too many differences between the SQL commands for MySQL and SQLite. I'm not sure how a conduct a proper test, but I am about to try some of the functions that I need.

I think that if it works, Squel should be marked to have official support for it. Of course, a full test should be done before that.

Table aliases not working with Postgres

var squel = require("squel");

var query = squel.select({autoQuoteTableNames:false})
  .from("test01", "t01")
  .where("t01.delete_flg = '0'")
  .toString();

console.log(query); // -> SELECT * FROM test01 `t01` WHERE (t01.delete_flg = '0')

var query2 = squel.select({autoQuoteTableNames:true, nameQuoteCharacter:'"'})
  .from("test01", "t01")
  .where("t01.delete_flg = '0'")
  .toString();

console.log(query2); // -> SELECT * FROM "test01" `t01` WHERE (t01.delete_flg = '0')

Results:

SQL state: 42601 syntax error at or near “`”

"set" only when value is not undefined

Sometimes I only have some field of the table I want to update.
I have to check each if a value is undefined and conditionally add the "set" clause.
Is there a way to instruct the "set" clause to only add to final string if value is not empty?
Eventually some configuration on how to handle empty string or null

are unquoted set values possible?

hello
Is it possible not to enclose a "set" value in quotes?
I would like to use:
set("date", "FROM_UNIXTIME(" + data.timestamp + ")")
and have the value unquoted like this:
FROM_UNIXTIME(949424400)

Table names are not escaped

Just being rather picky here, but table and field names that also happen to be reserved SQL keywords are not escaped properly by squel. For example...

Wrong -> SELECT select FROM select S
Correct -> SELECT `select` FROM `select` `S`

Sorry for the contrived example, but you get the point. :)

MSSQL flavour

Hi there,
we plan to use it to santize MSSQL sql.

Issue is, that the escaping in MSSQL works a little bit different:
Single quotes must be doubled - that's all what it needs. Therefore we have for every query:

        var username = "te';DROP TABLE portalUser;--st";
squel.select({replaceSingleQuotes:true, singleQuoteReplacement: "''"})
            .from("user")
            .where("username = ?", username)
            .toString();

To get

   SELECT * FROM portalUser WHERE (username = 'te'';DROP TABLE portalUser;--st')

Wich is valid SQL in MSSQL

Best it would be to use ? but there are other lmiitations in kind of connection handling which makes this not possible for us.
Might it be worth to put the above in an MSSQL flavour?

would adding duplicateKeyUpdate option to setFields() benefit anyone?

im considering implementing this functionality and wonder if anyone else would find it useful.

I'd like feedback on my implementation approach:

.setFields(item1, {duplicateKeyUpdate: item2 })

... would simply update an existing record with the data in item2 (which could match item1).

thoughts?

insert/update usingValuePlaceholders on single field

I am trying to run this query:

sql = squel.insert({ usingValuePlaceholders: true })
    .into('flags')
    .set('time', time)
    .set('type', data.type)
    .set('comment', data.comment)
    .set('geom', 'PointFromText(\'POINT(' + data.latlng.lng + ', ' + data.latlng.lat + ')\')');

if I specify {usingValuePlaceholders: true}, data.comment will not be enclosed with quotes and if I don't specify {usingValuePlaceholders: true} my function PointFromText will be enclosed in quotes which is also not correct.

What would you suggest?

Auto-quote names not working with Postgres

The quote escaping necessary to make Squel work with Postgres is more painful then just writing pure SQL. I see you discussed auto-quote #1 (comment), but the implementation doesn't seem to work. Instead, I needed to manually quote every field and table name to avoid an error. And, I still wasn't able to get a WHERE clause to work at all.

My apologies if I'm missing something obvious, but Squel doesn't seem usable with Postgres at the current time.

var squel = require("squel")
  , config = require(__dirname + "/config/config.js")
  , pg = require('pg')
  , conString = "postgres://" + config.username + ":" + (config.password || "") + "@" + config.host + ":" + config.port + "/" + config.database

console.log (conString)

var squelQuery = squel.select({usingPlaceholderValues: true})
  .from('"Variants"')
  .field('"color"')
  .field('"size"')
  .field('"childSku"')
  .field('"Variants"."updatedAt"')
  .field('"listPriceCents"')
  .field('"salePriceCents"')
  .field('"ProductId"')
  .left_join('"Products"', null, '"Variants"."ProductId" = "Products"."id"')
  .field('"Products"."parentSku"')
  .field('"Products"."title"')
  .field('"Products"."description"')
  .field('"Products"."CategoryId"')
  .left_join('"Categories"', null, '"Products"."CategoryId" = "Categories"."id"')
  .field('"Categories"."name"')
  .field('"Categories"."description"')
  .field('"Products"."BrandId"')
  .left_join('"Brands"', null, '"Products"."BrandId" = "Brands"."id"')
  .field('"Brands"."name"')
  .field('"Brands"."description"')
  .field('"Brands"."PartnerId"')
  .left_join('"Partners"', null, '"Brands"."PartnerId" = "Brands"."PartnerId"')
  .field('"Partners"."name"')
  // .where("`Variants`.`childSku` = 'puma-1234-red-large'")
  .toString();

console.log(squelQuery)

pg.connect(conString, function(err, client) {
  console.log ("connect error:",err)
  client.query(squelQuery, function(err, result) {
    console.log(JSON.stringify(result));
    console.log ("query error:",err);
    pg.end(); //terminate the client pool, disconnecting all clients
    })
  })

Where clause substitution is not adding quotes when `usingValuePlaceholders` is set to `true`

The following code fails to enclose the where clause in quotes, when really it should do?

var s = squel.update({ usingValuePlaceholders: true })
    .table('User')
    .set('password', '?')
    .where('username = ?', 'one two');

console.log(s.toString());

Outputs:

UPDATE User SET password = ? WHERE (username = one two)

This throws an error with SQLite, but the following would work fine:

UPDATE User SET password = ? WHERE (username = 'one two')

Save query to variable

EDIT: Nevermind! I just tested it on your demo, and there its working, so i got an error in my code.

Hello!

I am trying to create a query and add statements to the query modularly.
Therefore, i would like to do the following, like seen in your first demo:

var s = squel.select();
//do some computation..
s.from("student");
//another computation
s.where("do something")
alert( s.toString() ); /* SELECT * FROM student WHERE ... */

The problem i have is, this (and also your first demo) query only creates:
"SELECT *"

Whereas chaining works!

Any tips on this??

Thanks a lot!

How do I write a sub-query in a .field()?

I'm trying to convert a query like:

SELECT 
    u.id,
    ( 
        SELECT x 
        FROM table2 
        WHERE y = u.id
    ) AS roomUsers

FROM users u

The only way I've gotten it working is by building part of the query as a string;

squel.select()

        .from('users')

        .field('u.id')
        .field(
            '('
            + squel.select()

            .field('x')

            .from('table2')

            .where('y = u.id') 
            + ' AS roomUsers )'
        )

This isn't nice at all :/

COUNT()

I couldn't find any example of doing a simple query like: select count(*) from <table_name>

Is this possible with current updated version?

Provide alias for delete()

The word delete is reserved in javascript so jslint complains when you use it.
It's be nice to have remove() or something similar as an alias to delete().

FROM function() support

Please, can you add support for selecting data from function with parameters?
Something like this would be great:

var owner = "Martin";
var project = "Work";

var query = squel.select()
    .fromFunc("get_my_tasks", owner, project);
    .field("ticket")
    .field("description", "name");

Generated SQL query:

SELECT ticket, description as name FROM get_my_tasks('Martin', 'Work');

Project should not be targeted at browsers.

The examples pages suggests how to include quel in a browser while not showing any warnings about the dangers of generating SQL client side, for use with a server side database.

While all web developers should be aware of the dangers of exposing their database so openly, the fact is that many developers are not.

The examples page and readme files should contain large obvious warning messages about the incorrect way to use this project, to discourage insecure design mistakes and educate developers.

UNION support...?

Any suggestions how you would implement a UNION? Building search terms.

i.e.

SELECT MB_NAME as term FROM sites 
UNION 
SELECT GRID_LABEL as term FROM sections 
UNION 
SELECT GRID_LABEL as term FROM townships
UNION 
SELECT SH_UWI as term FROM wells

Delete query - table joins, etc.

squel.delete() should also support table joins and a way to indicate which tables' records are deleted.

For example,

/* Delete all messages for a user */
DELETE m.* FROM `messages` M
    INNER JOIN `users` U ON (M.SenderUserID=U.UserID)
WHERE U.EmailAddress='[email protected]'

I will try to implement this, but I am terrible with Coffee Script.

Admittedly, this use case is rather rare, but it can be helpful rather than writing a SELECT followed by a DELETE.

Expression cloning

I couldn't explicitly find the answer in the documentation, but from my tests I think the expressions don't can't be cloned in the same way that queries can.

I tried the following:

var squel = require('squel');
var base = squel.select().from('table');
var expr = squel.expr().and("id='5'");

base.clone().where(expr.clone().and("city='amsterdam'")); 
// SELECT * FROM table WHERE id='5' AND city='amsterdam'
base.clone().where(expr.clone().and("country='the netherlands'")); 
// SELECT * FROM table WHERE id='5' AND city='amsterdam' AND country='the netherlands'

Is this expected behavior?

Thanks

Can't use built-in functions on UPDATE

Is there no way to use built-in functions of my database in an update?

For example, I need to set a field to the current time. I can't use something like a formatted moment.js date representing right now because the time periods are short enough that any difference between my computer's time and the database server's time creates unstable timings.

What I need is to be able to do

.update().table('tablename').set('last_check', 'NOW()') and not have the resulting SQL built:
UPDATE tablename SET last_check = 'NOW()' WHERE (id = 2)

because the NOW() function does not run; it is evaluated as a string. Is there some way to do this? If not, I think it should be possible somehow.

Is there a way to do a nested join?

I see you can join to a sub query, but is there a way to do a nested join?

For example, I'd like to create the following SQL

SELECT *
FROM
( 
   table1 t1 join table2 t2 on (t1.id = t2.id)
) join table 3 t3 on (t1.id = t3.id) 

I'm assuming that using the sub query, I would end up with something like:

SELECT *
FROM
( 
  SELECT * FROM table1 t1 join table2 t2 on (t1.id = t2.id)
) join table 3 t3 on (t1.id = t3.id) 

I'd much prefer doing it the first way if possible

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.