Skip to content

Commit

Permalink
merged branch 0.7.0
Browse files Browse the repository at this point in the history
  • Loading branch information
grob committed Mar 2, 2016
2 parents 91137fc + 1eda854 commit 9fe15da
Show file tree
Hide file tree
Showing 147 changed files with 9,792 additions and 25,947 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
.idea/
jars/postgresql-9.4-1206-jdbc42.jar
*.iml
21 changes: 21 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
## v0.7.0

### Breaking changes

- Removed `ConnectionPool` constructor, use `Store.initConnectionPool()` instead
- Removed `Storable.prototype._id`, use `Storable.prototype.id` from now on

### Possibly breaking changes

- Restructured the whole package, most notably the "lib/sqlstore" directory is gone. If your application directly requires modules of ringo-sqlstore you'll need to adapt the module paths.

### Bugfixes and Improvements

- Switched to [HikariCP](https://github.com/brettwooldridge/HikariCP) as connection pool exclusively. All configuration options accepted by HikariCP can be specified in the configuration hash passed as argument to `Store.initConnectionPool()`.
- Added support for auto incremented IDs. From now on ID mappings can define either `autoIncrement: true` or `sequence: <name>`. The default is auto increment.
- Added basic support for `json` and `jsonb` PostgreSQL data types (contributed by [@botic](https://github.com/botic/)). Note that currently the sqlstore query language doesn't support JSON queries.
- Primitive or object mapping definitions can now contain a `unique` flag. [#33](https://github.com/grob/ringo-sqlstore/issues/33)
- `Store.prototype.syncTables()` creates a sequence only if it doesn't already exist. [#35](https://github.com/grob/ringo-sqlstore/issues/35)
- Fixed whitespace matching the empty string in query grammar [#32](https://github.com/grob/ringo-sqlstore/issues/32)
- Data types are now database specific, fixing [19](https://github.com/grob/ringo-sqlstore/issues/19)
- Added special SQL generator for Oracle, fixing [#27](https://github.com/grob/ringo-sqlstore/issues/27)
7 changes: 3 additions & 4 deletions benchmarks/connectionpool.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ var term = require("ringo/term");
var assert = require("assert");
var {Worker} = require("ringo/worker");
var {Semaphore} = require("ringo/concurrent");

var {ConnectionPool} = require("../lib/sqlstore/connection/pool");
var {init} = require("../lib/connectionpool");

var connectionPool = null;

exports.setUp = function(dbProps) {
connectionPool = new ConnectionPool(dbProps);
connectionPool = init(dbProps);
};

exports.tearDown = function() {
Expand All @@ -19,7 +18,7 @@ exports.start = function(cnt, maxWorkers) {
cnt || (cnt = 20000);
maxWorkers = maxWorkers || (maxWorkers = 100);

term.writeln("Using", connectionPool.getDriverClass());
term.writeln("Using", connectionPool.getDriverClassName());
var semaphore = new Semaphore();
var workers = new Array(maxWorkers);
var workerMillis = new Array(maxWorkers);
Expand Down
18 changes: 18 additions & 0 deletions benchmarks/key.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
var term = require("ringo/term");

var Key = require("../lib/key");

var setUp = exports.setUp = function() {};

exports.tearDown = function() {};

var start = exports.start = function(cnt) {
cnt || (cnt = 1000000);
var start = Date.now();
var result = [];
for (let i=0; i<cnt; i+=1) {
result.push(new Key("Author"));
}
var millis = Date.now() - start;
term.writeln(term.GREEN, millis, "ms for", cnt, "instantiations,", millis / cnt + "ms/instantiation", term.RESET);
}
18 changes: 18 additions & 0 deletions benchmarks/parse.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
var term = require("ringo/term");

var Parser = require("../lib/query/parser");
var SQL = "select Author.name as author, count(Book.id) as cnt from Author, Book where Book.author = Author.id group by Author.name order by Author.name";

exports.setUp = function() {};

exports.tearDown = function() {};

exports.start = function(cnt) {
cnt || (cnt = 10000);
var start = Date.now();
for (let i=0; i<cnt; i+=1) {
Parser.parse(SQL);
}
var millis = Date.now() - start;
term.writeln(term.GREEN, millis, "ms for", cnt, "parsings,", millis / cnt + "ms/parse", term.RESET);
};
25 changes: 10 additions & 15 deletions benchmarks/query.concurrent.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ var assert = require("assert");
var {Worker} = require("ringo/worker");
var {Semaphore} = require("ringo/concurrent");

var {Store, Cache, ConnectionPool} = require("../lib/sqlstore/main");
var sqlUtils = require("../lib/sqlstore/util");
var {Store, Cache} = require("../lib/main");
var utils = require("../test/utils");

var store = null;
var connectionPool = null;
Expand All @@ -31,7 +31,7 @@ exports.setUp = function(dbProps) {
connectionPool = Store.initConnectionPool(dbProps);
store = new Store(connectionPool);
term.writeln("------------------------------");
term.writeln("Using", store.connectionPool.getDriverClass());
term.writeln("Using", store.connectionPool.getDriverClassName());
Author = store.defineEntity("Author", MAPPING_AUTHOR);
store.syncTables();
store.beginTransaction();
Expand All @@ -44,16 +44,7 @@ exports.setUp = function(dbProps) {
};

exports.tearDown = function() {
var conn = store.getConnection();
[Author].forEach(function(ctor) {
var schemaName = ctor.mapping.schemaName || store.dialect.getDefaultSchema(conn);
if (sqlUtils.tableExists(conn, ctor.mapping.tableName, schemaName)) {
sqlUtils.dropTable(conn, store.dialect, ctor.mapping.tableName, schemaName);
if (ctor.mapping.id.hasSequence() && store.dialect.hasSequenceSupport()) {
sqlUtils.dropSequence(conn, store.dialect, ctor.mapping.id.sequence, schemaName);
}
}
});
utils.drop(store, Author);
store.close();
};

Expand All @@ -80,24 +71,27 @@ exports.start = function(cnt, maxWorkers) {
}
term.writeln("Setup", maxWorkers, "workers");

var queryCache = new Cache(10000);
var queryCache = new Cache(10);
var start = Date.now();
workers.forEach(function(worker, idx) {
worker.postMessage({
"workerNr": idx,
"mapping": MAPPING_AUTHOR,
"maxAuthors": maxAuthors,
"connectionPool": connectionPool,
"queryCache": queryCache,
"cnt": cnt
}, true);
});
semaphore.wait(maxWorkers);
var totalMillis = Date.now() - start;
term.writeln(maxWorkers, "workers finished");
var workerMillisAvg = workerMillis.reduce(function(prev, current) {
return prev + current;
}, 0) / maxWorkers;
var millisPerQuery = workerMillisAvg / cnt;
var queriesPerSec = (1000 / millisPerQuery).toFixed(2);
term.writeln(term.GREEN, maxWorkers, "workers,", cnt, "queries/worker,",
term.writeln(term.GREEN, totalMillis + "ms, ", maxWorkers, "workers,", cnt, "queries/worker,",
millisPerQuery.toFixed(2) + "ms/query,", queriesPerSec, "queries/sec", term.RESET);
//term.writeln("----------- AVG:", workerMillisAvg.toFixed(2));
/*
Expand All @@ -107,4 +101,5 @@ exports.start = function(cnt, maxWorkers) {
}, 0) / arr.length);
});
*/
quit();
};
23 changes: 4 additions & 19 deletions benchmarks/query.concurrent.worker.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,24 @@
var term = require("ringo/term");
var assert = require("assert");
var {Store} = require("../lib/sqlstore/store");
var {Cache} = require("../lib/sqlstore/cache");
var Store = require("../lib/store");

var store = null;
var Author = null;

var MAPPING_AUTHOR = {
// "schema": "TEST",
"table": "author",
"id": {
"column": "author_id",
"sequence": "author_id"
},
"properties": {
"name": {
"type": "string",
"column": "author_name",
"nullable": false
}
}
};

function onmessage(event) {
var start = Date.now();
store = new Store(event.data.connectionPool);
store.setQueryCache(event.data.queryCache);
Author = store.defineEntity("Author", MAPPING_AUTHOR);
store.setEntityCache(event.data.entityCache || null);
Author = store.defineEntity("Author", event.data.mapping);
var msPerQuery = [];
for (let i=0; i<event.data.cnt; i+=1) {
let s = Date.now();
let id = ((Math.random() * event.data.maxAuthors) | 0) + 1;
let author = store.query("select Author.* from Author where Author.id = :id", {
"id": id
})[0];
//let author = store.sqlQuery("select * from \"author\" where \"author_id\" = ?", [id])[0];
msPerQuery[i] = Date.now() - s;
}
event.source.postMessage({
Expand Down
26 changes: 9 additions & 17 deletions benchmarks/query.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
var term = require("ringo/term");
var assert = require("assert");

var {Store, ConnectionPool, Cache} = require("../lib/sqlstore/main");
var sqlUtils = require("../lib/sqlstore/util");
var {Store, Cache} = require("../lib/main");
var utils = require("../test/utils");

var store = null;
var Author = null;
var maxAuthors = 10000;
var maxAuthors = 1000;

var MAPPING_AUTHOR = {
// "schema": "TEST",
Expand All @@ -25,10 +25,11 @@ var MAPPING_AUTHOR = {
};

exports.setUp = function(dbProps) {
store = new Store(new ConnectionPool(dbProps));
store = new Store(Store.initConnectionPool(dbProps));
term.writeln("------------------------------");
term.writeln("Using", store.connectionPool.getDriverClass());
term.writeln("Using", store.connectionPool.getDriverClassName());
store.setQueryCache(new Cache(10000));
//store.setEntityCache(new Cache(10000));
Author = store.defineEntity("Author", MAPPING_AUTHOR);
store.syncTables();
store.beginTransaction();
Expand All @@ -41,16 +42,7 @@ exports.setUp = function(dbProps) {
};

exports.tearDown = function() {
var conn = store.getConnection();
[Author].forEach(function(ctor) {
var schemaName = ctor.mapping.schemaName || store.dialect.getDefaultSchema(conn);
if (sqlUtils.tableExists(conn, ctor.mapping.tableName, schemaName)) {
sqlUtils.dropTable(conn, store.dialect, ctor.mapping.tableName, schemaName);
if (ctor.mapping.id.hasSequence() && store.dialect.hasSequenceSupport()) {
sqlUtils.dropSequence(conn, store.dialect, ctor.mapping.id.sequence, schemaName);
}
}
});
utils.drop(store, Author);
store.close();
};

Expand All @@ -59,11 +51,11 @@ exports.start = function(cnt) {
var start = Date.now();
for (let i=0; i<cnt; i+=1) {
let id = ((Math.random() * maxAuthors) | 0) + 1;
let author = store.query("select Author.* from Author where Author.id = :id", {
let author = store.query("select * from Author where id = :id", {
"id": id
})[0];
assert.strictEqual(author.id, id);
}
var millis = Date.now() - start;
term.writeln(term.GREEN, cnt, "queries,", millis / cnt + "ms/query", term.RESET);
term.writeln(term.GREEN, millis, "ms for", cnt, "queries,", millis / cnt + "ms/query", term.RESET);
};
12 changes: 7 additions & 5 deletions benchmarks/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ var term = require("ringo/term");
var {Parser} = require("ringo/args");
var {Profiler} = require("ringo/profiler");
var {getOptimizationLevel} = require("ringo/engine");
var logging = require("ringo/logging");
logging.setConfig(getResource("../test/log4j.properties"));

var config = require("../test/config");
var database = "h2";
Expand All @@ -29,12 +31,12 @@ var run = function() {
profiler.attach();
}
benchmark.start.apply(null, arguments);
if (profiler !== null) {
console.log("\n" + profiler.formatResult(30))
}
} finally {
benchmark.tearDown(dbProps);
}
if (profiler !== null) {
console.log("\n" + profiler.formatResult(30))
}
};

if (require.main == module.id) {
Expand All @@ -46,8 +48,8 @@ if (require.main == module.id) {
"' is not defined in config.js", term.RESET);
system.exit(-1);
}
console.dir(dbProps);
var path = args.shift();
var file = null;
if (!path) {
term.writeln(term.RED, "Missing benchmark module argument", term.RESET);
printUsage();
Expand All @@ -61,4 +63,4 @@ if (require.main == module.id) {
}
run.apply(null, args);
system.exit(1);
};
}
76 changes: 76 additions & 0 deletions benchmarks/sqlgenerator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
var term = require("ringo/term");

var Store = require("../lib/store");
var utils = require("../test/utils");
var Parser = require("../lib/query/parser");
var SqlGenerator = require("../lib/query/sqlgenerator");
var SQL = "select Author.name as author, count(Book.id) as cnt from Author, Book where Book.author = Author.id group by Author.name order by Author.name";
var store = null;
var Author = null;
var Book = null;
var ast = null;

var MAPPING_AUTHOR = {
"table": "author",
"id": {
"column": "author_id",
"sequence": "author_id"
},
"properties": {
"name": {
"type": "string",
"column": "author_name",
"nullable": false
},
"books": {
"type": "collection",
"query": "from Book where author = :id"
}
}
};

var MAPPING_BOOK = {
"table": "book",
"id": {
"column": "book_id",
"sequence": "book_id"
},
"properties": {
"title": {
"type": "string",
"column": "book_title",
"nullable": false
},
"author": {
"type": "object",
"column": "book_f_author",
"entity": "Author",
"nullable": false
}
}
};

exports.setUp = function(dbProps) {
store = new Store(Store.initConnectionPool(dbProps));
term.writeln("------------------------------");
term.writeln("Using", store.connectionPool.getDriverClassName());
Author = store.defineEntity("Author", MAPPING_AUTHOR);
Book = store.defineEntity("Book", MAPPING_BOOK);
store.syncTables();
ast = Parser.parse(SQL);
};

exports.tearDown = function() {
utils.drop(store, Author, Book);
store.close();
};

exports.start = function(cnt) {
cnt || (cnt = 100000);
var start = Date.now();
for (let i=0; i<cnt; i+=1) {
SqlGenerator.generate(store, ast);
}
var millis = Date.now() - start;
term.writeln(term.GREEN, millis, "ms for", cnt, "selectors,", millis / cnt + "ms/selector", term.RESET);
};
Loading

0 comments on commit 9fe15da

Please sign in to comment.