<commit_before>import Promise from 'bluebird'
import moment from 'moment'

import coreTables from './core_tables'
import kvs from './kvs'

const initializeCoreDatabase = knex => {
  if (!knex) {
    throw new Error('You must initialize the database before')
  }

  return Promise.mapSeries(coreTables, fn => fn(knex))
}

module.exports = ({ sqlite, postgres }) => {

  let knex = null

  const getDb = () => {
    if (knex) {
      return Promise.resolve(knex)
    }

    if (postgres.enabled) {
      knex = require('knex')({
        client: 'pg',
        connection: {
          host: postgres.host,
          port: postgres.port,
          user: postgres.user,
          password: <PASSWORD>,
          database: postgres.database,
          ssl: postgres.ssl
        },
        useNullAsDefault: true
      })
    } else {
      knex = require('knex')({
        client: 'sqlite3',
        connection: { filename: sqlite.location },
        useNullAsDefault: true
      })
    }

    return initializeCoreDatabase(knex)
    .then(() => knex)
  }

  const saveUser = ({ id, platform, gender, timezone, locale, picture_url, first_name, last_name }) => {
    const userId = platform + ':' + id
    const userRow = {
      id: userId,
      userId: id,
      platform: platform,
      gender: gender || 'unknown',
      timezone: timezone || null,
      locale: locale || null,
      created_on: moment(new Date()).toISOString(),
      picture_url: picture_url,
      last_name: last_name,
      first_name: first_name
    }

    return getDb()
    .then(knex => {
      var query = knex('users').insert(userRow)
      .where(function() {
        return this
          .select(knex.raw(1))
          .from('users')
          .where('id', '=', userId)
      })

      if (postgres.enabled) {
        query = `${query} on conflict (id) do nothing`
      } else { // SQLite
        query = query.toString().replace(/^insert/i, 'insert or ignore')
      }

      return knex.raw(query)
    })
  }

  let kvs_instance = null
  const getKvs = () => {
    if (!kvs_instance) {
      return getDb()
      .then(knex => {
        kvs_instance = new kvs(knex)
        return kvs_instance.bootstrap()
        .then(() => kvs_instance)
      })
    } else {
      return Promise.resolve(kvs_instance)
    }
  }

  const kvsGet = function() {
    const args = arguments
    return getKvs()
    .then(instance => instance.get.apply(null, args))
  }

  const kvsSet = function() {
    const args = arguments
    return getKvs()
    .then(instance => instance.set.apply(null, args))
  }

  return {
    get: getDb,
    saveUser,
    location: postgres.enabled ? 'postgres' : sqlite.location,
    kvs: { get: kvsGet, set: kvsSet }
  }
}
<commit_msg>Added support for postgres connection strings<commit_after>import Promise from 'bluebird'
import moment from 'moment'

import coreTables from './core_tables'
import kvs from './kvs'

const initializeCoreDatabase = knex => {
  if (!knex) {
    throw new Error('You must initialize the database before')
  }

  return Promise.mapSeries(coreTables, fn => fn(knex))
}

module.exports = ({ sqlite, postgres }) => {

  let knex = null

  const getDb = () => {
    if (knex) {
      return Promise.resolve(knex)
    }

    if (postgres.enabled) {

      // If we're passing in a postgres connection string, 
      // use that instead of the other params
      if (postgres.connection) {
        knex = require('knex')({
          client: 'pg',
          connection: postgres.connection,
          useNullAsDefault: true
        })
      } else {
        knex = require('knex')({
          client: 'pg',
          connection: {
            host: postgres.host,
            port: postgres.port,
            user: postgres.user,
            password: <PASSWORD>,
            database: postgres.database,
            ssl: postgres.ssl
          },
          useNullAsDefault: true
        })
      }
      
    } else {
      knex = require('knex')({
        client: 'sqlite3',
        connection: { filename: sqlite.location },
        useNullAsDefault: true
      })
    }

    return initializeCoreDatabase(knex)
    .then(() => knex)
  }

  const saveUser = ({ id, platform, gender, timezone, locale, picture_url, first_name, last_name }) => {
    const userId = platform + ':' + id
    const userRow = {
      id: userId,
      userId: id,
      platform: platform,
      gender: gender || 'unknown',
      timezone: timezone || null,
      locale: locale || null,
      created_on: moment(new Date()).toISOString(),
      picture_url: picture_url,
      last_name: last_name,
      first_name: first_name
    }

    return getDb()
    .then(knex => {
      var query = knex('users').insert(userRow)
      .where(function() {
        return this
          .select(knex.raw(1))
          .from('users')
          .where('id', '=', userId)
      })

      if (postgres.enabled) {
        query = `${query} on conflict (id) do nothing`
      } else { // SQLite
        query = query.toString().replace(/^insert/i, 'insert or ignore')
      }

      return knex.raw(query)
    })
  }

  let kvs_instance = null
  const getKvs = () => {
    if (!kvs_instance) {
      return getDb()
      .then(knex => {
        kvs_instance = new kvs(knex)
        return kvs_instance.bootstrap()
        .then(() => kvs_instance)
      })
    } else {
      return Promise.resolve(kvs_instance)
    }
  }

  const kvsGet = function() {
    const args = arguments
    return getKvs()
    .then(instance => instance.get.apply(null, args))
  }

  const kvsSet = function() {
    const args = arguments
    return getKvs()
    .then(instance => instance.set.apply(null, args))
  }

  return {
    get: getDb,
    saveUser,
    location: postgres.enabled ? 'postgres' : sqlite.location,
    kvs: { get: kvsGet, set: kvsSet }
  }
}

{'fraction_non_alphanumeric': 0.1310013717421125, 'fraction_numerical': 0.0006858710562414266, 'mean_word_length': 2.137708445400753, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3475745', 'n_tokens_mistral': 1842, 'n_tokens_neox': 1819, 'n_words': 443}