Получение BYTEA из PostgreSQL в Sails.js

У меня есть проблема в работе с типом PostgreSQL BYTEA в Sails.js.

Определение таблицы (да, странно создавать двоичные PK, но some_data всегда мала):

CREATE TABLE data_blobs (
  some_data BYTEA PRIMARY KEY,
  my_date_time TIMESTAMP WITH TIME ZONE NOT NULL);

Конфигурация модели выглядит так:

module.exports = {
  tableName: 'data_blobs',
  autoCreatedAt: false,
  autoUpdatedAt: false,
  autoPK: false,
  attributes: {
    some_data: {
      type: 'binary',
      primaryKey: true
    },
    my_date_time: 'datetime',
};

Когда я запрашиваю таблицу из node.js, используя node-postgres (pg), результат содержит Node Buffer с some_data, который очень прост в использовании.

Но когда я запрашиваю таблицу из Sails.js, используя такой код:

DataBlobs.find().then(function(result){
  console.log('Result: ');
  console.log(result);
});

Результат выглядит так:

{
  some_data: 
  { '0': 1,
    '1': 79,
    '2': 95,
    ...
    '19': 216,
    length: 20,
    parent: 
    { '0': 47,
      ...
      '8191': 0 }
  },
  my_date_time: '2015-08-24T10:43:11.959Z'
}

Мне кажется, что Waterline превращает Node Buffer во что-то странное и совершенно бесполезное (без дополнительного преобразования). Я не смог найти никакой документации о преобразовании данных ни в документах Waterline, ни в документах sails-postgresql.

Я вижу два варианта решения этой ситуации:

  1. Как-то, чтобы предотвратить конвертацию буфера в Waterline и сделать конвертацию самостоятельно.
  2. Чтобы захватить вывод Waterline и преобразовать его в контроллеры.

Второй вариант кажется менее эффективным, потому что к исходным данным добавляется большой "родительский", и было бы два преобразования Buffer->Waterline->MyFormat вместо простого Buffer->MyFormat.

1 ответ

Первое решение, которое я нашел, основано на идее переопределить функцию Waterline Model на JSON ( https://github.com/balderdashy/waterline).

Я написал функцию преобразования:

function internalWaterlineBinaryToBase64(waterlineBinaryRepresentation) {
  var temporaryArray = [];
  for(var i = 0, arrLength = waterlineBinaryRepresentation.length; i < arrLength; i++) {
    temporaryArray.push(waterlineBinaryRepresentation[i.toString()]);
  }

  var temporaryBuffer = new Buffer(temporaryArray);

  return temporaryBuffer.toString('base64');
}

и скорректировал мою модель:

module.exports = {
  tableName: 'data_blobs',
  autoCreatedAt: false,
  autoUpdatedAt: false,
  autoPK: false,
  attributes: {
    some_data: {
      type: 'binary',
      primaryKey: true
    },
    my_date_time: 'datetime',
    toJSON: function() {
      var obj = this.toObject();

      if(obj.some_data) {
        obj.some_data = internalWaterlineBinaryToBase64(obj.some_data);
      }

      return obj;
    }
};

Он работает нормально, но мне кажется, что должен быть менее дорогой метод (ватерлинии преобразует оригинальный буфер в объект, затем я преобразую его в массив, затем в буфер и затем в строку).

Другие вопросы по тегам