From 1deaa9e1504eda6109008363bc077a61bba9765b Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 10 Dec 2014 15:16:47 +1100 Subject: [PATCH 01/12] Complete refactor to not use collection-hooks --- counter-cache.js | 154 ++++++++++++------------ counter-cache_tests.js | 259 ++++++++++++++++++++++++++--------------- package.js | 6 +- 3 files changed, 249 insertions(+), 170 deletions(-) diff --git a/counter-cache.js b/counter-cache.js index 8f8bd62..43b7a88 100644 --- a/counter-cache.js +++ b/counter-cache.js @@ -2,17 +2,12 @@ var debug = function(str) { // console.log('counter-cache: ' + str); }; -// iterator for the property functions below -var walker = function(node, part) { return node[part]; }; - -_.mixin({ - dottedProperty: function(record, key) { - return _.reduce(key.split('.'), walker, record || {}); - } -}); - var resolveForeignKey = function(doc, foreignKey) { - return _.isFunction(foreignKey) ? foreignKey(doc) : _.dottedProperty(doc, foreignKey); + if (_.isFunction(foreignKey)) { + return foreignKey(doc); + } else { + return Meteor._get.apply(Meteor, [].concat(doc, foreignKey.split('.'))); + } }; var applyFilter = function(doc, filter) { @@ -22,71 +17,80 @@ var applyFilter = function(doc, filter) { return true; }; -Mongo.Collection.prototype.maintainCountOf = function(collection, foreignKey, counterField, filter) { - var self = this; - - if (! (collection instanceof Mongo.Collection)) - throw new Error("Expected first argument to be a Mongo Collection"); - if (! foreignKey) - throw new Error("Missing argument: foreignKey"); - - if (! counterField) - counterField = collection._name + 'Count'; - - debug('setup counts of `' + collection._name + '` onto `' + this._name + '` with counter field `' + counterField + '`'); - var modifier = { $inc: {}}; - var increment = function(_id) { - debug('increment ' + _id); - if (! _id) return; - - modifier.$inc[counterField] = 1; - self.update(_id, modifier); - }; - var decrement = function(_id) { - debug('decrement ' + _id); - if (! _id) return; - - modifier.$inc[counterField] = -1; - self.update(_id, modifier); - }; - - collection.after.insert(function(userId, doc) { - var foreignKeyValue = resolveForeignKey(doc, foreignKey); - if (foreignKeyValue && applyFilter(doc, filter)) - increment(foreignKeyValue); +CounterCache = function(options) { + // could probably be more flexible in how we establish relationships + check(options, { + target: { + collection: Mongo.Collection, + counter: String + }, + source: { + collection: Mongo.Collection, + foreignKey: Match.OneOf(String, Function), + filter: Match.Optional(Function) + } }); - - collection.after.update(function(userId, doc, fieldNames, modifier, options) { - var self = this; - var oldDoc = self.previous; - - // console.log(modifier); - // console.log(fieldNames); - // console.log(self.previous); - // console.log(doc); - - // LocalCollection._modify(doc, modifier); - - var oldDocForeignKeyValue = resolveForeignKey(oldDoc, foreignKey); - var newDocForeignKeyValue = resolveForeignKey(doc, foreignKey); - - var filterApplyOldValue = applyFilter(oldDoc, filter); - var filterApplyNewValue = applyFilter(doc, filter); - - if (oldDocForeignKeyValue === newDocForeignKeyValue && filterApplyOldValue === filterApplyNewValue) - return; - - if (oldDocForeignKeyValue && filterApplyOldValue) - decrement(oldDocForeignKeyValue); - - if (newDocForeignKeyValue && filterApplyNewValue) - increment(newDocForeignKeyValue); - }); - - collection.after.remove(function(userId, doc) { - var foreignKeyValue = resolveForeignKey(doc, foreignKey); - if (foreignKeyValue && applyFilter(doc, filter)) - decrement(foreignKeyValue); + + // debug('setup counts of `' + collection._name + '` onto `' + this._name + '` with counter field `' + counterField + '`'); + + // private functions (going all crockford on this one) + var increment = function(_id, direction) { + var mod = {$inc: {}}; + mod.$inc[options.target.counter] = direction || 1; + options.target.collection.update(_id, mod); + } + + var getDoc = function(id) { + var fields = {}; + // optimization -- if we don't have special foreignKey or filter functions, + // we know we only need the foreign key from the db + if (! options.source.filter && ! _.isFunction(options.source.foreignKey)) + fields[options.source.foreignKey] = 1; + return options.source.collection.findOne(id, {fields: fields}); + } + + var resolve = function(doc) { + return resolveForeignKey(doc, options.source.foreignKey); + } + + var filter = function(doc) { + return applyFilter(doc, options.source.filter); + } + + _.extend(this, { + insert: function(doc) { + var foreignKeyValue = resolve(doc); + if (foreignKeyValue && filter(doc)) + increment(foreignKeyValue, 1); + }, + update: function(id, modifier) { + var oldDoc = getDoc(id); + + var newDoc = EJSON.clone(oldDoc); + LocalCollection._modify(newDoc, modifier); + + var oldDocForeignKeyValue = resolve(oldDoc); + var newDocForeignKeyValue = resolve(newDoc); + + var filterApplyOldValue = filter(oldDoc); + var filterApplyNewValue = filter(newDoc); + + if (oldDocForeignKeyValue === newDocForeignKeyValue && + filterApplyOldValue === filterApplyNewValue) + return; + + if (oldDocForeignKeyValue && filterApplyOldValue) + increment(oldDocForeignKeyValue, -1); + + if (newDocForeignKeyValue && filterApplyNewValue) + increment(newDocForeignKeyValue, 1); + }, + remove: function(id) { + var doc = getDoc(id); + var foreignKeyValue = resolve(doc); + if (foreignKeyValue && filter(doc)) + increment(foreignKeyValue, -1); + } }); -}; +} \ No newline at end of file diff --git a/counter-cache_tests.js b/counter-cache_tests.js index a0d918f..278cc08 100644 --- a/counter-cache_tests.js +++ b/counter-cache_tests.js @@ -1,128 +1,193 @@ -Tinytest.add('Counter cache - foreignKey works', function(test) { - Authors = new Mongo.Collection('authors' + test.id); - Books = new Mongo.Collection('books' + test.id); +var setup = function(test, options) { + var collections = { + authors: new Mongo.Collection('authors' + test.id), + books: new Mongo.Collection('books' + test.id) + } + + options = options || {target: {}, source: {}}; + _.defaults(options.target, { + collection: collections.authors, + counter: 'booksCount' + }); + _.defaults(options.source, { + collection: collections.books, + foreignKey: 'authorId' + }); + var bookCounter = new CounterCache(options); + + collections.books.mutate = { + insert: function(doc) { + bookCounter.insert(doc); + return collections.books.insert(doc); + }, + update: function(id, update) { + bookCounter.update(id, update); + return collections.books.update(id, update); + }, + remove: function(id) { + bookCounter.remove(id); + return collections.books.remove(id) + } + }; + + return collections; +} - Authors.maintainCountOf(Books, 'authorId', 'booksCount'); - var authorId = Authors.insert({ +Tinytest.add('Counter cache - foreignKey works', function(test) { + var collections = setup(test); + + var authorId = collections.authors.insert({ name: 'Charles Darwin' }); - var bookId = Books.insert({ + var bookId = collections.books.mutate.insert({ name: 'On the Origin of Species', authorId: authorId }); - var author = Authors.findOne(authorId); + var author = collections.authors.findOne(authorId); // insert test.equal(author.booksCount, 1); - Books.remove(bookId); - author = Authors.findOne(authorId); + collections.books.mutate.remove(bookId); + author = collections.authors.findOne(authorId); // remove test.equal(author.booksCount, 0); // insert book again - bookId = Books.insert({ + bookId = collections.books.mutate.insert({ name: 'On the Origin of Species', authorId: authorId }); - author = Authors.findOne(authorId); + author = collections.authors.findOne(authorId); // we should be 1 again test.equal(author.booksCount, 1); - author2Id = Authors.insert({ + author2Id = collections.authors.insert({ name: 'Charles Darwin 2' }); // insert a book for a different author - book2Id = Books.insert({ + book2Id = collections.books.mutate.insert({ name: 'A test book', authorId: author2Id }); // this should not affect the first author count - author = Authors.findOne(authorId); + author = collections.authors.findOne(authorId); test.equal(author.booksCount, 1); - Books.remove(book2Id); + collections.books.mutate.remove(book2Id); // change this book to another author - Books.update(bookId, { $set: { authorId: author2Id }}); + collections.books.mutate.update(bookId, { $set: { authorId: author2Id }}); - author = Authors.findOne(authorId); + author = collections.authors.findOne(authorId); // book changed author test.equal(author.booksCount, 0); - var author2 = Authors.findOne(author2Id); + var author2 = collections.authors.findOne(author2Id); test.equal(author2.booksCount, 1); // set back to original author again - Books.update(bookId, { $set: { authorId: authorId }}); + collections.books.mutate.update(bookId, { $set: { authorId: authorId }}); - author2 = Authors.findOne(author2Id); + author2 = collections.authors.findOne(author2Id); test.equal(author2.booksCount, 0); - author = Authors.findOne(authorId); + author = collections.authors.findOne(authorId); test.equal(author.booksCount, 1); // remove authorId - Books.update(bookId, { $unset: { authorId: '' }}); + collections.books.mutate.update(bookId, { $unset: { authorId: '' }}); - author = Authors.findOne(authorId); + author = collections.authors.findOne(authorId); test.equal(author.booksCount, 0); // random update that doesn't include the authorId - Books.update(bookId, { $set: { nothing: true }}); + collections.books.mutate.update(bookId, { $set: { nothing: true }}); test.equal(author.booksCount, 0); // update with the same id - Books.update(bookId, { $set: { authorId: authorId }}); - Books.update(bookId, { $set: { authorId: authorId }}); - Books.update(bookId, { $set: { authorId: authorId }}); + collections.books.mutate.update(bookId, { $set: { authorId: authorId }}); + collections.books.mutate.update(bookId, { $set: { authorId: authorId }}); + collections.books.mutate.update(bookId, { $set: { authorId: authorId }}); - author = Authors.findOne(authorId); + author = collections.authors.findOne(authorId); test.equal(author.booksCount, 1); }); Tinytest.add('Counter cache - foreignKey lookup function', function(test) { - Publishers = new Mongo.Collection('publishers' + test.id); - Publishers.maintainCountOf(Books, function(doc) { - return Authors.findOne(doc.authorId).publisherId; - }, 'booksCount'); + // this one's a bit different + var collections = { + publishers: new Mongo.Collection('publishers' + test.id), + authors: new Mongo.Collection('authors' + test.id), + books: new Mongo.Collection('books' + test.id) + } + + var bookCounter = new CounterCache({ + target: { + collection: collections.publishers, + counter: 'fictionBooksCount' + }, + source: { + collection: collections.books, + foreignKey: function(doc) { + return collections.authors.findOne(doc.authorId).publisherId; + }, + filter: function(doc) { return doc.isFiction; } + } + }); + + collections.books.mutate = { + insert: function(doc) { + bookCounter.insert(doc); + return collections.books.insert(doc); + }, + update: function(id, update) { + bookCounter.update(id, update); + return collections.books.update(id, update); + }, + remove: function(id) { + bookCounter.remove(id); + return collections.books.remove(id) + } + }; - var publisherId = Publishers.insert({ - name: 'Good Books' + var publisherId = collections.publishers.insert({ + name: 'Good collections.books' }); - var publisher2Id = Publishers.insert({ - name: 'Gooder Books' + var publisher2Id = collections.publishers.insert({ + name: 'Gooder collections.books' }); - var authorId = Authors.insert({ + var authorId = collections.authors.insert({ name: 'Charles Darwin', publisherId: publisherId }); - var author2Id = Authors.insert({ + var author2Id = collections.authors.insert({ name: 'Charles Darwin 2', publisherId: publisher2Id }); - var bookId = Books.insert({ + var bookId = collections.books.mutate.insert({ name: 'On the Origin of Species', - authorId: authorId + authorId: authorId, + isFiction: true }); - var publisher = Publishers.findOne(publisherId); + var publisher = collections.publishers.findOne(publisherId); // insert - test.equal(publisher.booksCount, 1); + test.equal(publisher.fictionBooksCount, 1); // remove - Books.remove(bookId); + collections.books.mutate.remove(bookId); - publisher = Publishers.findOne(publisherId); + publisher = collections.publishers.findOne(publisherId); - test.equal(publisher.booksCount, 0); + test.equal(publisher.fictionBooksCount, 0); // TODO: Add tests like above @@ -130,103 +195,111 @@ Tinytest.add('Counter cache - foreignKey lookup function', function(test) { // Note: // If we remove an author, the publishers book count will not change to reflect this, - // in this case a before-remove collection-hook on Authors should be setup to remove - // all books related to this author. + // in this case a before-remove collection-hook on collections.authors should be setup to remove + // all collections.books related to this author. }); Tinytest.add('Counter cache - filter and foreignKey - add and remove', function(test) { - Authors = new Mongo.Collection('authors' + test.id); - Books = new Mongo.Collection('books' + test.id); - var filter = function(doc) { return doc.isFiction; }; - Authors.maintainCountOf(Books, 'authorId', 'fictionBooksCount', filter); - - var authorId = Authors.insert({ + var collections = setup(test, { + target: { + counter: 'fictionBooksCount' + }, + source: { + filter: function(doc) { return doc.isFiction; } + } + }); + + var authorId = collections.authors.insert({ name: 'Test Author' }); // Filter increments on insert - var book1Id = Books.insert({ + var book1Id = collections.books.mutate.insert({ name: 'How to test your book counters', authorId: authorId, isFiction: true }); - test.equal(Authors.findOne(authorId).fictionBooksCount, 1); + test.equal(collections.authors.findOne(authorId).fictionBooksCount, 1); // Filter shouldn't have incremented with this book - var book2Id = Books.insert({ + var book2Id = collections.books.mutate.insert({ name: 'How to test your book counters again', authorId: authorId, isFiction: false }); - test.equal(Authors.findOne(authorId).fictionBooksCount, 1); + test.equal(collections.authors.findOne(authorId).fictionBooksCount, 1); // filter decrements on delete - Books.remove(book1Id); - test.equal(Authors.findOne(authorId).fictionBooksCount, 0); + collections.books.mutate.remove(book1Id); + test.equal(collections.authors.findOne(authorId).fictionBooksCount, 0); // but not if it's false - Books.remove(book2Id); - test.equal(Authors.findOne(authorId).fictionBooksCount, 0); + collections.books.mutate.remove(book2Id); + test.equal(collections.authors.findOne(authorId).fictionBooksCount, 0); }); Tinytest.add('Counter cache - filter and foreignKey - changes', function(test) { - Authors = new Mongo.Collection('authors' + test.id); - Books = new Mongo.Collection('books' + test.id); - var filter = function(doc) { return doc.isFiction; }; - Authors.maintainCountOf(Books, 'authorId', 'fictionBooksCount', filter); + var collections = setup(test, { + target: { + counter: 'fictionBooksCount' + }, + source: { + filter: function(doc) { return doc.isFiction; } + } + }); - var author1Id = Authors.insert({ + var author1Id = collections.authors.insert({ name: 'Test Author', fictionBooksCount: 0 }); - var author2Id = Authors.insert({ + var author2Id = collections.authors.insert({ name: 'Test Author 2', fictionBooksCount: 0 }); - var bookId = Books.insert({ + var bookId = collections.books.mutate.insert({ name: 'How to test your book counters', authorId: author1Id, isFiction: true }); - test.equal(Authors.findOne(author1Id).fictionBooksCount, 1); + test.equal(collections.authors.findOne(author1Id).fictionBooksCount, 1); // 1. an irrelevant change - Books.update(bookId, {$set: {name: 'A new way to test'}}); - test.equal(Authors.findOne(author1Id).fictionBooksCount, 1); - test.equal(Authors.findOne(author2Id).fictionBooksCount, 0); + collections.books.mutate.update(bookId, {$set: {name: 'A new way to test'}}); + test.equal(collections.authors.findOne(author1Id).fictionBooksCount, 1); + test.equal(collections.authors.findOne(author2Id).fictionBooksCount, 0); // 2. change it to no longer match - Books.update(bookId, {$set: {isFiction: false}}); - test.equal(Authors.findOne(author1Id).fictionBooksCount, 0); - test.equal(Authors.findOne(author2Id).fictionBooksCount, 0); + collections.books.mutate.update(bookId, {$set: {isFiction: false}}); + test.equal(collections.authors.findOne(author1Id).fictionBooksCount, 0); + test.equal(collections.authors.findOne(author2Id).fictionBooksCount, 0); // 3. an irrelevant change - Books.update(bookId, {$set: {name: 'A new way to test again'}}); - test.equal(Authors.findOne(author1Id).fictionBooksCount, 0); - test.equal(Authors.findOne(author2Id).fictionBooksCount, 0); + collections.books.mutate.update(bookId, {$set: {name: 'A new way to test again'}}); + test.equal(collections.authors.findOne(author1Id).fictionBooksCount, 0); + test.equal(collections.authors.findOne(author2Id).fictionBooksCount, 0); // 4. change author without changing matching - Books.update(bookId, {$set: {authorId: author2Id}}); - test.equal(Authors.findOne(author1Id).fictionBooksCount, 0); - test.equal(Authors.findOne(author2Id).fictionBooksCount, 0); + collections.books.mutate.update(bookId, {$set: {authorId: author2Id}}); + test.equal(collections.authors.findOne(author1Id).fictionBooksCount, 0); + test.equal(collections.authors.findOne(author2Id).fictionBooksCount, 0); // 5. change to now match - Books.update(bookId, {$set: {isFiction: true}}); - test.equal(Authors.findOne(author1Id).fictionBooksCount, 0); - test.equal(Authors.findOne(author2Id).fictionBooksCount, 1); + collections.books.mutate.update(bookId, {$set: {isFiction: true}}); + test.equal(collections.authors.findOne(author1Id).fictionBooksCount, 0); + test.equal(collections.authors.findOne(author2Id).fictionBooksCount, 1); // 6. change author without changing matching - Books.update(bookId, {$set: {authorId: author1Id}}); - test.equal(Authors.findOne(author1Id).fictionBooksCount, 1); - test.equal(Authors.findOne(author2Id).fictionBooksCount, 0); + collections.books.mutate.update(bookId, {$set: {authorId: author1Id}}); + test.equal(collections.authors.findOne(author1Id).fictionBooksCount, 1); + test.equal(collections.authors.findOne(author2Id).fictionBooksCount, 0); // 7. change author while changing matching - Books.update(bookId, {$set: {authorId: author2Id, isFiction: false}}); - test.equal(Authors.findOne(author1Id).fictionBooksCount, 0); - test.equal(Authors.findOne(author2Id).fictionBooksCount, 0); + collections.books.mutate.update(bookId, {$set: {authorId: author2Id, isFiction: false}}); + test.equal(collections.authors.findOne(author1Id).fictionBooksCount, 0); + test.equal(collections.authors.findOne(author2Id).fictionBooksCount, 0); // 8. change author while changing matching - Books.update(bookId, {$set: {authorId: author1Id, isFiction: true}}); - test.equal(Authors.findOne(author1Id).fictionBooksCount, 1); - test.equal(Authors.findOne(author2Id).fictionBooksCount, 0); + collections.books.mutate.update(bookId, {$set: {authorId: author1Id, isFiction: true}}); + test.equal(collections.authors.findOne(author1Id).fictionBooksCount, 1); + test.equal(collections.authors.findOne(author2Id).fictionBooksCount, 0); }); \ No newline at end of file diff --git a/package.js b/package.js index d41adf7..67a9973 100644 --- a/package.js +++ b/package.js @@ -1,4 +1,5 @@ Package.describe({ + name: 'dburles:counter-cache', summary: "Cache the counts of an associated collection", version: "0.2.1", git: "https://github.com/percolatestudio/meteor-counter-cache.git" @@ -6,11 +7,12 @@ Package.describe({ Package.onUse(function(api) { api.use([ - 'mrt:collection-hooks@0.6.3', 'underscore@1.0.0', - 'mongo@1.0.6' + 'mongo@1.0.6', + 'minimongo' ]); api.add_files('counter-cache.js', ['client', 'server']); + api.export('CounterCache'); }); Package.onTest(function(api) { From 8f6176e377ee26e8c929b200eba0344ba058e789 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 10 Dec 2014 15:28:13 +1100 Subject: [PATCH 02/12] Need this --- package.js | 1 + 1 file changed, 1 insertion(+) diff --git a/package.js b/package.js index 67a9973..1c5b3e7 100644 --- a/package.js +++ b/package.js @@ -7,6 +7,7 @@ Package.describe({ Package.onUse(function(api) { api.use([ + 'check', 'underscore@1.0.0', 'mongo@1.0.6', 'minimongo' From 152fe9fe14793e459f83952bdd919a0e2831ebd8 Mon Sep 17 00:00:00 2001 From: Jani Halmetoja Date: Wed, 1 Apr 2015 18:06:16 +0300 Subject: [PATCH 03/12] replaced mrt:collection-hooks@0.6.3 with matb33:collection-hooks@0.7.11 --- .versions | 22 ++++++++++++++++++++++ package.js | 9 +++++---- smart.json | 10 +++++----- 3 files changed, 32 insertions(+), 9 deletions(-) create mode 100644 .versions diff --git a/.versions b/.versions new file mode 100644 index 0000000..d672422 --- /dev/null +++ b/.versions @@ -0,0 +1,22 @@ +base64@1.0.3 +binary-heap@1.0.3 +callback-hook@1.0.3 +check@1.0.5 +ddp@1.1.0 +ejson@1.0.6 +geojson-utils@1.0.3 +hazio:counter-cache@0.0.1 +id-map@1.0.3 +json@1.0.3 +local-test:hazio:counter-cache@0.0.1 +logging@1.0.7 +matb33:collection-hooks@0.7.11 +meteor@1.1.6 +minimongo@1.0.8 +mongo@1.1.0 +ordered-dict@1.0.3 +random@1.0.3 +retry@1.0.3 +tinytest@1.0.5 +tracker@1.0.7 +underscore@1.0.3 diff --git a/package.js b/package.js index d41adf7..518168a 100644 --- a/package.js +++ b/package.js @@ -1,12 +1,12 @@ Package.describe({ + name: "hazio:counter-cache", summary: "Cache the counts of an associated collection", - version: "0.2.1", - git: "https://github.com/percolatestudio/meteor-counter-cache.git" + version: "0.0.1" }); Package.onUse(function(api) { api.use([ - 'mrt:collection-hooks@0.6.3', + 'matb33:collection-hooks@0.7.11', 'underscore@1.0.0', 'mongo@1.0.6' ]); @@ -14,6 +14,7 @@ Package.onUse(function(api) { }); Package.onTest(function(api) { - api.use(['tinytest', 'dburles:counter-cache']); + api.use(['tinytest', 'hazio:counter-cache']); api.add_files('counter-cache_tests.js', 'server'); }); + diff --git a/smart.json b/smart.json index cb73575..d80e265 100644 --- a/smart.json +++ b/smart.json @@ -1,11 +1,11 @@ { "name": "counter-cache", "description": "Cache the counts of an associated collection", - "homepage": "https://github.com/percolatestudio/meteor-counter-cache", - "author": "David Burles (http://twitter.com/dburles)", - "version": "0.1.3", - "git": "https://github.com/percolatestudio/meteor-counter-cache.git", + "homepage": "https://github.com/hazio/meteor-counter-cache", + "author": "Jani Halmetoja (http://twitter.com/halmetoja)", + "version": "0.0.1", + "git": "https://github.com/hazio/meteor-counter-cache.git", "packages": { - "collection-hooks": "0.6.3" + "matb33:collection-hooks": "0.7.11" } } From 0be6400396b823b2597fcc44c823ef3a1f7900ec Mon Sep 17 00:00:00 2001 From: Jani Halmetoja Date: Wed, 1 Apr 2015 18:09:09 +0300 Subject: [PATCH 04/12] added git repo --- package.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.js b/package.js index 518168a..e0f2740 100644 --- a/package.js +++ b/package.js @@ -1,7 +1,8 @@ Package.describe({ name: "hazio:counter-cache", summary: "Cache the counts of an associated collection", - version: "0.0.1" + version: "0.0.1", + git: "https://github.com/hazio/meteor-counter-cache.git" }); Package.onUse(function(api) { From 3a05aecacfb15519371f8e83e02a39c50ef5149d Mon Sep 17 00:00:00 2001 From: Jani Halmetoja Date: Wed, 1 Apr 2015 18:13:21 +0300 Subject: [PATCH 05/12] credits to percolatestudio --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 37d0c98..dea5121 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ meteor-counter-cache ==================== Cache the counts of an associated collection. +Forked from https://github.com/percolatestudio/meteor-counter-cache/ to work with Meteor version 0.9 and above. ## Usage From 7db6652471df92dfadd36429f4b0a6bd8f2a34ff Mon Sep 17 00:00:00 2001 From: Jani Halmetoja Date: Thu, 15 Oct 2015 11:40:13 +0300 Subject: [PATCH 06/12] metadata update --- package.js | 6 +++--- smart.json | 11 ++++------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/package.js b/package.js index 1c5b3e7..bb8f782 100644 --- a/package.js +++ b/package.js @@ -1,8 +1,8 @@ Package.describe({ - name: 'dburles:counter-cache', + name: 'hazio:counter-cache', summary: "Cache the counts of an associated collection", - version: "0.2.1", - git: "https://github.com/percolatestudio/meteor-counter-cache.git" + version: "0.0.3", + git: "https://github.com/hazio/meteor-counter-cache.git" }); Package.onUse(function(api) { diff --git a/smart.json b/smart.json index cb73575..ad62a2d 100644 --- a/smart.json +++ b/smart.json @@ -1,11 +1,8 @@ { "name": "counter-cache", "description": "Cache the counts of an associated collection", - "homepage": "https://github.com/percolatestudio/meteor-counter-cache", - "author": "David Burles (http://twitter.com/dburles)", - "version": "0.1.3", - "git": "https://github.com/percolatestudio/meteor-counter-cache.git", - "packages": { - "collection-hooks": "0.6.3" - } + "homepage": "https://github.com/hazio/meteor-counter-cache", + "author": "Jani Halmetoja (http://twitter.com/halmetoja)", + "version": "0.0.3", + "git": "https://github.com/hazio/meteor-counter-cache.git" } From ebfe472bf9df42efa08c196a2fd2ada4a03bbad2 Mon Sep 17 00:00:00 2001 From: Jani Halmetoja Date: Thu, 15 Oct 2015 11:43:32 +0300 Subject: [PATCH 07/12] package versions --- package.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.js b/package.js index bb8f782..8a7bb67 100644 --- a/package.js +++ b/package.js @@ -7,10 +7,10 @@ Package.describe({ Package.onUse(function(api) { api.use([ - 'check', + 'check@1.0.0', 'underscore@1.0.0', 'mongo@1.0.6', - 'minimongo' + 'minimongo@3.5.6' ]); api.add_files('counter-cache.js', ['client', 'server']); api.export('CounterCache'); From 361aee42fdf5e5cc924890c753e7dcdc66fe5102 Mon Sep 17 00:00:00 2001 From: Jani Halmetoja Date: Thu, 15 Oct 2015 11:45:30 +0300 Subject: [PATCH 08/12] minimongo version --- package.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.js b/package.js index 8a7bb67..1334be4 100644 --- a/package.js +++ b/package.js @@ -10,7 +10,7 @@ Package.onUse(function(api) { 'check@1.0.0', 'underscore@1.0.0', 'mongo@1.0.6', - 'minimongo@3.5.6' + 'minimongo@1.0.10' ]); api.add_files('counter-cache.js', ['client', 'server']); api.export('CounterCache'); From 4af94c4d4cf3a5c8ce5184303b2b91e60f10ffeb Mon Sep 17 00:00:00 2001 From: Jani Halmetoja Date: Thu, 15 Oct 2015 12:41:35 +0300 Subject: [PATCH 09/12] collection-hooks@0.7.11 --- .versions | 47 ++++++++ counter-cache.js | 154 ++++++++++++------------ counter-cache_tests.js | 259 +++++++++++++++-------------------------- package.js | 11 +- smart.json | 11 +- 5 files changed, 226 insertions(+), 256 deletions(-) create mode 100644 .versions diff --git a/.versions b/.versions new file mode 100644 index 0000000..e093af8 --- /dev/null +++ b/.versions @@ -0,0 +1,47 @@ +babel-compiler@5.8.24_1 +babel-runtime@0.1.4 +base64@1.0.4 +binary-heap@1.0.4 +blaze@2.1.3 +blaze-tools@1.0.4 +boilerplate-generator@1.0.4 +callback-hook@1.0.4 +check@1.0.6 +dburles:counter-cache@0.1.2 +ddp@1.2.2 +ddp-client@1.2.1 +ddp-common@1.2.1 +ddp-server@1.2.1 +deps@1.0.9 +diff-sequence@1.0.1 +ecmascript@0.1.5 +ecmascript-collections@0.1.6 +ejson@1.0.7 +geojson-utils@1.0.4 +hazio:counter-cache@0.0.3 +html-tools@1.0.5 +htmljs@1.0.5 +id-map@1.0.4 +jquery@1.11.4 +local-test:hazio:counter-cache@0.0.3 +logging@1.0.8 +meteor@1.1.9 +minimongo@1.0.10 +mongo@1.1.2 +mongo-id@1.0.1 +npm-mongo@1.4.39_1 +observe-sequence@1.0.7 +ordered-dict@1.0.4 +promise@0.5.0 +random@1.0.4 +reactive-var@1.0.6 +retry@1.0.4 +routepolicy@1.0.6 +spacebars@1.0.7 +spacebars-compiler@1.0.7 +tinytest@1.0.6 +tracker@1.0.9 +ui@1.0.8 +underscore@1.0.4 +webapp@1.2.2 +webapp-hashing@1.0.5 diff --git a/counter-cache.js b/counter-cache.js index 43b7a88..8f8bd62 100644 --- a/counter-cache.js +++ b/counter-cache.js @@ -2,12 +2,17 @@ var debug = function(str) { // console.log('counter-cache: ' + str); }; -var resolveForeignKey = function(doc, foreignKey) { - if (_.isFunction(foreignKey)) { - return foreignKey(doc); - } else { - return Meteor._get.apply(Meteor, [].concat(doc, foreignKey.split('.'))); +// iterator for the property functions below +var walker = function(node, part) { return node[part]; }; + +_.mixin({ + dottedProperty: function(record, key) { + return _.reduce(key.split('.'), walker, record || {}); } +}); + +var resolveForeignKey = function(doc, foreignKey) { + return _.isFunction(foreignKey) ? foreignKey(doc) : _.dottedProperty(doc, foreignKey); }; var applyFilter = function(doc, filter) { @@ -17,80 +22,71 @@ var applyFilter = function(doc, filter) { return true; }; +Mongo.Collection.prototype.maintainCountOf = function(collection, foreignKey, counterField, filter) { + var self = this; + + if (! (collection instanceof Mongo.Collection)) + throw new Error("Expected first argument to be a Mongo Collection"); + if (! foreignKey) + throw new Error("Missing argument: foreignKey"); + + if (! counterField) + counterField = collection._name + 'Count'; + + debug('setup counts of `' + collection._name + '` onto `' + this._name + '` with counter field `' + counterField + '`'); -CounterCache = function(options) { - // could probably be more flexible in how we establish relationships - check(options, { - target: { - collection: Mongo.Collection, - counter: String - }, - source: { - collection: Mongo.Collection, - foreignKey: Match.OneOf(String, Function), - filter: Match.Optional(Function) - } + var modifier = { $inc: {}}; + var increment = function(_id) { + debug('increment ' + _id); + if (! _id) return; + + modifier.$inc[counterField] = 1; + self.update(_id, modifier); + }; + var decrement = function(_id) { + debug('decrement ' + _id); + if (! _id) return; + + modifier.$inc[counterField] = -1; + self.update(_id, modifier); + }; + + collection.after.insert(function(userId, doc) { + var foreignKeyValue = resolveForeignKey(doc, foreignKey); + if (foreignKeyValue && applyFilter(doc, filter)) + increment(foreignKeyValue); }); - - // debug('setup counts of `' + collection._name + '` onto `' + this._name + '` with counter field `' + counterField + '`'); - - // private functions (going all crockford on this one) - var increment = function(_id, direction) { - var mod = {$inc: {}}; - mod.$inc[options.target.counter] = direction || 1; - options.target.collection.update(_id, mod); - } - - var getDoc = function(id) { - var fields = {}; - // optimization -- if we don't have special foreignKey or filter functions, - // we know we only need the foreign key from the db - if (! options.source.filter && ! _.isFunction(options.source.foreignKey)) - fields[options.source.foreignKey] = 1; - return options.source.collection.findOne(id, {fields: fields}); - } - - var resolve = function(doc) { - return resolveForeignKey(doc, options.source.foreignKey); - } - - var filter = function(doc) { - return applyFilter(doc, options.source.filter); - } - - _.extend(this, { - insert: function(doc) { - var foreignKeyValue = resolve(doc); - if (foreignKeyValue && filter(doc)) - increment(foreignKeyValue, 1); - }, - update: function(id, modifier) { - var oldDoc = getDoc(id); - - var newDoc = EJSON.clone(oldDoc); - LocalCollection._modify(newDoc, modifier); - - var oldDocForeignKeyValue = resolve(oldDoc); - var newDocForeignKeyValue = resolve(newDoc); - - var filterApplyOldValue = filter(oldDoc); - var filterApplyNewValue = filter(newDoc); - - if (oldDocForeignKeyValue === newDocForeignKeyValue && - filterApplyOldValue === filterApplyNewValue) - return; - - if (oldDocForeignKeyValue && filterApplyOldValue) - increment(oldDocForeignKeyValue, -1); - - if (newDocForeignKeyValue && filterApplyNewValue) - increment(newDocForeignKeyValue, 1); - }, - remove: function(id) { - var doc = getDoc(id); - var foreignKeyValue = resolve(doc); - if (foreignKeyValue && filter(doc)) - increment(foreignKeyValue, -1); - } + + collection.after.update(function(userId, doc, fieldNames, modifier, options) { + var self = this; + var oldDoc = self.previous; + + // console.log(modifier); + // console.log(fieldNames); + // console.log(self.previous); + // console.log(doc); + + // LocalCollection._modify(doc, modifier); + + var oldDocForeignKeyValue = resolveForeignKey(oldDoc, foreignKey); + var newDocForeignKeyValue = resolveForeignKey(doc, foreignKey); + + var filterApplyOldValue = applyFilter(oldDoc, filter); + var filterApplyNewValue = applyFilter(doc, filter); + + if (oldDocForeignKeyValue === newDocForeignKeyValue && filterApplyOldValue === filterApplyNewValue) + return; + + if (oldDocForeignKeyValue && filterApplyOldValue) + decrement(oldDocForeignKeyValue); + + if (newDocForeignKeyValue && filterApplyNewValue) + increment(newDocForeignKeyValue); }); -} \ No newline at end of file + + collection.after.remove(function(userId, doc) { + var foreignKeyValue = resolveForeignKey(doc, foreignKey); + if (foreignKeyValue && applyFilter(doc, filter)) + decrement(foreignKeyValue); + }); +}; diff --git a/counter-cache_tests.js b/counter-cache_tests.js index 278cc08..a0d918f 100644 --- a/counter-cache_tests.js +++ b/counter-cache_tests.js @@ -1,193 +1,128 @@ -var setup = function(test, options) { - var collections = { - authors: new Mongo.Collection('authors' + test.id), - books: new Mongo.Collection('books' + test.id) - } - - options = options || {target: {}, source: {}}; - _.defaults(options.target, { - collection: collections.authors, - counter: 'booksCount' - }); - _.defaults(options.source, { - collection: collections.books, - foreignKey: 'authorId' - }); - var bookCounter = new CounterCache(options); - - collections.books.mutate = { - insert: function(doc) { - bookCounter.insert(doc); - return collections.books.insert(doc); - }, - update: function(id, update) { - bookCounter.update(id, update); - return collections.books.update(id, update); - }, - remove: function(id) { - bookCounter.remove(id); - return collections.books.remove(id) - } - }; - - return collections; -} +Tinytest.add('Counter cache - foreignKey works', function(test) { + Authors = new Mongo.Collection('authors' + test.id); + Books = new Mongo.Collection('books' + test.id); + Authors.maintainCountOf(Books, 'authorId', 'booksCount'); -Tinytest.add('Counter cache - foreignKey works', function(test) { - var collections = setup(test); - - var authorId = collections.authors.insert({ + var authorId = Authors.insert({ name: 'Charles Darwin' }); - var bookId = collections.books.mutate.insert({ + var bookId = Books.insert({ name: 'On the Origin of Species', authorId: authorId }); - var author = collections.authors.findOne(authorId); + var author = Authors.findOne(authorId); // insert test.equal(author.booksCount, 1); - collections.books.mutate.remove(bookId); - author = collections.authors.findOne(authorId); + Books.remove(bookId); + author = Authors.findOne(authorId); // remove test.equal(author.booksCount, 0); // insert book again - bookId = collections.books.mutate.insert({ + bookId = Books.insert({ name: 'On the Origin of Species', authorId: authorId }); - author = collections.authors.findOne(authorId); + author = Authors.findOne(authorId); // we should be 1 again test.equal(author.booksCount, 1); - author2Id = collections.authors.insert({ + author2Id = Authors.insert({ name: 'Charles Darwin 2' }); // insert a book for a different author - book2Id = collections.books.mutate.insert({ + book2Id = Books.insert({ name: 'A test book', authorId: author2Id }); // this should not affect the first author count - author = collections.authors.findOne(authorId); + author = Authors.findOne(authorId); test.equal(author.booksCount, 1); - collections.books.mutate.remove(book2Id); + Books.remove(book2Id); // change this book to another author - collections.books.mutate.update(bookId, { $set: { authorId: author2Id }}); + Books.update(bookId, { $set: { authorId: author2Id }}); - author = collections.authors.findOne(authorId); + author = Authors.findOne(authorId); // book changed author test.equal(author.booksCount, 0); - var author2 = collections.authors.findOne(author2Id); + var author2 = Authors.findOne(author2Id); test.equal(author2.booksCount, 1); // set back to original author again - collections.books.mutate.update(bookId, { $set: { authorId: authorId }}); + Books.update(bookId, { $set: { authorId: authorId }}); - author2 = collections.authors.findOne(author2Id); + author2 = Authors.findOne(author2Id); test.equal(author2.booksCount, 0); - author = collections.authors.findOne(authorId); + author = Authors.findOne(authorId); test.equal(author.booksCount, 1); // remove authorId - collections.books.mutate.update(bookId, { $unset: { authorId: '' }}); + Books.update(bookId, { $unset: { authorId: '' }}); - author = collections.authors.findOne(authorId); + author = Authors.findOne(authorId); test.equal(author.booksCount, 0); // random update that doesn't include the authorId - collections.books.mutate.update(bookId, { $set: { nothing: true }}); + Books.update(bookId, { $set: { nothing: true }}); test.equal(author.booksCount, 0); // update with the same id - collections.books.mutate.update(bookId, { $set: { authorId: authorId }}); - collections.books.mutate.update(bookId, { $set: { authorId: authorId }}); - collections.books.mutate.update(bookId, { $set: { authorId: authorId }}); + Books.update(bookId, { $set: { authorId: authorId }}); + Books.update(bookId, { $set: { authorId: authorId }}); + Books.update(bookId, { $set: { authorId: authorId }}); - author = collections.authors.findOne(authorId); + author = Authors.findOne(authorId); test.equal(author.booksCount, 1); }); Tinytest.add('Counter cache - foreignKey lookup function', function(test) { - // this one's a bit different - var collections = { - publishers: new Mongo.Collection('publishers' + test.id), - authors: new Mongo.Collection('authors' + test.id), - books: new Mongo.Collection('books' + test.id) - } - - var bookCounter = new CounterCache({ - target: { - collection: collections.publishers, - counter: 'fictionBooksCount' - }, - source: { - collection: collections.books, - foreignKey: function(doc) { - return collections.authors.findOne(doc.authorId).publisherId; - }, - filter: function(doc) { return doc.isFiction; } - } - }); - - collections.books.mutate = { - insert: function(doc) { - bookCounter.insert(doc); - return collections.books.insert(doc); - }, - update: function(id, update) { - bookCounter.update(id, update); - return collections.books.update(id, update); - }, - remove: function(id) { - bookCounter.remove(id); - return collections.books.remove(id) - } - }; + Publishers = new Mongo.Collection('publishers' + test.id); + Publishers.maintainCountOf(Books, function(doc) { + return Authors.findOne(doc.authorId).publisherId; + }, 'booksCount'); - var publisherId = collections.publishers.insert({ - name: 'Good collections.books' + var publisherId = Publishers.insert({ + name: 'Good Books' }); - var publisher2Id = collections.publishers.insert({ - name: 'Gooder collections.books' + var publisher2Id = Publishers.insert({ + name: 'Gooder Books' }); - var authorId = collections.authors.insert({ + var authorId = Authors.insert({ name: 'Charles Darwin', publisherId: publisherId }); - var author2Id = collections.authors.insert({ + var author2Id = Authors.insert({ name: 'Charles Darwin 2', publisherId: publisher2Id }); - var bookId = collections.books.mutate.insert({ + var bookId = Books.insert({ name: 'On the Origin of Species', - authorId: authorId, - isFiction: true + authorId: authorId }); - var publisher = collections.publishers.findOne(publisherId); + var publisher = Publishers.findOne(publisherId); // insert - test.equal(publisher.fictionBooksCount, 1); + test.equal(publisher.booksCount, 1); // remove - collections.books.mutate.remove(bookId); + Books.remove(bookId); - publisher = collections.publishers.findOne(publisherId); + publisher = Publishers.findOne(publisherId); - test.equal(publisher.fictionBooksCount, 0); + test.equal(publisher.booksCount, 0); // TODO: Add tests like above @@ -195,111 +130,103 @@ Tinytest.add('Counter cache - foreignKey lookup function', function(test) { // Note: // If we remove an author, the publishers book count will not change to reflect this, - // in this case a before-remove collection-hook on collections.authors should be setup to remove - // all collections.books related to this author. + // in this case a before-remove collection-hook on Authors should be setup to remove + // all books related to this author. }); Tinytest.add('Counter cache - filter and foreignKey - add and remove', function(test) { - var collections = setup(test, { - target: { - counter: 'fictionBooksCount' - }, - source: { - filter: function(doc) { return doc.isFiction; } - } - }); - - var authorId = collections.authors.insert({ + Authors = new Mongo.Collection('authors' + test.id); + Books = new Mongo.Collection('books' + test.id); + var filter = function(doc) { return doc.isFiction; }; + Authors.maintainCountOf(Books, 'authorId', 'fictionBooksCount', filter); + + var authorId = Authors.insert({ name: 'Test Author' }); // Filter increments on insert - var book1Id = collections.books.mutate.insert({ + var book1Id = Books.insert({ name: 'How to test your book counters', authorId: authorId, isFiction: true }); - test.equal(collections.authors.findOne(authorId).fictionBooksCount, 1); + test.equal(Authors.findOne(authorId).fictionBooksCount, 1); // Filter shouldn't have incremented with this book - var book2Id = collections.books.mutate.insert({ + var book2Id = Books.insert({ name: 'How to test your book counters again', authorId: authorId, isFiction: false }); - test.equal(collections.authors.findOne(authorId).fictionBooksCount, 1); + test.equal(Authors.findOne(authorId).fictionBooksCount, 1); // filter decrements on delete - collections.books.mutate.remove(book1Id); - test.equal(collections.authors.findOne(authorId).fictionBooksCount, 0); + Books.remove(book1Id); + test.equal(Authors.findOne(authorId).fictionBooksCount, 0); // but not if it's false - collections.books.mutate.remove(book2Id); - test.equal(collections.authors.findOne(authorId).fictionBooksCount, 0); + Books.remove(book2Id); + test.equal(Authors.findOne(authorId).fictionBooksCount, 0); }); Tinytest.add('Counter cache - filter and foreignKey - changes', function(test) { - var collections = setup(test, { - target: { - counter: 'fictionBooksCount' - }, - source: { - filter: function(doc) { return doc.isFiction; } - } - }); + Authors = new Mongo.Collection('authors' + test.id); + Books = new Mongo.Collection('books' + test.id); + var filter = function(doc) { return doc.isFiction; }; + Authors.maintainCountOf(Books, 'authorId', 'fictionBooksCount', filter); - var author1Id = collections.authors.insert({ + var author1Id = Authors.insert({ name: 'Test Author', fictionBooksCount: 0 }); - var author2Id = collections.authors.insert({ + var author2Id = Authors.insert({ name: 'Test Author 2', fictionBooksCount: 0 }); - var bookId = collections.books.mutate.insert({ + var bookId = Books.insert({ name: 'How to test your book counters', authorId: author1Id, isFiction: true }); - test.equal(collections.authors.findOne(author1Id).fictionBooksCount, 1); + test.equal(Authors.findOne(author1Id).fictionBooksCount, 1); // 1. an irrelevant change - collections.books.mutate.update(bookId, {$set: {name: 'A new way to test'}}); - test.equal(collections.authors.findOne(author1Id).fictionBooksCount, 1); - test.equal(collections.authors.findOne(author2Id).fictionBooksCount, 0); + Books.update(bookId, {$set: {name: 'A new way to test'}}); + test.equal(Authors.findOne(author1Id).fictionBooksCount, 1); + test.equal(Authors.findOne(author2Id).fictionBooksCount, 0); // 2. change it to no longer match - collections.books.mutate.update(bookId, {$set: {isFiction: false}}); - test.equal(collections.authors.findOne(author1Id).fictionBooksCount, 0); - test.equal(collections.authors.findOne(author2Id).fictionBooksCount, 0); + Books.update(bookId, {$set: {isFiction: false}}); + test.equal(Authors.findOne(author1Id).fictionBooksCount, 0); + test.equal(Authors.findOne(author2Id).fictionBooksCount, 0); // 3. an irrelevant change - collections.books.mutate.update(bookId, {$set: {name: 'A new way to test again'}}); - test.equal(collections.authors.findOne(author1Id).fictionBooksCount, 0); - test.equal(collections.authors.findOne(author2Id).fictionBooksCount, 0); + Books.update(bookId, {$set: {name: 'A new way to test again'}}); + test.equal(Authors.findOne(author1Id).fictionBooksCount, 0); + test.equal(Authors.findOne(author2Id).fictionBooksCount, 0); // 4. change author without changing matching - collections.books.mutate.update(bookId, {$set: {authorId: author2Id}}); - test.equal(collections.authors.findOne(author1Id).fictionBooksCount, 0); - test.equal(collections.authors.findOne(author2Id).fictionBooksCount, 0); + Books.update(bookId, {$set: {authorId: author2Id}}); + test.equal(Authors.findOne(author1Id).fictionBooksCount, 0); + test.equal(Authors.findOne(author2Id).fictionBooksCount, 0); // 5. change to now match - collections.books.mutate.update(bookId, {$set: {isFiction: true}}); - test.equal(collections.authors.findOne(author1Id).fictionBooksCount, 0); - test.equal(collections.authors.findOne(author2Id).fictionBooksCount, 1); + Books.update(bookId, {$set: {isFiction: true}}); + test.equal(Authors.findOne(author1Id).fictionBooksCount, 0); + test.equal(Authors.findOne(author2Id).fictionBooksCount, 1); // 6. change author without changing matching - collections.books.mutate.update(bookId, {$set: {authorId: author1Id}}); - test.equal(collections.authors.findOne(author1Id).fictionBooksCount, 1); - test.equal(collections.authors.findOne(author2Id).fictionBooksCount, 0); + Books.update(bookId, {$set: {authorId: author1Id}}); + test.equal(Authors.findOne(author1Id).fictionBooksCount, 1); + test.equal(Authors.findOne(author2Id).fictionBooksCount, 0); // 7. change author while changing matching - collections.books.mutate.update(bookId, {$set: {authorId: author2Id, isFiction: false}}); - test.equal(collections.authors.findOne(author1Id).fictionBooksCount, 0); - test.equal(collections.authors.findOne(author2Id).fictionBooksCount, 0); + Books.update(bookId, {$set: {authorId: author2Id, isFiction: false}}); + test.equal(Authors.findOne(author1Id).fictionBooksCount, 0); + test.equal(Authors.findOne(author2Id).fictionBooksCount, 0); // 8. change author while changing matching - collections.books.mutate.update(bookId, {$set: {authorId: author1Id, isFiction: true}}); - test.equal(collections.authors.findOne(author1Id).fictionBooksCount, 1); - test.equal(collections.authors.findOne(author2Id).fictionBooksCount, 0); + Books.update(bookId, {$set: {authorId: author1Id, isFiction: true}}); + test.equal(Authors.findOne(author1Id).fictionBooksCount, 1); + test.equal(Authors.findOne(author2Id).fictionBooksCount, 0); }); \ No newline at end of file diff --git a/package.js b/package.js index 1334be4..baf2552 100644 --- a/package.js +++ b/package.js @@ -1,19 +1,16 @@ Package.describe({ - name: 'hazio:counter-cache', summary: "Cache the counts of an associated collection", - version: "0.0.3", - git: "https://github.com/hazio/meteor-counter-cache.git" + version: "0.2.2", + git: "https://github.com/percolatestudio/meteor-counter-cache.git" }); Package.onUse(function(api) { api.use([ - 'check@1.0.0', + 'matb33:collection-hooks@0.7.11', 'underscore@1.0.0', - 'mongo@1.0.6', - 'minimongo@1.0.10' + 'mongo@1.0.6' ]); api.add_files('counter-cache.js', ['client', 'server']); - api.export('CounterCache'); }); Package.onTest(function(api) { diff --git a/smart.json b/smart.json index ad62a2d..b5e44d0 100644 --- a/smart.json +++ b/smart.json @@ -1,8 +1,11 @@ { "name": "counter-cache", "description": "Cache the counts of an associated collection", - "homepage": "https://github.com/hazio/meteor-counter-cache", - "author": "Jani Halmetoja (http://twitter.com/halmetoja)", - "version": "0.0.3", - "git": "https://github.com/hazio/meteor-counter-cache.git" + "homepage": "https://github.com/percolatestudio/meteor-counter-cache", + "author": "David Burles (http://twitter.com/dburles)", + "version": "0.1.3", + "git": "https://github.com/percolatestudio/meteor-counter-cache.git", + "packages": { + "collection-hooks": "0.7.11" + } } From cbdb441f6e296f7066639846a5e40b0b4addde60 Mon Sep 17 00:00:00 2001 From: Jani Halmetoja Date: Thu, 15 Oct 2015 13:14:12 +0300 Subject: [PATCH 10/12] metadata --- .versions | 5 +++-- package.js | 4 ++-- smart.json | 8 ++++---- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.versions b/.versions index e093af8..9e2ceb6 100644 --- a/.versions +++ b/.versions @@ -18,14 +18,15 @@ ecmascript@0.1.5 ecmascript-collections@0.1.6 ejson@1.0.7 geojson-utils@1.0.4 -hazio:counter-cache@0.0.3 html-tools@1.0.5 htmljs@1.0.5 id-map@1.0.4 jquery@1.11.4 -local-test:hazio:counter-cache@0.0.3 +local-test:meteor-counter-cache@0.2.2 logging@1.0.8 +matb33:collection-hooks@0.7.15 meteor@1.1.9 +meteor-counter-cache@0.2.2 minimongo@1.0.10 mongo@1.1.2 mongo-id@1.0.1 diff --git a/package.js b/package.js index baf2552..2a0f136 100644 --- a/package.js +++ b/package.js @@ -1,7 +1,7 @@ Package.describe({ summary: "Cache the counts of an associated collection", - version: "0.2.2", - git: "https://github.com/percolatestudio/meteor-counter-cache.git" + version: "0.0.4", + git: "https://github.com/hazio/meteor-counter-cache.git" }); Package.onUse(function(api) { diff --git a/smart.json b/smart.json index b5e44d0..030a26e 100644 --- a/smart.json +++ b/smart.json @@ -1,10 +1,10 @@ { "name": "counter-cache", "description": "Cache the counts of an associated collection", - "homepage": "https://github.com/percolatestudio/meteor-counter-cache", - "author": "David Burles (http://twitter.com/dburles)", - "version": "0.1.3", - "git": "https://github.com/percolatestudio/meteor-counter-cache.git", + "homepage": "https://github.com/hazio/meteor-counter-cache", + "author": "Jani Halmetoja (http://twitter.com/halmetoja)", + "version": "0.0.4", + "git": "https://github.com/hazio/meteor-counter-cache.git", "packages": { "collection-hooks": "0.7.11" } From 312763acbdbf5e82b3851733083472f56b116ad7 Mon Sep 17 00:00:00 2001 From: Jani Halmetoja Date: Tue, 16 Aug 2016 09:55:08 +0300 Subject: [PATCH 11/12] updated package versions --- package.js | 11 ++++++----- smart.json | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/package.js b/package.js index 2a0f136..4246231 100644 --- a/package.js +++ b/package.js @@ -1,19 +1,20 @@ Package.describe({ summary: "Cache the counts of an associated collection", - version: "0.0.4", + version: "0.0.5", git: "https://github.com/hazio/meteor-counter-cache.git" }); Package.onUse(function(api) { api.use([ - 'matb33:collection-hooks@0.7.11', - 'underscore@1.0.0', - 'mongo@1.0.6' + 'matb33:collection-hooks@0.8.3', + 'underscore@1.8.3', + 'mongo@2.2.5' ]); api.add_files('counter-cache.js', ['client', 'server']); }); Package.onTest(function(api) { - api.use(['tinytest', 'dburles:counter-cache']); + api.use(['tinytest', 'underscore', 'mongo', 'matb33:collection-hooks@0.8.3']); api.add_files('counter-cache_tests.js', 'server'); + api.add_files('counter-cache.js', ['client', 'server']); }); diff --git a/smart.json b/smart.json index 030a26e..3d58189 100644 --- a/smart.json +++ b/smart.json @@ -3,9 +3,9 @@ "description": "Cache the counts of an associated collection", "homepage": "https://github.com/hazio/meteor-counter-cache", "author": "Jani Halmetoja (http://twitter.com/halmetoja)", - "version": "0.0.4", + "version": "0.0.5", "git": "https://github.com/hazio/meteor-counter-cache.git", "packages": { - "collection-hooks": "0.7.11" + "collection-hooks": "0.8.3" } } From d16a13b86c4441ad35d0734bc958d6dcfb6470d1 Mon Sep 17 00:00:00 2001 From: Jani Halmetoja Date: Tue, 16 Aug 2016 18:41:26 +0300 Subject: [PATCH 12/12] update packages --- .versions | 96 ++++++++++++++++++++++++++------------------------- package.js | 4 +-- packages.json | 1 + 3 files changed, 52 insertions(+), 49 deletions(-) create mode 100644 packages.json diff --git a/.versions b/.versions index 9e2ceb6..65c3c1e 100644 --- a/.versions +++ b/.versions @@ -1,48 +1,50 @@ -babel-compiler@5.8.24_1 -babel-runtime@0.1.4 -base64@1.0.4 -binary-heap@1.0.4 -blaze@2.1.3 -blaze-tools@1.0.4 -boilerplate-generator@1.0.4 -callback-hook@1.0.4 -check@1.0.6 -dburles:counter-cache@0.1.2 -ddp@1.2.2 -ddp-client@1.2.1 -ddp-common@1.2.1 -ddp-server@1.2.1 -deps@1.0.9 -diff-sequence@1.0.1 -ecmascript@0.1.5 -ecmascript-collections@0.1.6 -ejson@1.0.7 -geojson-utils@1.0.4 -html-tools@1.0.5 -htmljs@1.0.5 -id-map@1.0.4 -jquery@1.11.4 -local-test:meteor-counter-cache@0.2.2 -logging@1.0.8 -matb33:collection-hooks@0.7.15 -meteor@1.1.9 -meteor-counter-cache@0.2.2 -minimongo@1.0.10 -mongo@1.1.2 -mongo-id@1.0.1 -npm-mongo@1.4.39_1 -observe-sequence@1.0.7 -ordered-dict@1.0.4 -promise@0.5.0 -random@1.0.4 -reactive-var@1.0.6 -retry@1.0.4 -routepolicy@1.0.6 -spacebars@1.0.7 -spacebars-compiler@1.0.7 +allow-deny@1.0.5 +babel-compiler@6.8.5 +babel-runtime@0.1.9_1 +base64@1.0.9 +binary-heap@1.0.9 +blaze@2.1.8 +blaze-tools@1.0.9 +boilerplate-generator@1.0.9 +callback-hook@1.0.9 +check@1.2.3 +ddp@1.2.5 +ddp-client@1.2.5 +ddp-common@1.2.5 +ddp-server@1.2.6 +deps@1.0.12 +diff-sequence@1.0.6 +ecmascript@0.4.6_1 +ecmascript-runtime@0.2.12 +ejson@1.0.12 +geojson-utils@1.0.9 +hazio:counter-cache@0.0.5 +html-tools@1.0.10 +htmljs@1.0.10 +id-map@1.0.8 +jquery@1.11.9 +local-test:hazio:counter-cache@0.0.5 +logging@1.0.13_1 +matb33:collection-hooks@0.8.3 +meteor@1.1.16 +minimongo@1.0.17 +modules@0.6.5 +modules-runtime@0.6.5 +mongo@1.1.9_1 +mongo-id@1.0.5 +npm-mongo@1.4.44_1 +observe-sequence@1.0.12 +ordered-dict@1.0.8 +promise@0.7.3 +random@1.0.10 +reactive-var@1.0.10 +retry@1.0.7 +routepolicy@1.0.11 +spacebars@1.0.12 +spacebars-compiler@1.0.12 tinytest@1.0.6 -tracker@1.0.9 -ui@1.0.8 -underscore@1.0.4 -webapp@1.2.2 -webapp-hashing@1.0.5 +tracker@1.0.15 +ui@1.0.11 +underscore@1.0.9 +webapp@1.2.9_1 +webapp-hashing@1.0.9 diff --git a/package.js b/package.js index 4246231..309b1cb 100644 --- a/package.js +++ b/package.js @@ -7,8 +7,8 @@ Package.describe({ Package.onUse(function(api) { api.use([ 'matb33:collection-hooks@0.8.3', - 'underscore@1.8.3', - 'mongo@2.2.5' + 'underscore@1.0.9', + 'mongo@1.1.9_1' ]); api.add_files('counter-cache.js', ['client', 'server']); }); diff --git a/packages.json b/packages.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/packages.json @@ -0,0 +1 @@ +{}