-
Notifications
You must be signed in to change notification settings - Fork 120
stores
Store#find
Store#findOne
Store#count
Store#exists
Returns an array of models. The database is free to perform more fine-grained optimizations, such as making a collection.findOne
call in mongodb if there's only one id
we're searching by.
store.find { "id" : { "$in": [1, 2, 3] } }
store.find { "id" : { "$nin": [1, 2, 3] } }
store.find { "tags" : { "$all": ["ruby", "javascript"] } }
store.find { "tags" : { "$in": ["ruby", "javascript"] } }
store.find { "$or": [ { "tags" : { "$in": ["ruby", "javascript"] } }, { "id" : { "$in": [1, 2, 3] } } ] }
Each Tower.Store
method requires exact parameters (there's no argument overloading).
The store is used by the Tower.Model
internally.
Store#create
Store#update
Store#destroy
Creates one model.
store.create { "tags" : ["ruby", "javascript"] }
Updates any models matching the query.
store.update { "$set": { "tags" : ["ruby", "javascript"] } }, { "id" : { "$in": [1, 2, 3] } }
Deletes any models matching the query.
store.destroy { "id" : { "$in": [1, 2, 3] } }
store.find { "status" : "active" }
store.find { "status" : "$eq" : "active" }
store.find { "status" : "$ne" : "inactive" }
store.find { "likeCount" : ">=" : 10 }
store.find { "likeCount" : "$gte" : 10 }
store.find { "tags" : { "$all" : ["ruby", "javascript"] } }
store.find { "tags" : { "$in" : ["ruby", "javascript"] } }
store.find { "tags" : { "$nin" : ["java", "asp"] } }
store.find { "name" : /acme.*corp/i }
store.find { "name" : /acme.*corp/i }
store.find { "$or": [ { "likeCount" : 1000 }, { "likeCount" : { "$gte": 1, "$lte": 100 } } ] }
store.find { "$nor": [ { "likeCount" : 1000 }, { "likeCount" : { "$gte": 1, "$lte": 100 } } ] }
store.find { "$and" : [ { "a" : 1 }, { "a" : { $gt: 5 } } ] }
store.find { "tags" : { "$in" : ["ruby", "javascript"] }, "sort": [["title", "asc"]] }
store.find { "tags" : { "$in" : ["ruby", "javascript"] }, "limit": 20 }
store.find { "tags" : { "$in" : ["ruby", "javascript"] }, "offset": 10 }
The memory story stores all the records in a JavaScript object. It can perform all the same advanced queries as Tower.Store.MongoDB
, making it really easy to reuse server-side model code on the client.
- http://mongodb.github.com/node-mongodb-native/
- http://mobile.eweek.com/c/a/Application-Development/MongoDB-Native-Driver-for-Nodejs-Speeds-Up-Results-176150/
This is the Tower adapter to Neo4j, an awesome graph database. Neo4j has several features that the other databases don't have.
Tower models have something like database transactions.
On the client, there is one global transaction. By default, this transaction commits every time you create/save/update/destroy a record. You can set Tower.Store.Transaction.commitInterval = n
to some n
millisecond value, and it will make sure the transaction is committed every n
milliseconds. If it's 0
, it will commit automatically. You can also set it to null
and it will never commit, you have to manually call Tower.Store.instance().commit()
.
On the server, there is no global transaction; that would create a huge memory management problem. Instead, every create/save/update/destroy creates its own transaction and automatically commits. If you want group multiple operations into a single transaction, you can do that like this:
class App.TransactionsController extends Tower.Controller
create: ->
Tower.Store.transaction (transaction) =>
user = App.User.with(transaction).create()
post = App.Post.with(transaction).create()
transaction.commit (error) =>
if error
@render json: success: "All operations saved"
else
@render json: failure: error.message
The model instances themselves will always show their new/updated attribute values, but they won't necessarily get their id
immediately due to the async database operations.
App.User.where(firstName: "Lance").create()
cursor.create() # pass in transaction if cursor had transaction
record.save()
transaction.create()
if transaction.autocommit
store.create()
user = new App.User
user.save()
transaction.create()
store.create()
App.User.create({}, {}, {})
cursor.create()
for record in records
record.save()
transaction.create()
store.create()
App.User.transaction().create({}, {}, {})
cursor.create()
for record in records
record.save()
transaction.create()
transaction.commit()
store.create()
scope.all
returns a cursor, so if you want the records you have to add a callback scope.all (error, records)
. This makes it so you can do both/or: get the records or set up a binding to that record set.
# this returns a cursor that acts like an array of records.
App.usersByFirstName = App.User.asc("firstName").limit(20).all()
# this returns a cursor that acts as an individual record.
# this way you can have something like a "featured post"
# that will automatically update. Maybe we don't want to do this.
App.topPost = App.Post.desc("likes").first()
<ul>
{{#each App.usersByFirstName}}
<li>{{fullName}}</li>
{{/each}}
</ul>
Ideally you'd be able to not have to call all
, so you could do this:
class App.User extends Tower.Model
@field "firstName"
@scope "byFirstName", @asc("firstName").limit(20)
<ul>
{{#each App.User.byFirstName}}
<li>{{fullName}}</li>
{{/each}}
</ul>
Since the >=
is a Date
, Tower will generate a callback which will update the query with the latest records. By default it will update it every 5 seconds, but you can change this.
App.latestCheckins = App.Checkin.where(createdAt: ">=": _(1).minute().ago()).all()
App.Checkin.create()
# wait 0:50
App.Checkin.create()
# wait 0:11, 1 checkin disappears.
<ul>
{{#each App.lastCheckins}}
<li>{{user.name}} checked into {{place.name}} at {{createdAtAgo}}</li>
{{/each}}
</ul>
- If
Date
, refresh every x interval.
currentLocation = [40.741404, -73.988135]
App.closestDeals = App.Deal.near(currentLocation).within(1, "mile").all()
<ul>
{{#each App.closestDeals}}
<li>{{description}}</li>
{{/each}}
</ul>
That currentLocation
will be a bindable array, which when updated will update the scope, so the deals always reflect the ones closest the current location!
- If location, refresh if location changes
- If array, refresh if array changes.
Potential idea!
ul ->
each "App.closestDeals", ->
li "{{description}}"