New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

sworm

Package Overview
Dependencies
Maintainers
1
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

sworm - npm Package Compare versions

Comparing version 2.5.1 to 2.6.0

docker-compose.yml

14

index.js

@@ -8,4 +8,5 @@ var crypto = require("crypto");

var sqliteDriver = require("./sqliteDriver");
var debugQuery = require("debug")("sworm");
var debug = require("debug")("sworm");
var debugResults = require("debug")("sworm:results");
var redactConfig = require('./redactConfig');

@@ -298,3 +299,3 @@ var rowBase = function() {

foreignKeyFor: foreignKeyFor,
compoundKey: id instanceof Array
compoundKey: id == false || id instanceof Array
};

@@ -356,3 +357,3 @@

logError: function(query, params, error) {
debugQuery(query, params, error);
debug(query, params, error);
},

@@ -365,5 +366,5 @@

if (params) {
debugQuery(query, params);
debug(query, params);
} else {
debugQuery(query);
debug(query);
}

@@ -409,3 +410,6 @@

this.driver = driver();
debug('connecting to', redactConfig(_config));
this.connection = this.driver.connect(_config).then(function () {
debug('connected to', redactConfig(_config));
function finishRunningBeginSession() {

@@ -412,0 +416,0 @@ self.runningBeginSession = false;

{
"name": "sworm",
"version": "2.5.1",
"version": "2.6.0",
"description": "a lightweight write-only ORM for MSSQL, MySQL, PostgreSQL, Oracle, Sqlite 3",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -263,3 +263,3 @@ # SWORM [![npm version](https://img.shields.io/npm/v/sworm.svg)](https://www.npmjs.com/package/sworm) [![npm](https://img.shields.io/npm/dm/sworm.svg)](https://www.npmjs.com/package/sworm) [![Build Status](https://travis-ci.org/featurist/sworm.svg?branch=master)](https://travis-ci.org/featurist/sworm)

* `table` (`undefined`) the name of the table to save entities to
* `id` (`'id'`) the name of the identity column. This can be an array of id columns for compound keys.
* `id` (`'id'`) the name of the identity column. This can be an array of id columns for compound keys, or `false` if there is no id column.
* `foreignKeyFor` a function that returns a foreign key field name for a member (see [Relationships](#relationships)), defaults to:

@@ -563,1 +563,14 @@

# Development
## Tests
The only thing slightly awkward about this project are the test environments for each database. I've tried to make this as easy as possible however:
* sqlite3 works out of the box on most if not all platforms
* mysql, postgres and oracle instances can be found in the `docker-compose.yml` file. Install docker, make it run somehow, then run `docker-compose up -d`. This will download and start each of the databases necessary to run the tests. The tests look for the `$DOCKER_HOST` environment variable to see where the docker host is, if it's in a VM or somewhere else, otherwise the databases are expected to be on localhost, running on their default ports.
* mssql is less friendly, and all I ask is that it's running on a machine called `windows` (hack your `/etc/hosts` file if necessary), with a fresh database called `sworm`, with user `user` and password `password`.
Each database can be tested individually by running `mocha test/{mssql,mysql,postgres,oracle,sqlite}Spec.js`. All of them with simply `npm test`.
Nevertheless, this project is almost entirely covered with tests and I expect any pull request to have tests that demonstrate any new feature or bugfix.

@@ -0,9 +1,4 @@

var sworm = require("..");
var chai = require("chai");
var expect = chai.expect;
var chaiAsPromised = require("chai-as-promised");
chai.use(chaiAsPromised);
var _ = require("underscore");
var fs = require("fs-promise");
var sworm = require("..");
var databases = require('./databases');

@@ -44,931 +39,1 @@ describe("sworm", function() {

});
if (process.env.TRAVIS) {
describeDatabase("postgres", {
driver: "pg",
url: "postgres://postgres@localhost/sworm"
});
describeDatabase("mysql", {
driver: "mysql",
config: { user: "travis", password: "", database: "sworm" }
});
describeDatabase("sqlite", {
driver: "sqlite",
config: { filename: __dirname + "/test.db" }
});
} else {
describeDatabase("mssql", {
driver: "mssql",
config: { user: "user", password: "password", server: "windows", database: "mssqlOrm" }
});
describeDatabase("oracle", {
driver: "oracle",
config: { user: "system", password: "oracle", connectString: "192.168.99.100/XE" }
});
describeDatabase("postgres", {
driver: "pg",
url: "postgres://localhost/sworm"
});
describeDatabase("mysql", {
driver: "mysql",
config: { user: "user", password: "password", database: "sworm" }
});
describeDatabase("sqlite", {
driver: "sqlite",
config: { filename: __dirname + "/test.db" }
});
}
function describeDatabase(name, config) {
var helpers = databases[name];
describe(name, function() {
describe("missing modules", function() {
var moduleName = __dirname + "/../node_modules/" + helpers.driverModuleName;
beforeEach(function() {
return fs.rename(moduleName, moduleName + ".missing");
});
afterEach(function() {
return fs.rename(moduleName + ".missing", moduleName);
});
it("throws an exception if the driver module is not present", function() {
return expect(function() {
sworm.db(config).connect();
}).to.throw("npm install " + helpers.driverModuleName);
});
});
context("when connected", function() {
var db;
var tables = [];
var person;
var address;
var personAddress;
var statements;
before(function() {
var schema = sworm.db(config);
return helpers.createTables(schema, tables);
});
function clearTables() {
return Promise.all(tables.map(function (table) {
return db.query('delete from ' + table);
}));
}
beforeEach(function() {
db = sworm.db(config);
statements = [];
db.log = function(sql) {
var originalLog = this.log;
this.log = undefined;
var match = /^(insert|update|delete|select)/.exec(sql);
statements.push(match[1]);
this.logResults.apply(this, arguments);
this.log = originalLog;
};
return clearTables().then(function() {
statements = [];
person = db.model({
table: "people"
});
address = db.model({
table: "addresses",
addPerson: function(person) {
this.people = this.people || [];
person.address = this;
this.people.push(person);
}
});
personAddress = db.model({
table: "people_addresses",
id: [ "address_id", "person_id" ]
});
});
});
afterEach(function() {
return db.close();
});
it("can insert", function() {
var p = person({
name: "bob"
});
return p.save().then(function() {
expect(p.id).to.exist;
return db.query("select * from people").then(function(people) {
return expect(helpers.clean(people)).to.eql([{
id: p.id,
name: "bob",
address_id: null
}]);
});
});
});
it("can insert emtpy rows", function() {
var personWeirdId = db.model({
table: "people_weird_id",
id: "weird_id"
});
var p = personWeirdId({});
return p.save().then(function() {
expect(p.weird_id).to.exist;
return db.query("select * from people_weird_id").then(function(people) {
return expect(helpers.clean(people)).to.eql([{
weird_id: p.weird_id,
name: null,
address_weird_id: null
}]);
});
});
});
describe("concurrency", function() {
it("can insert multiple rows, maintaining correct IDs", function() {
return Promise.all(_.range(1, 101).map(function (n) {
var p = person({ name: 'Person ' + n });
return p.save().then(function () {
return p;
});
})).then(function (people) {
return Promise.all(people.map(function (originalPerson) {
return db.query('select name from people where id = @id', {id: originalPerson.id}).then(function (loadedPerson) {
expect(originalPerson.name).to.equal(loadedPerson[0].name);
});
}));
});
});
});
describe("strings", function() {
it("can insert with escapes", function() {
var p = person({
name: "bob's name is 'matilda'"
});
return p.save().then(function() {
expect(p.id).to.exist;
return db.query("select * from people").then(function(people) {
expect(helpers.clean(people)).to.eql([{
id: p.id,
name: "bob's name is 'matilda'",
address_id: null
}]);
});
});
});
});
describe("only saving when modified", function() {
var bob;
beforeEach(function() {
bob = person({
name: "bob"
});
});
it("doesn't save unmodified entity again after insert", function() {
return bob.save().then(function() {
expect(statements).to.eql([ "insert" ]);
return bob.save().then(function() {
expect(statements).to.eql([ "insert" ]);
});
});
});
it("doesn't save unmodified entity again after update", function() {
return bob.save().then(function() {
expect(statements).to.eql([ "insert" ]);
bob.name = "jane";
return bob.save().then(function() {
expect(statements).to.eql([ "insert", "update" ]);
return bob.save().then(function() {
expect(statements).to.eql([ "insert", "update" ]);
});
});
});
});
it("can force an update", function() {
return bob.save().then(function() {
expect(statements).to.eql([ "insert" ]);
bob.name = "jane";
return bob.save().then(function() {
expect(statements).to.eql([ "insert", "update" ]);
return bob.save({force: true}).then(function() {
expect(statements).to.eql([ "insert", "update", "update" ]);
});
});
});
});
it("doesn't update after entity taken from model query", function() {
return bob.save().then(function() {
expect(statements).to.eql([ "insert" ]);
return person.query("select * from people").then(function(results) {
var savedBob = results[0];
return savedBob.save().then(function() {
expect(statements).to.eql([ "insert", "select" ]);
savedBob.name = "jane";
return savedBob.save().then(function() {
expect(statements).to.eql([ "insert", "select", "update" ]);
});
});
});
});
});
});
it("can save and update", function() {
var p = person({ name: "bob" });
return p.save().then(function() {
p.name = "jane";
return p.save().then(function() {
return db.query("select * from people").then(function(people) {
expect(helpers.clean(people)).to.eql([{
id: p.id,
name: "jane",
address_id: null
}]);
});
});
});
});
describe("custom id columns", function() {
it("can insert with weird_id", function() {
var personWeirdId = db.model({
table: "people_weird_id",
id: "weird_id"
});
var p = personWeirdId({
name: "bob"
});
return p.save().then(function() {
expect(p.weird_id).to.exist;
return db.query("select * from people_weird_id").then(function(people) {
expect(helpers.clean(people)).to.eql([{
weird_id: p.weird_id,
name: "bob",
address_weird_id: null
}]);
});
});
});
});
describe("explicitly setting id", function() {
it("can insert with id", function() {
var personExplicitId = db.model({
table: "people_explicit_id"
});
var p = personExplicitId({
id: 1,
name: "bob"
});
return p.save().then(function() {
return db.query("select * from people_explicit_id").then(function(people) {
expect(helpers.clean(people)).to.eql([{
id: 1,
name: "bob"
}]);
});
});
});
});
describe("saved and modified", function() {
it("inserts when created for the first time", function() {
return person({
name: "bob"
}).save().then(function() {
expect(statements).to.eql([ "insert" ]);
});
});
it("doesn't save created with saved = true", function() {
var bob = person({ name: "bob" }, { saved: true });
return bob.save().then(function() {
expect(statements).to.eql([]);
bob.name = "jane";
bob.id = 1;
return bob.save().then(function() {
expect(statements).to.eql([ "update" ]);
});
});
});
it("updates when created with saved = true and force = true", function() {
return person({
id: 1,
name: "bob"
}, { saved: true }).save({ force: true }).then(function() {
expect(statements).to.eql([ "update" ]);
});
});
it("updates when created with saved = true and modified = true", function() {
return person({
id: 1,
name: "bob"
}, {
saved: true,
modified: true
}).save().then(function() {
expect(statements).to.eql([ "update" ]);
});
});
it("throws if no id on update", function() {
return expect(person({
name: "bob"
}, {
saved: true,
modified: true
}).save()).to.eventually.be.rejectedWith("entity must have id to be updated");
});
});
describe("compound keys", function() {
it("can save an entity with compound keys", function() {
var pa = personAddress({
person_id: 12,
address_id: 34
});
return pa.save().then(function() {
return db.query("select * from people_addresses").then(function(peopleAddresses) {
return expect(helpers.clean(peopleAddresses)).to.eql([{
person_id: 12,
address_id: 34,
rating: null
}]);
});
});
});
it("can update an entity with compound keys", function() {
var pa = personAddress({
person_id: 12,
address_id: 34,
rating: 1
});
return pa.save().then(function() {
return db.query("select * from people_addresses").then(function(peopleAddresses) {
expect(helpers.clean(peopleAddresses)).to.eql([{
person_id: 12,
address_id: 34,
rating: 1
}]);
pa.rating = 10;
return pa.save().then(function() {
return db.query("select * from people_addresses").then(function(updatedPeopleAddresses) {
return expect(helpers.clean(updatedPeopleAddresses)).to.eql([ {
person_id: 12,
address_id: 34,
rating: 10
} ]);
});
});
});
});
});
return describe("saving only when modified", function() {
var pa;
beforeEach(function() {
pa = personAddress({
person_id: 12,
address_id: 34
});
});
it("can save an entity with compound keys", function() {
return pa.save().then(function() {
expect(statements).to.eql([ "insert" ]);
return pa.save().then(function() {
expect(statements).to.eql([ "insert" ]);
});
});
});
it("can update an entity with compound keys", function() {
return pa.save().then(function() {
expect(statements).to.eql([ "insert" ]);
pa.rating = 10;
return pa.save().then(function() {
expect(statements).to.eql([ "insert", "update" ]);
return pa.save().then(function() {
expect(statements).to.eql([ "insert", "update" ]);
});
});
});
});
});
});
describe("queries", function() {
describe("parameterised queries", function() {
it("can pass parameters to a query", function() {
return person({
name: "bob"
}).save().then(function() {
return person({
name: "jane"
}).save().then(function() {
return db.query("select name from people where name = @name", {
name: "jane"
}).then(function(records) {
expect(helpers.clean(records)).to.eql([{
name: "jane"
}]);
});
});
});
});
});
return describe("model queries", function() {
it("can pass parameters to a query", function() {
return person({
name: "bob"
}).save().then(function() {
return person({
name: "jane"
}).save().then(function() {
return person.query("select name from people where name = @name", {
name: "jane"
}).then(function(records) {
expect(records.map(function (p) {
return {name: p.name};
})).to.eql([{
name: 'jane'
}]);
});
});
});
});
it("entites are returned from query and can be modified and saved", function() {
var bob = person({
name: "bob"
});
return bob.save().then(function() {
var jane = person({
name: "jane"
});
return jane.save().then(function() {
return person.query("select * from people").then(function(people) {
expect(people.map(function(p) {
return p.name;
})).to.eql([ "bob", "jane" ]);
return people[0].save().then(function() {
people[1].name = "jenifer";
return people[1].save().then(function() {
return db.query("select * from people").then(function(people) {
expect(people.map(function(p) {
return p.name;
})).to.eql([ "bob", "jenifer" ]);
});
});
});
});
});
});
});
});
});
return describe("foreign keys", function() {
it("can save a many to one relationship", function() {
var bob = person({
name: "bob",
address: address({
address: "15, Rue d'Essert"
})
});
return bob.save().then(function() {
expect(statements).to.eql([ "insert", "insert" ]);
return db.query("select * from addresses").then(function(addresses) {
expect(helpers.clean(addresses)).to.eql([{
id: bob.address_id,
address: "15, Rue d'Essert"
}]);
});
});
});
it("can save a shared foreign object", function() {
var essert = address({
address: "15, Rue d'Essert"
});
var bob = person({
name: "bob",
address: essert
});
var jane = person({
name: "jane",
address: essert
});
return Promise.all([bob.save(), jane.save()]).then(function() {
expect(bob.address_id).to.equal(essert.id);
expect(jane.address_id).to.equal(essert.id);
});
});
it("can save a many to one relationship with function", function() {
var bobsAddress;
var bob = person({
name: "bob",
address: function () {
return bobsAddress = address({
address: "15, Rue d'Essert"
})
}
});
return bob.save().then(function() {
expect(statements).to.eql([ "insert", "insert" ]);
expect(bob.address).to.equal(bobsAddress);
return db.query("select * from addresses").then(function(addresses) {
expect(helpers.clean(addresses)).to.eql([{
id: bob.address_id,
address: "15, Rue d'Essert"
}]);
});
});
});
it("can save a many to one relationship with function that returns undefined", function() {
var bobsAddress;
var bob = person({
name: "bob",
address: function () {
}
});
return bob.save().then(function() {
expect(statements).to.eql([ "insert" ]);
expect(bob.address).to.equal(bobsAddress);
return db.query("select * from addresses").then(function(addresses) {
expect(helpers.clean(addresses)).to.eql([]);
});
}).then(function () {
return db.query("select * from people").then(function(people) {
expect(helpers.clean(people)).to.eql([{
id: bob.id,
name: 'bob',
address_id: null
}]);
});
});
});
describe("custom foreign keys", function() {
it("can save a many to one relationship with a custom foreign key", function() {
var personWeirdId = db.model({
table: "people_weird_id",
id: "weird_id",
foreignKeyFor: function(x) {
return x + "_weird_id";
}
});
var bob = personWeirdId({
name: "bob",
address: address({
address: "15, Rue d'Essert"
})
});
return bob.save().then(function() {
return db.query("select * from addresses").then(function(addresses) {
expect(helpers.clean(addresses)).to.eql([{
id: bob.address_weird_id,
address: "15, Rue d'Essert"
}]);
});
});
});
});
it("can save a one to many relationship", function() {
var rueDEssert = address({
address: "15, Rue d'Essert"
});
var bob = person({
name: "bob"
});
rueDEssert.addPerson(bob);
var jane = person({
name: "jane"
});
rueDEssert.addPerson(jane);
return bob.save().then(function() {
expect(statements).to.eql([ "insert", "insert", "insert" ]);
return db.query("select * from addresses").then(function(addresses) {
expect(helpers.clean(addresses)).to.eql([{
id: bob.address_id,
address: "15, Rue d'Essert"
}]);
return db.query("select * from people order by name").then(function(people) {
expect(people.map(function (p) {
return {
name: p.name,
address_id: p.address_id
};
})).to.eql([
{
name: "bob",
address_id: rueDEssert.id
},
{
name: "jane",
address_id: rueDEssert.id
}
]);
});
});
});
});
it("can save a one to many relationship with function", function() {
var bob;
var jane;
var rueDEssert = address({
address: "15, Rue d'Essert",
people: function() {
return [
bob = person({
name: "bob",
address: this
}),
jane = person({
name: "jane",
address: this
})
];
}
});
return rueDEssert.save().then(function() {
expect(statements).to.eql([ "insert", "insert", "insert" ]);
expect(rueDEssert.people).to.eql([bob, jane]);
return db.query("select * from addresses").then(function(addresses) {
expect(helpers.clean(addresses)).to.eql([ {
id: bob.address_id,
address: "15, Rue d'Essert"
} ]);
return db.query("select * from people order by name").then(function(people) {
expect(people.map(function (p) {
return {
name: p.name,
address_id: p.address_id
};
})).to.eql([
{
name: "bob",
address_id: rueDEssert.id
},
{
name: "jane",
address_id: rueDEssert.id
}
]);
});
});
});
});
it("one to many relationships with functions aren't saved twice", function() {
var bob;
var jane;
var rueDEssert = address({
address: "15, Rue d'Essert",
people: function() {
return [
bob = person({
name: "bob",
address: this
}),
jane = person({
name: "jane",
address: this
})
];
}
});
return rueDEssert.save().then(function() {
return rueDEssert.save().then(function() {
return db.query("select * from people order by name").then(function(people) {
expect(people.map(function (p) {
return {
name: p.name,
address_id: p.address_id
};
})).to.eql([
{
name: "bob",
address_id: rueDEssert.id
},
{
name: "jane",
address_id: rueDEssert.id
}
]);
});
});
});
});
it("can have a many to many relationship", function() {
function livesIn(person, address) {
var pa = personAddress({
person: person,
address: address
});
person.addresses = person.addresses || [];
person.addresses.push(pa);
address.people = address.people || [];
address.people.push(pa);
}
var bob = person({
name: "bob"
});
var jane = person({
name: "jane"
});
var fremantle = address({
address: "Fremantle"
});
var essert = address({
address: "15 Rue d'Essert"
});
livesIn(bob, fremantle);
livesIn(jane, fremantle);
livesIn(jane, essert);
return essert.save().then(function() {
return fremantle.save().then(function() {
expect(statements).to.eql([ "insert", "insert", "insert", "insert", "insert", "insert", "insert" ]);
return db.query("select * from people order by name").then(function(people) {
expect(people.map(function (p) {
return {
name: p.name,
id: p.id
};
})).to.eql([
{ id: bob.id, name: 'bob' },
{ id: jane.id, name: 'jane' }
]);
return db.query("select * from people_addresses order by address_id, person_id").then(function(peopleAddresses) {
expect(helpers.clean(peopleAddresses)).to.eql([
{
address_id: essert.id,
person_id: jane.id,
rating: null
},
{
address_id: fremantle.id,
person_id: jane.id,
rating: null
},
{
address_id: fremantle.id,
person_id: bob.id,
rating: null
}
]);
return db.query("select * from addresses").then(function(addresses) {
return expect(helpers.clean(addresses)).to.eql([
{
id: essert.id,
address: "15 Rue d'Essert"
}, {
id: fremantle.id,
address: "Fremantle"
}
]);
});
});
});
});
});
});
});
});
describe("connection", function() {
it("can define models before connecting to database", function() {
var schema = sworm.db();
var personModel = schema.model({
table: "people"
});
var bob = personModel({
name: "bob"
});
return schema.connect(config).then(function() {
return bob.save().then(function() {
return schema.query("select * from people").then(function(people) {
expect(people.map(function (p) {
return p.name;
})).to.eql(['bob']);
});
});
});
});
it('can setup the session after connection', function () {
this.timeout(5000);
var statements = [];
var db = sworm.db(_.extend(config, {setupSession: function (db) {
return db.query('select * from people_addresses');
}}));
db.log = function (query) {
statements.push(query);
};
return db.query('select * from people').then(function () {
expect(statements).to.eql(['select * from people_addresses', 'select * from people']);
});
});
});
});
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc