Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Need a way to add new converters #62

Open
Suor opened this issue Feb 19, 2015 · 5 comments
Open

Need a way to add new converters #62

Suor opened this issue Feb 19, 2015 · 5 comments
Milestone

Comments

@Suor
Copy link
Contributor

Suor commented Feb 19, 2015

I am trying to add support for JSON fields here - Suor/sql-bricks-postgres#3. But looks like I can only do it overwriting sql.convert(), e.g. messing with original namespace.

Any ideas?

@prust
Copy link
Collaborator

prust commented Feb 19, 2015

@Suor: Yeah, sql.convert()/sql.conversions is not very extensible the way it is:

  sql.conversions = {
    'String': function(str) { return "'" + str.replace(/'/g, "''") + "'"; },
    'Null': function() { return 'null'; },
    'Undefined': function() { return 'null'; },
    'Number': function(num) { return num.toString(); },
    'Boolean': function(bool) { return bool.toString().toUpperCase(); },
    'Date': function(dt) { return "TIMESTAMP WITH TIME ZONE '" + dt.toISOString().replace('T', ' ').replace('Z', '+00:00') + "'"; },
    'Array': function(arr) { return '{' + arr.map(sql.convert).join(', ') + '}'; }
  };

I think all it would take to make it more extensible would be this (not sure the .bind(_) is necessary):

  sql.conversions = [
    [_.isString.bind(_), function(str) { return "'" + str.replace(/'/g, "''") + "'"; }],
    [_.isNull.bind(_), function() { return 'null'; }],
    [_.isUndefined.bind(_), function() { return 'null'; }],
    [_.isNumber.bind(_), function(num) { return num.toString(); }],
    [_.isBoolean.bind(_), function(bool) { return bool.toString().toUpperCase(); }],
    [_.isDate.bind(_), function(dt) { return "TIMESTAMP WITH TIME ZONE '" + dt.toISOString().replace('T', ' ').replace('Z', '+00:00') + "'"; }],
    [_.isArray.bind(_), function(arr) { return '{' + arr.map(sql.convert).join(', ') + '}'; }]
  ];

Then to extend it you could just do:

sql.conversions.push([
  function(val) { return _.isObject(val) && !_.isArray(val) && !_.isArguments(val); },
  function(val) { return sql.convert(JSON.stringify(val)); }
]);

I'll go ahead & make those changes...

@Suor
Copy link
Contributor Author

Suor commented Feb 19, 2015 via email

@prust
Copy link
Collaborator

prust commented Feb 19, 2015

@Suor: Oh, I see. The only way I can think to support this is by making sql an instance of a class:

// inside sql-bricks.js:
module.exports = new SqlBricks();

// calling code would remain unchanged
var sql = require('sql-bricks');

sql._extension() would then return an instance of the subclass:

  sql._extension = function () {
    var SubClass = subclass(SqlBricks);
    var ext = new SubClass();

    // ... other logic already in sql._extension()

    return ext;
  }

Then internally sql-bricks would call this.convert() instead of sql.convert() and if you override convert() in your subclass, the override will be called instead.

What do you think?

@Suor
Copy link
Contributor Author

Suor commented Feb 19, 2015 via email

@prust
Copy link
Collaborator

prust commented Aug 26, 2015

For the record: Suor was able to hack around this in Suor/sql-bricks-postgres@c5a6975c98df8044d2, but really we should fix this so that he doesn't have to.

@prust prust mentioned this issue Oct 31, 2016
6 tasks
@prust prust added this to the 3.0 milestone Aug 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants