github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-supply-chain-master/ledger_sync/db/state.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 _ = require('lodash')
    20  const r = require('rethinkdb')
    21  const db = require('./')
    22  
    23  
    24  const valueNames = {
    25    BYTES: 'bytesValue',
    26    BOOLEAN: 'booleanValue',
    27    NUMBER: 'numberValue',
    28    STRING: 'stringValue',
    29    ENUM: 'enumValue',
    30    LOCATION: 'locationValue'
    31  }
    32  
    33  const xformStruct = properties => {
    34    return _.fromPairs(properties.map(property => {
    35      const value = property.dataType === 'STRUCT'
    36        ? xformStruct(property.structValues)
    37        : property[ valueNames[property.dataType] ]
    38      return [property.name, value]
    39    }))
    40  }
    41  
    42  const addBlockState = (tableName, indexName, indexValue, doc, blockNum) => {
    43    return db.modifyTable(tableName, table => {
    44      return table
    45        .getAll(indexValue, { index: indexName })
    46        .filter({ endBlockNum: Number.MAX_SAFE_INTEGER })
    47        .coerceTo('array')
    48        .do(oldDocs => {
    49          return oldDocs
    50            .filter({ startBlockNum: blockNum })
    51            .coerceTo('array')
    52            .do(duplicates => {
    53              return r.branch(
    54                // If there are duplicates, do nothing
    55                duplicates.count().gt(0),
    56                duplicates,
    57  
    58                // Otherwise, update the end block on any old docs,
    59                // and insert the new one
    60                table
    61                  .getAll(indexValue, { index: indexName })
    62                  .update({ endBlockNum: blockNum })
    63                  .do(() => {
    64                    return table.insert(_.assign({}, doc, {
    65                      startBlockNum: blockNum,
    66                      endBlockNum: Number.MAX_SAFE_INTEGER
    67                    }))
    68                  })
    69              )
    70            })
    71        })
    72    })
    73  }
    74  
    75  const addAgent = (agent, blockNum) => {
    76    return addBlockState('agents', 'publicKey', agent.publicKey,
    77                         agent, blockNum)
    78  }
    79  
    80  const addRecord = (record, blockNum) => {
    81    return addBlockState('records', 'recordId', record.recordId,
    82                         record, blockNum)
    83  }
    84  
    85  const addRecordType = (type, blockNum) => {
    86    return addBlockState('recordTypes', 'name', type.name,
    87                         type, blockNum)
    88  }
    89  
    90  const addProperty = (property, blockNum) => {
    91    return addBlockState('properties', 'attributes',
    92                         ['name', 'recordId'].map(k => property[k]),
    93                         property, blockNum)
    94  }
    95  
    96  const addPropertyPage = (page, blockNum) => {
    97    return db.queryTable('properties', properties => {
    98      return properties
    99        .getAll([page.name, page.recordId], { index: 'attributes' })
   100        .filter({ endBlockNum: Number.MAX_SAFE_INTEGER })
   101    })
   102      .then(properties => {
   103        if (properties.length === 0) {
   104          const attrs = `${page.name}, ${page.recordId}`
   105          return console.warn("WARNING! Unable to find page's Property:", attrs)
   106        }
   107  
   108        const property = properties[0]
   109  
   110        // Convert enum indexes into names, or empty strings if not an enum
   111        if (property.dataType === 'ENUM') {
   112          page.reportedValues.forEach(reported => {
   113            reported.enumValue = property.enumOptions[reported.enumValue]
   114          })
   115        } else {
   116          page.reportedValues.forEach(reported => {
   117            reported.enumValue = ''
   118          })
   119        }
   120  
   121        // Convert `structValues` array into `structValue` object
   122        if (property.dataType === 'STRUCT') {
   123          page.reportedValues.forEach(reported => {
   124            reported.structValue = xformStruct(reported.structValues)
   125            delete reported.structValues
   126          })
   127        } else {
   128          page.reportedValues.forEach(reported => {
   129            reported.structValue = {}
   130            delete reported.structValues
   131          })
   132        }
   133  
   134      })
   135      .then(() => {
   136        return addBlockState('propertyPages', 'attributes',
   137                             ['name', 'recordId', 'pageNum'].map(k => page[k]),
   138                             page, blockNum)
   139      })
   140  }
   141  
   142  const addProposal = (proposal, blockNum) => {
   143    return addBlockState(
   144      'proposals', 'attributes',
   145      ['recordId', 'timestamp', 'receivingAgent', 'role'].map(k => proposal[k]),
   146      proposal, blockNum)
   147  }
   148  
   149  module.exports = {
   150    addAgent,
   151    addRecord,
   152    addRecordType,
   153    addProperty,
   154    addPropertyPage,
   155    addProposal
   156  }