/**
 * Model loader
 */
import debug from 'debug'
import redis from 'redis'
import Redlock from 'redlock'
import RethinkDB from 'rethinkdbdash'
import * as config from 'bshed/config'
const log = debug('server:models')

import Bikeshed from './bikeshed'
import User from './user'
import Vote from './vote'

export const MODELS = {
  Bikeshed,
  User,
  Vote
}

export const TABLES = Object.values(MODELS).map(model => model.TABLE)

export const INDEXES = Object.entries(MODELS).reduce((indexes, [modelName, model]) => {
  indexes[model.TABLE] = model.INDEXES
  return indexes
}, {})

// Given a rethinkdbdash and redlock instance, instantiate each model
export function createModels ({ r, redlock }) {
  log('creating models')
  return Object.entries(MODELS).reduce((instances, [name, createModel]) => {
    log(`creating "${name}"`)
    instances[name] = createModel({ r, redlock })
    return instances
  }, { r, redlock })
}

// Get self-initialized model instances
export function getModels () {
  log('initializing rethinkdb')
  const r = new RethinkDB(config.rethinkdb)

  log('initializing redlock')
  const redlock = new Redlock([
    redis.createClient(config.redis)
  ])

  return createModels({ r, redlock })
}

@@ -54,25 +54,29 @@
 ort 
+c
 re
-dis
+ateKnex
  from '
-redis
+knex
 '%0Aim
@@ -84,107 +84,87 @@
 ort 
-Redlock from 'redlock'%0Aimport RethinkDB from 'rethinkdbdash'%0Aimport * as config from 'bshed/config'
+createBookshelf from 'bookshelf'%0Aimport %7B camelCase, snakeCase %7D from 'lodash'%0A
 %0Acon
@@ -196,16 +196,42 @@
 dels')%0A%0A
+import Bike from './bike'%0A
 import B
@@ -309,23 +309,16 @@
 /vote'%0A%0A
-export 
 const MO
@@ -326,16 +326,24 @@
 ELS = %7B%0A
+  Bike,%0A
   Bikesh
@@ -375,94 +375,207 @@
 ort 
-const TABLES = Object.values(MODELS).map(mod
+default function createModels (%7B database %7D) %7B%0A  const knex = createKnex(database)%0A  const booksh
 el
+f
  =
-%3E model.TABLE)%0A%0Aexport const INDEXES =
+ createBookshelf(knex)%0A%0A  bookshelf.plugin('virtuals')%0A  bookshelf.plugin(camelizeKeys)%0A%0A  return
  Obj
@@ -585,32 +585,35 @@
 .entries(MODELS)
+%0A  
 .reduce((indexes
@@ -609,738 +609,844 @@
 ce((
-indexes, %5BmodelName, model%5D) =%3E %7B%0A  indexes%5Bmodel.TABLE%5D = model.INDEXES%0A  return indexes%0A%7D, %7B%7D)%0A%0A// Given a rethinkdbdash and redlock instance, instantiate each model%0Aexport function createModels (%7B r, redlock %7D) %7B%0A  log('creating models')%0A  return Object.entries(MODELS).reduce((instances, %5Bname, createModel%5D) =%3E %7B%0A    log(%60creating %22$%7Bname%7D%22%60)%0A    instances%5Bn
+models, %5Bname, createModel%5D) =%3E %7B%0A    log(%60creating %22$%7Bname%7D%22%60)%0A    models%5Bname%5D = createModel(models)%0A    return models%0A  %7D, %7B%0A    bookshelf,%0A    knex%0A  %7D)%0A%7D%0A%0A/**%0A * Convert attributes to camelCase when they come out%0A * and to snake_case when they go in%0A */%0Afunction camelizeKeys (bookshelf) %7B%0A  bookshelf.Model = bookshelf.Model.extend(%7B%0A    // Convert attributes to camelCase when they come out%0A    parse (attrs) %7B%0A      return Object.entries(attrs)%0A      .reduce((attrs, %5BattrName, attrValue%5D) =%3E %7B%0A        attrs%5BcamelCase(attrN
 ame
+)
 %5D = 
-createModel(%7B r, redlock %7D)%0A    return instances%0A  %7D, %7B r, redlock %7D)%0A%7D%0A%0A// Get self-initialized model instances%0Aexport function getModels () %7B%0A  log('initializing rethinkdb')%0A  const r = new RethinkDB(config.rethinkdb)%0A%0A  log('initializing redlock')%0A  const redlock = new Redlock(%5B%0A    redis.createClient(config.redis)%0A  %5D)%0A%0A  return createModels(%7B r, redlock
+attrValue%0A        return attrs%0A      %7D, %7B%7D)%0A    %7D,%0A%0A    // Convert keys to snake_case when they go in%0A    format (attrs) %7B%0A      return Object.entries(attrs)%0A      .reduce((attrs, %5BattrName, attrValue%5D) =%3E %7B%0A        attrs%5BsnakeCase(attrName)%5D = attrValue%0A        return attrs%0A      %7D, %7B%7D)%0A    %7D%0A 
  %7D)%0A

Update model creator