UNPKG

streamsql

Version:
385 lines (337 loc) 9.9 kB
const test = require('tap').test const useDb = require('./testdb') test('table.get', function (t) { useDb(t, ['user'], function (db, done) { const user = makeUserTable(db) user.row.fullname = function fullname() { return this.first_name + ' ' + this.last_name } user.get({ last_name: 'Hannah' }, { sort: 'first_name', debug: true }, function (err, row) { t.notOk(err, 'no errors') t.same(row[0].fullname(), 'Barry Hannah') user.getOne({last_name: 'Hannah'}, function (err, row) { t.notOk(err, 'no errors') t.same(row.fullname(), 'Barry Hannah') t.end() }) }) }) }) test('table.get, pagination', function (t) { useDb(t, ['user'], function (db, done) { const user = makeUserTable(db) const options = { limit: 1, page: 1, includeTotal: true, debug: true }; const query = { age: { operation: ">", value: 45, } } user.get(query, function (err, rows) { const expectedTotal = rows.length const expectedFirstRow = rows[0] user.get(query, options, function (err, data) { t.same(expectedTotal, data.total, 'has correct total') t.same(expectedFirstRow, data.rows[0], 'has correct first row') t.same(data.rows.length, 1, 'has correct limit'); t.end(); }) }) }) }) test('table.get, ordering', function (t) { useDb(t, ['user'], function (db, done) { const user = makeUserTable(db) user.get({}, { sort: {age: 'desc'}, debug: true }, function (err, rows) { t.notOk(err, 'No error thrown') t.ok(rows[0].age > rows[1].age, 'Sorted by age descending') user.get({}, {order: {age: 'desc'}}, function (err, moreRows) { t.deepEquals(rows, moreRows, '`sort` and `order` synonymous') t.end() }) }) }) }) test('table.get, complex where', function (t) { useDb(t, ['user'], function (db, done) { const user = makeUserTable(db) user.get({ age: [ { value: 40, op: '>=' }, { value: 60, op: '<=' }, ] }, { sort: 'age', debug: true }, function (err, rows) { const expect = ['Link', 'Saunders'] const result = rows.map(value('last_name')) t.same(result, expect, 'should have the right values') t.end() }) }) }) test('table.get, complex where', function (t) { useDb(t, ['user'], function (db, done) { const user = makeUserTable(db) const sql = 'select last_name AS `last` from $table where first_name = ? OR first_name = ?' user.get([sql, ['George', 'Kelly']], function (err, rows) { console.dir(err) const expect = ['Saunders', 'Link'] const result = rows.map(value('last')) t.same(result, expect, 'should have the right values') t.end() }) }) }) test('table.get, relationships', function (t) { useDb(t, ['user', 'book'], function (db, done) { const user = makeUserTable(db) const book = makeBookTable(db) const review = makeReviewTable(db) book.get({}, { debug: true, relationships: true }, function (err, allBooks) { t.notOk(err, 'no errors') t.equal(allBooks.length, 17, 'all books accounted for') book.get({ author_id: 1 }, { debug: true, relationships: true }, function (err, someBooks) { t.notOk(err, 'no errors') t.ok(someBooks.length < allBooks.length, 'query returns subset of books') t.equal(someBooks.length, 6, 'all requested books accounted for') t.end() }) }) }) }) test('table.get, relationships', function (t) { useDb(t, ['user', 'book'], function (db, done) { const user = makeUserTable(db) const book = makeBookTable(db) user.getOne({ id: 1 }, { debug: true, relationships: true }, function (err, author) { t.notOk(err, 'no errors') t.equal(author.last_name, 'Saunders', 'We\'ve found Mr Saunders') book.get({ author_id: 1 }, { debug: true, }, function (err, books) { t.notOk(err, 'no errors') t.equal(author.books.length, books.length, 'All of author\'s books found correctly') t.end() }) }) }) }) test('table.get, nested relationships', function (t) { useDb(t, ['user', 'book', 'review'], function (db, done) { const user = makeUserTable(db) const book = makeBookTable(db) const review = makeReviewTable(db) review.getOne({ id: 1 }, { debug: true, relationships: true, relationshipsDepth: -1 }, function (err, review) { t.notOk(err, 'no errors') t.same(review.test(), 'This is a review', 'review is model instance') t.ok(review.book, 'review book returned') t.same(review.book.test(), 'This is a book', 'book is model instance') t.ok(review.book.author, 'review book author returned') t.same(review.book.author.test(), 'This is a user', 'author is model instance') t.ok(review.book.author.books, 'review book author publications returned') t.same(review.book.author.books[0].test(), 'This is a book', 'review book author publications are model instances') t.end() }) }) }) test('table.get, many-to-many relationships', function (t) { useDb(t, ['via'], function (db, done) { const primary = makeViaPrimaryTable(db); const secondary = makeViaSecondaryTable(db); const via = makeViaThroughTable(db); primary.get({}, { debug: true, relationships: true }, function (err, rows) { t.same(rows.length, 3) t.same(rows[0].things.length, 3) secondary.get({id: 2}, { debug: true, relationships: true }, function (err, rows) { t.same(rows.length, 1) t.same(rows[0].things.length, 2) t.end() }); }) }) }) test('table.get, OR query', function (t) { useDb(t, ['user'], function (db, done) { const user = makeUserTable(db) user.get([{age: {value: 65, operation: '>='}}, {first_name: 'George'}], { debug: true }, function (err, rows) { t.notOk(err, 'No errors') t.same(rows.length, 2) t.same(rows[0].first_name, 'George') t.same(rows[1].first_name, 'Barry') t.end() }); }) }) // https://github.com/brianloveswords/streamsql/issues/10 test('table.get, relationships should not hang when query returns empty set', function (t) { useDb(t, ['user', 'book'], function (db, done) { const user = makeUserTable(db) const book = makeBookTable(db) user.get({ id: 'whatever' }, { debug: true, relationships: true }, function (err, authors) { t.same(authors, []) t.end() }) }) }) // https://github.com/brianloveswords/streamsql/issues/5 test('table.getOne, should not hang on empty rows', function (t) { useDb(t, ['empty'], function (db, done) { const empty = db.table('empty', ['space']) empty.getOne({ id: 1 }, { debug: true, }, function (err, row) { console.dir(row) t.end() }) }) }) // https://github.com/brianloveswords/streamsql/issues/8 test('table.get, better raw sql handling', function (t) { useDb(t, ['empty'], function (db, done) { const empty = db.table('empty', ['space']) empty.getOne('select 1 as `lol`', { debug: true, }, function (err, row) { t.same(row, {lol: 1}) t.end() }) }) }) test('table.get, better error messaging', function (t) { useDb(t, ['empty'], function (db, done) { const empty = db.table('empty', ['space']) empty.getOne({id: undefined}, { debug: true, }, function (err, row) { t.same(err.name, 'RangeError') t.end() }) }) }) function value(name) { return function (obj) { return obj[name] } } function makeUserTable(db) { return db.table('user', { fields: ['first_name', 'last_name', 'age'], methods: { test: function testUserMethods () { return 'This is a user' } }, relationships: { books: { type: 'hasMany', local: 'id', foreign: { table: 'book', key: 'author_id' }, optional: true, } }, }) } function makeBookTable(db) { return db.table('book', { fields: [ 'id', 'author_id', 'title', 'release_date' ], methods: { test: function testBookMethods () { return 'This is a book' } }, relationships: { author: { type: 'hasOne', local: 'author_id', foreign: { table: 'user', key: 'id' }, }, reviews: { type: 'hasMany', local: 'id', foreign: { table: 'review', key: 'book_id' }, optional: true, }, }, }) } function makeReviewTable(db) { return db.table('review', { fields: ['id', 'book_id', 'link'], methods: { test: function testReviewMethods () { return 'This is a review' } }, relationships: { book: { type: 'hasOne', local: 'book_id', foreign: { table: 'book', key: 'id' }, } } }) } function makeViaPrimaryTable(db) { return db.table('viaPrimary', { fields: ['id', 'label'], relationships: { things: { type: 'hasMany', local: 'id', foreign: { table: 'viaSecondary', key: 'id' }, via: { table: 'viaThrough', local: 'primary_id', foreign: 'secondary_id' } } } }) } function makeViaSecondaryTable(db) { return db.table('viaSecondary', { fields: ['id', 'label'], relationships: { things: { type: 'hasMany', local: 'id', foreign: { table: 'viaPrimary', key: 'id' }, via: { table: 'viaThrough', local: 'secondary_id', foreign: 'primary_id' } } } }) } function makeViaThroughTable(db) { return db.table('viaThrough', { fields: ['primary_id', 'secondary_id'] }) }