Skip to content

Commit

Permalink
finalizing the utils namespace.
Browse files Browse the repository at this point in the history
  • Loading branch information
vitaly-t committed Jun 2, 2016
1 parent c09b7ec commit 4933203
Show file tree
Hide file tree
Showing 11 changed files with 96 additions and 32 deletions.
6 changes: 2 additions & 4 deletions lib/events.js
Expand Up @@ -46,7 +46,7 @@ var $events = {
}
}
},

/**
* @event disconnect
* @description
Expand Down Expand Up @@ -224,12 +224,10 @@ var $events = {
* }
* };
*
* var humps = require('humps');
*
* function camelizeColumns(data) {
* var template = data[0];
* for (var prop in template) {
* var camel = humps.camelize(prop);
* var camel = pgp.utils.camelize(prop);
* if (!(camel in template)) {
* for (var i = 0; i < data.length; i++) {
* var d = data[i];
Expand Down
2 changes: 2 additions & 0 deletions lib/helpers/README.md
@@ -1,5 +1,7 @@
### `helpers` namespace

**Added in v.4.1.0**

This folder contains everything that's available via the [helpers] namespace, after initializing the library:

```js
Expand Down
3 changes: 2 additions & 1 deletion lib/helpers/index.js
Expand Up @@ -13,7 +13,8 @@ var $npm = {
/**
* @namespace helpers
* @description
*
* **Added in v.4.1.0**
*
* Namespace for query-formatting generators, available as `pgp.helpers`, after initializing the library.
*
* It is a set of types and methods for generating queries in a fast, flexible and reliable way.
Expand Down
2 changes: 2 additions & 0 deletions lib/utils/README.md
@@ -1,5 +1,7 @@
### `utils` namespace

**Added in v.4.3.6**

This folder contains everything that's available via the [utils] namespace, before and after initialization:

```js
Expand Down
13 changes: 8 additions & 5 deletions lib/utils/index.js
Expand Up @@ -9,19 +9,22 @@ var prv = require('./private');
* @description
* **Added in v.4.3.6**
*
* Namespace for general-purpose functions, available as `pgp.utils`, before and after initializing the library.
* Namespace for general-purpose static functions, available as `pgp.utils`, before and after initializing the library.
*
* Its main purpose however is to simplify developing projects with large number of SQL files
* (see [Automatic SQL Trees](https://github.com/vitaly-t/pg-promise/issues/153)).
*
* @property {function} camelize
* {@link utils.camelize camelize} static method.
* {@link utils.camelize camelize} - camelizes a text string.
*
* @property {function} camelizeVar
* {@link utils.camelizeVar camelizeVar} static method.
* {@link utils.camelizeVar camelizeVar} - camelizes a text string as a variable.
*
* @property {function} enumSql
* {@link utils.enumSql enumSql} static method.
* {@link utils.enumSql enumSql} - enumerates SQL files in a directory.
*
* @property {function} objectToCode
* {@link utils.objectToCode objectToCode} static method.
* {@link utils.objectToCode objectToCode} - generates code from an object.
*
*/
module.exports = {
Expand Down
92 changes: 73 additions & 19 deletions lib/utils/public.js
Expand Up @@ -11,10 +11,10 @@ var EOL = require('os').EOL;
* Camelizes a text string.
*
* Case-changing characters include:
* - `-` - hyphen
* - `_` - underscore
* - `.` - period
* - ` ` - space
* - hyphen
* - underscore
* - period
* - space
*
* @param {string} text
* Input text string.
Expand Down Expand Up @@ -47,7 +47,7 @@ function camelize(text) {
*
*/
function camelizeVar(text) {
text = text.replace(/[^a-zA-Z0-9\$_\-\s]/g, '').replace(/^[0-9_\-\s]+/, '');
text = text.replace(/[^a-zA-Z0-9\$_\-\s\.]/g, '').replace(/^[0-9_\-\s\.]+/, '');
return camelize(text);
}

Expand Down Expand Up @@ -105,7 +105,10 @@ function _enumSql(dir, options, cb, namePath) {
/**
* @method utils.enumSql
* @description
* Synchronously enumerates all SQL files (within a given directory) into a camelized SQL tree, to allow named references from JavaScript.
* Synchronously enumerates all SQL files (for a given directory) into an SQL tree.
*
* All property names within the tree are camelized via {@link utils.camelizeVar camelizeVar},
* so they can be used in the code directly - as open property names.
*
* @param {string} dir
* Directory where SQL files are located.
Expand All @@ -119,7 +122,7 @@ function _enumSql(dir, options, cb, namePath) {
* Sub-directories without SQL files will be skipped from the result.
*
* @param {boolean} [options.ignoreErrors=false]
* Ignore the following type of errors:
* Ignore the following types of errors:
* - access errors, when there is no read access to a file or folder
* - empty or duplicate camelized property names
*
Expand All @@ -134,24 +137,26 @@ function _enumSql(dir, options, cb, namePath) {
* If the function returns anything other than `undefined`, it overrides the corresponding property value in the tree.
*
* @returns {object}
* Camelized SQL tree object.
* Camelized SQL tree object, with each value being an SQL file path.
*
* @example
*
* var pgp = require('pg-promise');
* // simple SQL tree generation for further processing:
* var tree = pgp.utils.enumSql('../sql', {recursive: true});
*
* @example
*
* // generating an SQL tree for dynamic access:
* // generating an SQL tree for dynamic-names queries:
* var sql = pgp.utils.enumSql('../sql', {recursive: true}, file=> {
* return new pgp.QueryFile(file, {minify: true});
* });
*
* @example
*
* var pgp = require('pg-promise');
* var path = require('path');
*
* // replacing each relative path with a full one:
* var sql = pgp.utils.enumSql('../sql', {recursive: true}, file=> {
* // replacing each relative path in the tree with a full one:
* var tree = pgp.utils.enumSql('../sql', {recursive: true}, file=> {
* return path.join(__dirname, file);
* });
*
Expand All @@ -171,41 +176,90 @@ function enumSql(dir, options, cb) {
*
* @method utils.objectToCode
* @description
* Translates an object tree into a JSON code string.
* Translates an object tree into a well-formatted JSON code string.
*
* @param {object} obj
* Source tree object.
*
* @param {function} [cb]
* A callback function to override property values.
* A callback function to override property values for the code.
*
* It takes three arguments:
*
* - `value` - property value
* - `name` - property name
* - `obj` - current object (which contains the property)
*
* The returned value is used as is for the property value in the generated code.
*
* @returns {string}
*
* @example
*
* // Generating a JavaScript module with complete SQL tree
* // Generating code for a simple object
*
* var tree = {one: 1, two: {item: 'abc'}};
*
* var code = pgp.utils.objectToCode(tree);
*
* console.log(code);
* //=>
* // {
* // one: 1,
* // two: {
* // item: "abc"
* // }
* // }
*
* @example
*
* // Generating a Node.js module with an SQL tree
*
* var fs = require('fs');
* var EOL = require('os').EOL;
* var utils = require('pg-promise').utils;
*
* // generating an SQL tree from the folder:
* var tree = utils.enumSql('./sql', {recursive: true});
* var tree = pgp.utils.enumSql('./sql', {recursive: true});
*
* // generating the module's code:
* var code = "var load = require('./loadSql');" + EOL + "module.exports = " +
* utils.objectToCode(tree, function (value) {
* pgp.utils.objectToCode(tree, function (value) {
* return 'load(' + JSON.stringify(value) + ')';
* });
*
* // saving the module:
* fs.writeFileSync('sql.js', code);
* // see the output example below:
*
* @example
*
* // generated code example (file sql.js)
*
* var load = require('./loadSql');
*
* module.exports = {
* events: {
* add: load("../sql/events/add.sql"),
* delete: load("../sql/events/delete.sql"),
* find: load("../sql/events/find.sql"),
* update: load("../sql/events/update.sql")
* },
* products: {
* add: load("../sql/products/add.sql"),
* delete: load("../sql/products/delete.sql"),
* find: load("../sql/products/find.sql"),
* update: load("../sql/products/update.sql")
* },
* users: {
* add: load("../sql/users/add.sql"),
* delete: load("../sql/users/delete.sql"),
* find: load("../sql/users/find.sql"),
* update: load("../sql/users/update.sql")
* },
* create: load("../sql/create.sql"),
* init: load("../sql/init.sql"),
* drop: load("../sql/drop.sql")
*};
*
* @example
*
Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "pg-promise",
"version": "4.3.6",
"version": "4.3.7",
"description": "PostgreSQL via promises",
"main": "lib/index.js",
"scripts": {
Expand Down
Empty file added test/sql/sub/one.two.three.sql
Empty file.
4 changes: 4 additions & 0 deletions test/utilsSpec.js
Expand Up @@ -23,6 +23,9 @@ describe("camelizeVar", function () {
it("must remove leading digits and white spaces", function () {
expect(utils.camelizeVar(' 123 name 456')).toBe('name456');
});
it("must handle all special symbols", function () {
expect(utils.camelizeVar('-123_ 456.78.one.two . three.8')).toBe('oneTwoThree8');
});
});

describe("enumSql", function () {
Expand Down Expand Up @@ -57,6 +60,7 @@ describe("enumSql", function () {
expect(sql.simple).toBe('simple');
expect(sql.sub.one).toContain('sub.one');
expect(sql.sub.two).toContain('sub.two');
expect(sql.sub.oneTwoThree).toContain('sub.oneTwoThree');
});

it("must be able to ignore duplicate folders", function () {
Expand Down
2 changes: 1 addition & 1 deletion typescript/README.MD
@@ -1,6 +1,6 @@
### TypeScript for pg-promise

Complete TypeScript ambient declarations for [pg-promise] version 4.3.6 or later.
Complete TypeScript ambient declarations for [pg-promise] version 4.3.7 or later.

| File | Description |
|------------------|----------------------------------|
Expand Down
2 changes: 1 addition & 1 deletion typescript/pg-promise.d.ts
@@ -1,5 +1,5 @@
////////////////////////////////////////
// Requires pg-promise v4.3.6 or later.
// Requires pg-promise v4.3.7 or later.
////////////////////////////////////////

/// <reference path='./pg-subset' />
Expand Down

0 comments on commit 4933203

Please sign in to comment.