Spec-Zone.ru › RethinkDB ruby

Хранение двоичных объектов

RethinkDB поддерживает родной тип двоичных объектов, позволяющий использовать ReQL для прямого хранения двоичных объектов в базе данных. Драйвер ReQL прозрачно выполняет преобразование между типом ReQL и классом Ruby String.

Примечание: Тип двоичных объектов предназначен для данных, которые нельзя надёжно хранить в виде строк UTF-8, таких как загруженные файлы. Если вы работаете с данными, которые можно хранить в виде строк, обычно проще использовать тип данных строки.

В этих примерах мы будем предполагать, что подключение к RethinkDB доступно в глобальной области видимости как conn.

Хранение загруженных файлов в базе данных

Веб-приложениям часто требуется принимать загрузки файлов от пользователей; с RethinkDB вы можете хранить эти файлы непосредственно в базе данных.

def save_file(file_path, save_name, user_id)
    # Store the file at 'file_path' with the filename 'save_name'.
    fh = File.open(file_path, 'rb')
    contents = fh.read()
    fh.close()
    r.table('files').insert({
        :user_id => user_id,
        :filename => save_name,
        :file => r.binary(contents)
    }).run(conn)
end

В save_file, мы передаём путь к загруженному файлу (который может находиться в временной папке хранения, даже с временным именем, в зависимости от используемой библиотеки загрузки), имя для сохранения файла и идентификатор пользователя, который загрузил файл. Команда ReQL binary используется для хранения содержимого файла в виде двоичного объекта в поле file.

def get_user_file_ids(user_id)
    # Retrieve the IDs of previously-saved files for a user as an array of
    # hashes: [ { :id => x, :filename => y }, ...]
    return r.table('files').filter({ :user_id => user_id }).
        pluck('id', 'filename').run(conn)

def get_file(file_id):
    """
    Retrieve a file by its ID. Returns a hash with 'filename' and 'file'
    keys.
    """
    return r.table('files').get(file_id).pluck('file', 'filename').run(conn)

Далее, есть две функции для извлечения файлов: одна для извлечения каталога загруженных файлов пользователя (get_user_file_ids) и одна для извлечения самого файла (get_file). Нам не нужно использовать binary снова здесь; драйвер ReQL вернёт соответствующий тип данных для поля file в нашем объекте.

Вот ещё один, более интересный пример: добавление аватаров Gravatar к учётным записям пользователей. Мы можем использовать http для их получения.

require 'digest'

def add_gravatar(user_id):
    """
    Add a gravatar field with the binary avatar icon to user accounts if they
    have an avatar associated with their email address.
    """
    email = r.table('users').get(user_id)['email'].run(conn)
    hash = Digest::MD5.hexdigest email
    gravatar_url = 'http://www.gravatar.com/avatar/' + hash + '?d=retro'
    r.table('users').get(user_id).update({
        'gravatar': r.http(gravatar_url, :result_format => 'binary')
    }).run(conn)

Где r.binary? В данном случае он не нужен, потому что r.http вернёт двоичный объект с параметром :result_format => 'binary'. (Если тип MIME на сервере-отправителе настроен правильно, вы можете даже убрать его, и r.http определит правильный тип.)

© RethinkDB contributors
Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
https://rethinkdb.com/docs/storing-binary/ruby/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API