OpenStax.Swift.Ecto v0.2.3 OpenStax.Swift.Ecto.Model behaviour

This module simplifies using OpenStax Swift storage with Ecto Models.

It exposes several functions that allow to easily upload/download files that should be logically bound to certain record.

It automatically performs MIME type checks and ensures that uploaded files have right MIME type in the storage.

By design, only one file per record is allowed.

If either file_type or file_size, file_etag, file_name fields will be present in the model it will be automatically updated. Names of these fields can be overriden by overriding swift_file_size_field, swift_file_type_field, swift_file_etag_field and swift_file_name_field functions. Override this to functions that return nil to disable that feature.

An example model that uses OpenStax.Swift.Ecto.Model:

defmodule MyApp.MyModel do
  use Ecto.Model
  use OpenStax.Swift.Ecto.Model

  @required_fields ~w()
  @optional_fields ~w(file_size file_type file_etag file_name)

  schema "mymodel" do
    field :file_size, :integer
    field :file_type, :string
    field :file_etag, :string
    field :file_name, :string
    timestamps
  end

  def swift_endpoint_id(_record), do: :myendpoint
  def swift_container(_record),   do: :somecontainer
  def swift_object_id(record),    do: "something_" <> record.id

  def changeset(model, params \ :empty) do
    model
    |> cast(params, @required_fields, @optional_fields)
  end
end

An example usage:

defmodule MyApp.MyLogic do
  def attach_file_to_record(record_id, path) do
    record = MyApp.Repo.get!(MyApp.MyModel, record_id)

    case OpenStax.Swift.Ecto.Model.upload(MyApp.Repo, record, {:file, path}) do
      {:ok, record} ->
        IO.puts "OK " <> OpenStax.Swift.Ecto.Model.temp_url(record)

      {:error, reason} ->
        IO.puts "ERROR " <> inspect(reason)
    end
  end
end

Summary

Functions

Generates temporary URL for given record with specified expiry time

Synchronously uploads file from given path to the storage and associates it with given record using given repo

Does the same as upload/4 but throws an error in case of failure

Callbacks

Returns container name as atom or string for given record

Returns OpenStax Swift endpoint ID as atom for given record

Returns field name that should contain file type for given record

Returns field name that should contain file name for given record

Returns field name that should contain file size for given record

Returns field name that should contain file type for given record

Returns string that contains Swift Object ID for given record

Functions

temp_url(record, expires \\ 3600)
temp_url(map, non_neg_integer) :: String.t

Generates temporary URL for given record with specified expiry time.

upload(repo, record, body, options \\ [])
upload(Ecto.Repo.t, map, String.t | {:file, String.t}, [...]) ::
  {:ok, map} |
  {:error, any}

Synchronously uploads file from given path to the storage and associates it with given record using given repo.

If either file_type or file_size, file_etag, file_name fields will be present in the model it will be automatically updated. Names of these fields can be overriden by overriding swift_file_size_field, swift_file_type_field, swift_file_etag_field and swift_file_name_field functions. Override this to functions that return nil to disable that feature.

It creates single Object in the storage.

First argument is a repo to use while updating the record.

Second argument is a record that is supposed to be “an owner” of the file.

Third argument is a file contents passed as string (not recommended) or path to the file, represented as {:file, path}.

Fourth argument is a list of options containing {:key, value} pairs. Supported keys are:

  • :mime_type - if present, use given MIME type instead of performing guess.

On success it returns {:ok, record}.

On failure to communicate with the storage it returns {:error, {:storage, reason}}.

On failure to update the record it returns {:error, {:update, changeset}}.

upload!(repo, record, body)
upload!(Ecto.Repo.t, map, String.t | {:file, String.t}) :: map

Does the same as upload/4 but throws an error in case of failure.

Callbacks

swift_container(map)
swift_container(map) :: atom | String.t

Returns container name as atom or string for given record.

swift_endpoint_id(map)
swift_endpoint_id(map) :: atom

Returns OpenStax Swift endpoint ID as atom for given record.

Endpoint has to be previously configures, please refer to OpenStax Swift documentation to see how to do it.

swift_file_etag_field(map)
swift_file_etag_field(map) :: atom | nil

Returns field name that should contain file type for given record.

Return nil if you want to disable this feature.

swift_file_name_field(map)
swift_file_name_field(map) :: atom | nil

Returns field name that should contain file name for given record.

Return nil if you want to disable this feature.

swift_file_size_field(map)
swift_file_size_field(map) :: atom | nil

Returns field name that should contain file size for given record.

Return nil if you want to disable this feature.

swift_file_type_field(map)
swift_file_type_field(map) :: atom | nil

Returns field name that should contain file type for given record.

Return nil if you want to disable this feature.

swift_object_id(map)
swift_object_id(map) :: String.t

Returns string that contains Swift Object ID for given record.

Default implementation takes passed struct type and adds value of the id field of the struct, concatenated using underscore.