github.com/igggame/nebulas-go@v2.1.0+incompatible/nf/nvm/v8/lib/1.0.0/storage.js (about)

     1  // Copyright (C) 2017 go-nebulas authors
     2  //
     3  // This file is part of the go-nebulas library.
     4  //
     5  // the go-nebulas library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // the go-nebulas library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU General Public License
    16  // along with the go-nebulas library.  If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  
    19  'use strict';
    20  
    21  var fieldNameRe = /^[a-zA-Z_$][a-zA-Z0-9_]+$/;
    22  
    23  var combineStorageMapKey = function (fieldName, key) {
    24      return "@" + fieldName + "[" + key + "]";
    25  };
    26  
    27  var applyMapDescriptor = function (obj, descriptor) {
    28      descriptor = Object.assign({
    29          stringify: JSON.stringify,
    30          parse: JSON.parse
    31      }, descriptor || {});
    32  
    33      if (typeof descriptor.stringify !== 'function' || typeof descriptor.parse !== 'function') {
    34          throw new Error("descriptor.stringify and descriptor.parse must be function.");
    35      }
    36  
    37      Object.defineProperty(obj, "stringify", {
    38          configurable: false,
    39          enumerable: false,
    40          get: function () {
    41              return descriptor.stringify;
    42          }
    43      });
    44  
    45      Object.defineProperty(obj, "parse", {
    46          configurable: false,
    47          enumerable: false,
    48          get: function () {
    49              return descriptor.parse;
    50          }
    51      });
    52  };
    53  
    54  var applyFieldDescriptor = function (obj, fieldName, descriptor) {
    55      descriptor = Object.assign({
    56          stringify: JSON.stringify,
    57          parse: JSON.parse
    58      }, descriptor || {});
    59  
    60      if (typeof descriptor.stringify !== 'function' || typeof descriptor.parse !== 'function') {
    61          throw new Error("descriptor.stringify and descriptor.parse must be function.");
    62      }
    63  
    64      Object.defineProperty(obj, "__stringify__" + fieldName, {
    65          configurable: false,
    66          enumerable: false,
    67          get: function () {
    68              return descriptor.stringify;
    69          }
    70      });
    71  
    72      Object.defineProperty(obj, "__parse__" + fieldName, {
    73          configurable: false,
    74          enumerable: false,
    75          get: function () {
    76              return descriptor.parse;
    77          }
    78      });
    79  };
    80  
    81  var ContractStorage = function (handler) {
    82      var ns = new NativeStorage(handler);
    83      Object.defineProperty(this, "nativeStorage", {
    84          configurable: false,
    85          enumerable: false,
    86          get: function () {
    87              return ns;
    88          }
    89      });
    90  };
    91  
    92  var StorageMap = function (contractStorage, fieldName, descriptor) {
    93      if (!contractStorage instanceof ContractStorage) {
    94          throw new Error("StorageMap only accept instance of ContractStorage");
    95      }
    96  
    97      if (typeof fieldName !== "string" || fieldNameRe.exec(fieldName) == null) {
    98          throw new Error("StorageMap fieldName must match regex /^[a-zA-Z_$].*$/");
    99      }
   100  
   101      Object.defineProperty(this, "contractStorage", {
   102          configurable: false,
   103          enumerable: false,
   104          get: function () {
   105              return contractStorage;
   106          }
   107      });
   108      Object.defineProperty(this, "fieldName", {
   109          configurable: false,
   110          enumerable: false,
   111          get: function () {
   112              return fieldName;
   113          }
   114      });
   115  
   116      applyMapDescriptor(this, descriptor);
   117  };
   118  
   119  
   120  StorageMap.prototype = {
   121      del: function (key) {
   122          return this.contractStorage.del(combineStorageMapKey(this.fieldName, key));
   123      },
   124      get: function (key) {
   125          var val = this.contractStorage.rawGet(combineStorageMapKey(this.fieldName, key));
   126          if (val != null) {
   127              val = this.parse(val);
   128          }
   129          return val;
   130      },
   131      set: function (key, value) {
   132          var val = this.stringify(value);
   133          return this.contractStorage.rawSet(combineStorageMapKey(this.fieldName, key), val);
   134      }
   135  };
   136  StorageMap.prototype.put = StorageMap.prototype.set;
   137  StorageMap.prototype.delete = StorageMap.prototype.del;
   138  
   139  
   140  ContractStorage.prototype = {
   141      rawGet: function (key) {
   142          return this.nativeStorage.get(key);
   143      },
   144      rawSet: function (key, value) {
   145          var ret = this.nativeStorage.set(key, value);
   146          if (ret != 0) {
   147              throw new Error("set key " + key + " failed.");
   148          }
   149          return ret;
   150      },
   151      del: function (key) {
   152          var ret = this.nativeStorage.del(key);
   153          if (ret != 0) {
   154              throw new Error("del key " + key + " failed.");
   155          }
   156          return ret;
   157      },
   158      get: function (key) {
   159          var val = this.rawGet(key);
   160          if (val != null) {
   161              val = JSON.parse(val);
   162          }
   163          return val;
   164      },
   165      set: function (key, value) {
   166          return this.rawSet(key, JSON.stringify(value));
   167      },
   168      defineProperty: function (obj, fieldName, descriptor) {
   169          if (!obj || !fieldName) {
   170              throw new Error("defineProperty requires at least two parameters.");
   171          }
   172          var $this = this;
   173          Object.defineProperty(obj, fieldName, {
   174              configurable: false,
   175              enumerable: true,
   176              get: function () {
   177                  var val = $this.rawGet(fieldName);
   178                  if (val != null) {
   179                      val = obj["__parse__" + fieldName](val);
   180                  }
   181                  return val;
   182              },
   183              set: function (val) {
   184                  val = obj["__stringify__" + fieldName](val);
   185                  return $this.rawSet(fieldName, val);
   186              }
   187          });
   188          applyFieldDescriptor(obj, fieldName, descriptor);
   189          return this;
   190      },
   191      defineProperties: function (obj, props) {
   192          if (!obj || !props) {
   193              throw new Error("defineProperties requires two parameters.");
   194          }
   195  
   196          for (const fieldName in props) {
   197              this.defineProperty(obj, fieldName, props[fieldName]);
   198          }
   199          return this;
   200      },
   201      defineMapProperty: function (obj, fieldName, descriptor) {
   202          if (!obj || !fieldName) {
   203              throw new Error("defineMapProperty requires two parameters.");
   204          }
   205  
   206          var mapObj = new StorageMap(this, fieldName, descriptor);
   207          Object.defineProperty(obj, fieldName, {
   208              configurable: false,
   209              enumerable: true,
   210              get: function () {
   211                  return mapObj;
   212              }
   213          });
   214          return this;
   215      },
   216      defineMapProperties: function (obj, props) {
   217          if (!obj || !props) {
   218              throw new Error("defineMapProperties requires two parameters.");
   219          }
   220  
   221          for (const fieldName in props) {
   222              this.defineMapProperty(obj, fieldName, props[fieldName]);
   223          }
   224          return this;
   225      }
   226  };
   227  
   228  ContractStorage.prototype.put = ContractStorage.prototype.set;
   229  ContractStorage.prototype.delete = ContractStorage.prototype.del;
   230  
   231  var lcs = new ContractStorage(_native_storage_handlers.lcs);
   232  var gcs = new ContractStorage(_native_storage_handlers.gcs);
   233  var obj = {ContractStorage: ContractStorage};
   234  Object.defineProperty(obj, "lcs", {
   235      configurable: false,
   236      enumerable: false,
   237      get: function () {
   238          return lcs;
   239      }
   240  });
   241  
   242  Object.defineProperty(obj, "gcs", {
   243      configurable: false,
   244      enumerable: false,
   245      get: function () {
   246          return gcs;
   247      }
   248  });
   249  
   250  module.exports = Object.freeze(obj);