Packages
ecto_tablestore
0.8.1
0.15.1
0.15.0
0.14.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.2
0.12.1
0.12.0
0.11.2
0.11.1
0.11.0
0.10.1
0.10.0
0.9.0
0.8.3
0.8.2
0.8.1
0.8.0
0.7.0
0.6.1
0.6.0
0.5.11
0.5.10
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.2
0.4.1
0.4.0
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.0
0.1.0
Alibaba Tablestore adapter for Ecto
Current section
Files
Jump to
Current section
Files
ecto_tablestore
README.md
README.md
# Alibaba Tablestore adapter for Ecto
[](https://hex.pm/packages/ecto_tablestore)
[](https://hexdocs.pm/ecto_tablestore/)
[](https://hex.pm/packages/ecto_tablestore)
[](https://github.com/edragonconnect/ecto_tablestore/blob/master/LICENSE.md)
[](https://github.com/edragonconnect/ecto_tablestore/commits/master)
Ecto 3.x adapter for [Alibaba Tablestore](https://www.alibabacloud.com/product/table-store), this
is built on top of [`ex_aliyun_ots`](https://hex.pm/packages/ex_aliyun_ots) to implement
`Ecto.Adapter` and `Ecto.Adapter.Schema` behaviours.
Supported features:
* Compatible `Ecto.Repo` API.
* Support schema's `timestamps()` macro, make `inserted_at` and `updated_at` as an integer UTC
timestamps.
* Support `:map` | `{:map, _}` | `:array` | `{:array, _}` field type, use Jason to encode the
field value into :string when save, use Jason to simply decode the field value into `:map` |
`:array` when read, the :keys option of Jason's decode always use :string.
* Support the partition key is autoincrementing, use the sequence feature provided by
`ex_aliyun_ots`.
* Automatically converts the returned original row results into corresponding schema(s).
* Automatically generate the provided attribute-column field(s) of schema entity into the `filter`
expression option of `GetRow` (see `c:EctoTablestore.Repo.one/2`) and `BatchGet` (see
`c:EctoTablestore.Repo.batch_get/1`) use `entity_full_match: true`, by default this option is
`false`.
* Automatically generate the provided attribute-column field(s) of schema entity into the
`condition` expression option of `BatchWrite`.
* Automatically map changeset's attribute-column field(s) into `UpdateRow` operation when call
`c:EctoTablestore.Repo.update/2`:
* Use atomic increment via `{:increment, integer()}` in changeset, and return the increased
value in the corresponding field(s) by default;
* Set any attribute(s) of schema changeset as `nil` will `:delete_all` that attribute-column
field(s);
* Set existed attribute(s) in schema changeset will `:put` to save.
Implement Tablestore row related functions in `EctoTablestore.Repo` module, please see
[document](https://hexdocs.pm/ecto_tablestore/readme.html) for details:
* PutRow
* GetRow
* UpdateRow
* DeleteRow
* GetRange
* StreamRange
* BatchGetRow
* BatchWriteRow
* Search
## Migration
Provide a simple migration to create table, please see `EctoTablestore.Migration` for details.
## Usage
1, Configure `My` instance(s) information of Alibaba Tablestore product.
```elixir
use Mix.Config
# config for `ex_aliyun_ots`
config :ex_aliyun_ots, MyInstance,
name: "MY_INSTANCE_NAME",
endpoint: "MY_INSTANCE_ENDPOINT",
access_key_id: "MY_OTS_ACCESS_KEY",
access_key_secret: "MY_OTS_ACCESS_KEY_SECRET"
config :ex_aliyun_ots,
instances: [MyInstance]
# config for `ecto_tablestore`
config :my_otp_app, EctoTablestore.MyRepo,
instance: MyInstance
```
2, Create the `EctoTablestore.MyRepo` module mentioned earlier in the configuration, use
`EctoTablestore.Repo` and set required `otp_app` option with your OTP application's name.
```elixir
defmodule EctoTablestore.MyRepo do
use EctoTablestore.Repo,
otp_app: :my_otp_app
end
```
3, Each repository in Ecto defines a `start_link/0` function that needs to be invoked before using
the repository. In general, this function is not called directly, but used as part of your
application supervision tree.
Add `EctoTablestore.MyRepo` into your application start callback that defines and start your
supervisor. You just need to edit `start/2` function to start the repo as a supervisor on your
application's supervisor:
```elixir
def start(_type, _args) do
children = [
{EctoTablestore.MyRepo, []}
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
```
4, After finish the above preparation, we can use `MyRepo` to operate data store.
## Integrate Hashids
Base on unique integer of atomic-increment sequence, provides a way to simply integrate `Hashids`
to generate your *hash* ids when insert row(s), for `Repo.insert/2` or `Repo.batch_write/1`.
### Use in schema
```elixir
defmodule Module do
use EctoTablestore.Schema
tablestore_schema "table_name" do
field(:id, :hashids, primary_key: true, autogenerate: true,
hashids: [salt: "123", min_len: 2, alphabet: "..."])
field(:content, :string)
end
end
```
Options:
* The `primary_key` as true is required;
* The `autogenerate` as true is required;
* The `salt`, `min_len` and `alphabet` of hashids options are used for configuration options from
`Hashids.new/1`.
Notice: the `salt`, `min_len` and `alphabet` of hashids options also can be configured in the `:ecto_tablestore`
config for each defined schema, for example:
```elixir
config :ecto_tablestore,
hashids: [
{Module, salt: "...", min_len: 16, alphabet: "..."},
...
]
```
### Use in migration
Use `:hashids` as a type in `add` operation to define the partition key, the principle behind this
will use `ecto_tablestore_default_seq` as a global default table to maintain the sequences of all
tables, if `ecto_tablestore_default_seq` is not existed, there will create this, if it is existed,
please ignore the "OTSObjectAlreadyExist" error of requested table already exists.
```elixir
defmodule EctoTablestore.TestRepo.Migrations.TestHashids do
use EctoTablestore.Migration
def change do
create table("table_name") do
add :id, :hashids, partition_key: true
add :oid, :integer
end
end
end
```
Options:
* The `partition_key` option as true is required;
* The `auto_increment` option is ignored when the partition key is `:hashids` type.
## References
Alibaba Tablestore product official references:
* [English document](https://www.alibabacloud.com/help/doc-detail/27280.htm)
* [中文文档](https://help.aliyun.com/document_detail/27280.html)
## License
This project is licensed under the MIT license. Copyright (c) 2018- Xin Zou.