github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-supply-chain-master/ledger_sync/db/index.js (about)

     1  /**
     2   * Copyright 2018 Intel Corporation
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   * ----------------------------------------------------------------------------
    16   */
    17  'use strict'
    18  
    19  const r = require('rethinkdb')
    20  const config = require('../system/config')
    21  
    22  const HOST = config.DB_HOST
    23  const PORT = config.DB_PORT
    24  const NAME = config.DB_NAME
    25  const RETRY_WAIT = config.RETRY_WAIT
    26  const AWAIT_TABLE = 'blocks'
    27  
    28  // Connection to db for query methods, run connect before querying
    29  let connection = null
    30  
    31  const promisedTimeout = (fn, wait) => {
    32    return new Promise(resolve => setTimeout(resolve, wait)).then(fn);
    33  }
    34  
    35  const awaitDatabase = () => {
    36    return r.tableList().run(connection)
    37      .then(tableNames => {
    38        if (!tableNames.includes(AWAIT_TABLE)) {
    39          throw new Error()
    40        }
    41        console.log('Successfully connected to database:', NAME)
    42      })
    43      .catch(() => {
    44        console.warn('Database not initialized:', NAME)
    45        console.warn(`Retrying database in ${RETRY_WAIT / 1000} seconds...`)
    46        return promisedTimeout(awaitDatabase, RETRY_WAIT)
    47      })
    48  }
    49  
    50  const connect = () => {
    51    return r.connect({host: HOST, port: PORT, db: NAME})
    52      .then(conn => {
    53        connection = conn
    54        return awaitDatabase()
    55      })
    56      .catch(err => {
    57        if (err instanceof r.Error.ReqlDriverError) {
    58          console.warn('Unable to connect to RethinkDB')
    59          console.warn(`Retrying in ${RETRY_WAIT / 1000} seconds...`)
    60          return promisedTimeout(connect, RETRY_WAIT)
    61        }
    62        throw err
    63      })
    64  }
    65  
    66  // Runs a specified query against a database table
    67  const queryTable = (table, query, removeCursor = true) => {
    68    return query(r.table(table))
    69      .run(connection)
    70      .then(cursor => removeCursor ? cursor.toArray() : cursor)
    71      .catch(err => {
    72        console.error(`Unable to query "${table}" table!`)
    73        console.error(err.message)
    74        throw new Error(err.message)
    75      })
    76  }
    77  
    78  // Use for queries that modify a table, turns error messages into errors
    79  const modifyTable = (table, query) => {
    80    return queryTable(table, query, false)
    81      .then(results => {
    82        if (!results) {
    83          throw new Error(`Unknown error while attempting to modify "${table}"`)
    84        }
    85        if (results.errors > 0) {
    86          throw new Error(results.first_error)
    87        }
    88        return results
    89      })
    90  }
    91  
    92  module.exports = {
    93    connect,
    94    queryTable,
    95    modifyTable
    96  }