Skip to content

Structure Sync

dawnniie edited this page Jul 23, 2024 · 2 revisions

Since rethinkdb-ts-extra already needs to know your database/table layouts and indexes ('structures'), it makes a lot of sense to use this information to automatically keep things up to date. The 'sync' feature allows you to make sure your actual database is up-to-date with what you have specified in your configuration, without any need for writing migrations (this way, migrations are only for the actual data itself).

Note: this might be obvious, but 'syncing' does nothing to the data inside tables. Just the creation of databases, tables, and indexes.

Usage

const r = await extra(...)

await r.extra.sync({ log: 'actions' })

By default, sync will diff the existing database layout with your configuration, and create missing databases/tables/indexes where necessary. Any actions that it performs will be returned in an actions property on the output, and in this example with the log option they will also be logged.

Default behaviour for safety is to never delete anything. If you like living life on the edge, there are three options you can toggle on: dropUnknownDatabases, dropUnknownTables and dropUnknownIndexes. Indexes is generally okay because it's not destructive, but I really recommend against the other two.

You can also set log to 'verbose', which is guaranteed to log stuff whenever sync runs (as opposed to 'actions', which won't log anything if no actions are performed).

Auto Sync

If you happen to be using auto connection, you can also 'auto sync' by passing the same sync options to the extra function itself as a third argument. This will do all of your syncing in the exact same way straight after connecting, and only resolve the extra function once that is all complete (including waiting for indexes).

You can also just pass true for the third argument to use all defaults.

const r = await extra(
  { ... },
  { url: process.env.RETHINKDB_URL },
  { log: 'actions', dropUnknownIndexes: true }
)

Memory

You can get a slight performance boost by filling out the memory options. This will save a hash of the previous configuration somewhere in your database (that you specify), and compare that to the current hash before bothering to diff anything. If the hashes match, any syncing will be immediately skipped (and the skipped property on return will be set to true).

Warning: this means syncing (after the first time) will only happen whenever you change the configuration in code. The downside is that if you go in to your database and delete a table manually, it probably won't be automatically recreated when syncing runs next. You should keep this in mind if you use the memory options.

The memory options require a db, table, and id for a document in that location to store the previous sync hash in. That document will look like { id, h } with the relevant types. There are also options for a custom hashGenerator (we default to JSON.stringify -> SHA1 -> hex) and a custom hashComparison, which are probably entirely unnecessary, but why not!

await r.extra.sync({
  memory: { db: 'my_database', table: 'sync', id: 'sync' },
  log: 'verbose'
})

Clone this wiki locally