Changelog History
-
v2.8 Changes
December 14, 2018- โ added
record.update(data)
- โ added
record.isNewRecord
- โ added
-
v2.5 Changes
October 11, 2018It's now possible to create custom relations
e.g.// models/User.jsthis.has('has\_posts\_written', { query: function(store, parentRecords){ const ids = parentRecords.map(r =\> r.id) const Post = store.Model('Post') // query all posts by user\_id, group by user\_id and count(distinct(id))return Post.totalCount().group('user\_id').where({user\_id: ids}) }, convert: function(parent, records){ if(!records) return false// records =\> [{user\_id: 1, count: 4}, {user\_id: 2, count: 1}]// == the result of the above query!const result = records.find(r =\> r.user\_id === parent.id) if(!result) return falsereturn result.count \> 0 } })
A custom relation could return anything. In the example above it'll return a boolean value.
Works with
include()
like any other relation:
User.include('has_posts_written')
-
v2.4
October 03, 2018 -
v2.3
October 03, 2018 -
v2.2 Changes
August 29, 2018๐ The postgres store now supports all geometric data types.
There are also two new store options
externalAttributeName
andinternalAttributeName
for all stores.
Both options are optional and expect a method in the form offunction(fieldName: string): string
With
externalAttributeName
you can convert your internal database field names into another format. e.g. from snake_case to camelCase. The conversion is up to you!
internalAttributeName
should handle the opposite way. -
v2.1.0
August 21, 2018 -
v2.0.0 Changes
April 18, 2018๐ Version 2.0 - whats new?
Bulk loading
Relations got rewritten with optional bulk loading:
const user = await User.limit(3)const posts = await Promise.all(users.map(user =\> user.posts))
๐ will only execute 2 queries! To disable bulk loading see bulkFetch.
๐ However, in this case it's better to useconst user = await User.include('posts').limit(3)
Faster preloading
include was rewritten to load relations in parallel, if possible (SQL only!)
const users = await User.find(1).include('posts')/\* will execute `SELECT * FROM users WHERE id=1` and `SELECT * FROM posts WHERE user_id = 1` in parallel\*/
In V1 the above example would have loaded the data in series.
Of course this is only possible if the conditions for the first query will contain all information needed to execute the second query!
Model autoload (SQL only)
Similar to autoloading model attributes, it's now possible to autoload models.
const Store = require('openrecord/store/sqlite3')const store = new Store({ file: './my-posts-db.sqlite3', autoLoad: true // enable autoload})store.ready(async () =\> { const post = await store.Model('Post').find(1) // Post model is automatically available, if a table `posts` is defined in the sqlite3 database before.console.log(post) })
Classes
Defining a model via ES6 classes is now possible
class User extends Store.BaseModel{ fullName(){ return `${this.first\_name} ${this.last\_name}` } }
GraphQL
๐ Support for GraphQL with automatic relation loading and more.
Webpack
It's now possible to bundle your store via webpack (Version 3 and 4)
๐ There is also a Webpack Plugin to cache your data structure inside your bundle. (Faster startup for serverless apps)Custom operators
๐ It's now possible to define custom operators and use the whole power of knex
// the new operator is called `regexp`store.addOperator('regexp', function(field, value, query, condition){ query.where(field, '~', value.toString().replace(/(^\/|\/$)/g, '')) // naiv conversion of js regexp to postgres regexp!})// and it will be appended to the `string` typestore.appendOperator('string', 'regexp')
Query via:
const user = await User.where({login\_regexp: /open.\*/})
Everything Promise!
๐ฆ The whole core was rewritten to use Promises instead of async.
๐ Docs
๐ Docs are now available via https://openrecord.js.org
๐ฅ Breaking Changes to V1
- ๐
plugins
andmodels
store config does not take paths anymore. To get the old behavior back, use the automatic model loading plugin - ๐
paranoid
plugin scope to get all records was renamed towithDeleted
instead ofwith_deleted
- 0๏ธโฃ
join()
does an inner join by default (instead of a left join) - Failed validations will now throw an error! Therefore
save
,delete
,create
,... won't returnsuccess
anymore. Instead it will return the record on success - ๐ Hooks must return a promise or undefined. The
done
callback was removed. create
,save
,destroy
, ... won't take callbacks any more. use e.g.record.save().then(callback)
- Relation records wont be saved anymore. except you set autoSave to
true
(store or per relation) - Accessing a relation via e.g.
user.posts
will return a then-able object. To access loaded data directly useuser._posts
(Will return null if not loaded) limit(1)
does not return a single record anymore. Usefirst()
orsingleRecord()
insteadlogger
option on store is no longer available. openrecord now uses thedebug
module- โฌ๏ธ Drop support for NodeJS lower version 4
- ๐
-
v1.12 Changes
July 17, 2017I've added the ability to run raw joins via
.join('JOIN foo ON...')
or via.join(['JOIN foo ON foo.id=? ...', ['bar']])
-
v1.11.0 Changes
June 03, 2017Thanks to @arthurfranca
-
v1.10.16 Changes
March 10, 2017๐ Some small bugfixes, dependency upgrades and license change to MIT