Skip to content

Commit

Permalink
add sql_query support (#41)
Browse files Browse the repository at this point in the history
* feat: add sql_query support

* feat: add sql query apis

* feat: add sql query tests
  • Loading branch information
feng19 authored Apr 17, 2023
1 parent c02ab29 commit f2b93b5
Show file tree
Hide file tree
Showing 10 changed files with 401 additions and 34 deletions.
5 changes: 2 additions & 3 deletions config/config.exs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This file is responsible for configuring your application
# and its dependencies with the aid of the Mix.Config module.
use Mix.Config
import Config

# This configuration is loaded before any dependency and is restricted
# to this project. If another project depends on this project, this
Expand Down Expand Up @@ -29,8 +29,7 @@ use Mix.Config
#
# import_config "#{Mix.env}.exs"

config :logger,
level: :info
config :logger, level: :info

config :ex_aliyun_ots, debug: false

Expand Down
96 changes: 96 additions & 0 deletions lib/ex_aliyun_ots.ex
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ defmodule ExAliyunOts do
@type inclusive_start_primary_keys :: list
@type exclusive_end_primary_keys :: list
@type index_name :: String.t()
@type query :: String.t()
@type column_name :: String.t()
@type options :: Keyword.t()
@type result :: {:ok, map()} | {:error, ExAliyunOts.Error.t()}

Expand Down Expand Up @@ -1243,6 +1245,100 @@ defmodule ExAliyunOts do
@doc local_transaction: :local_transaction
defdelegate abort_transaction(instance, transaction_id), to: Client

@doc """
Official document in [Chinese](https://help.aliyun.com/document_detail/295884.html) | [English](https://www.alibabacloud.com/help/doc-detail/295884.html)
## Example
import MyApp.TableStore
sql_query("SELECT * FROM table LIMIT 20")
"""
@spec sql_query(instance, query) :: result
defdelegate sql_query(instance, query), to: Client

@doc """
Official document in [Chinese](https://help.aliyun.com/document_detail/295892.html) | [English](https://www.alibabacloud.com/help/doc-detail/295892.html)
## Example
import MyApp.TableStore
create_mapping_table(\"""
CREATE TABLE table (
id VARCHAR(1024) PRIMARY KEY,
is_actived BOOL,
name MEDIUMTEXT,
score DOUBLE,
tags MEDIUMTEXT
)
\""")
"""
@spec create_mapping_table(instance, query) :: :ok | {:error, ExAliyunOts.Error.t()}
defdelegate create_mapping_table(instance, query), to: Client

@doc """
Official document in [Chinese](https://help.aliyun.com/document_detail/295893.html) | [English](https://www.alibabacloud.com/help/doc-detail/295893.html)
## Example
import MyApp.TableStore
drop_mapping_table("table")
"""
@spec drop_mapping_table(instance, table_name) :: :ok | {:error, ExAliyunOts.Error.t()}
defdelegate drop_mapping_table(instance, table), to: Client

@doc """
Official document in [Chinese](https://help.aliyun.com/document_detail/295896.html) | [English](https://www.alibabacloud.com/help/doc-detail/295896.html)
## Example
import MyApp.TableStore
describe_mapping_table("table")
"""
@spec describe_mapping_table(instance, table_name) :: result
defdelegate describe_mapping_table(instance, table), to: Client

@doc """
Official document in [Chinese](https://help.aliyun.com/document_detail/437170.html) | [English](https://www.alibabacloud.com/help/doc-detail/437170.html)
## Example
import MyApp.TableStore
alter_table_drop_column("table", "column")
"""
@spec alter_table_drop_column(instance, table_name, column_name) ::
:ok | {:error, ExAliyunOts.Error.t()}
defdelegate alter_table_drop_column(instance, table, column), to: Client

@doc """
Official document in [Chinese](https://help.aliyun.com/document_detail/437170.html) | [English](https://www.alibabacloud.com/help/doc-detail/437170.html)
## Example
import MyApp.TableStore
alter_table_add_column("table", "column", "BOOL")
"""
@spec alter_table_add_column(instance, table_name, column_name, type :: String.t()) ::
:ok | {:error, ExAliyunOts.Error.t()}
defdelegate alter_table_add_column(instance, table, column, type), to: Client

@doc """
Official document in [Chinese](https://help.aliyun.com/document_detail/295884.html) | [English](https://www.alibabacloud.com/help/doc-detail/295884.html)
## Example
import MyApp.TableStore
query("SELECT * FROM table LIMIT 20")
"""
@spec query(instance, query) :: result
defdelegate query(instance, query), to: Client

defp map_options(var, nil), do: var

defp map_options(var, options) do
Expand Down
30 changes: 29 additions & 1 deletion lib/ex_aliyun_ots/client.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
defmodule ExAliyunOts.Client do
@moduledoc false

alias ExAliyunOts.Client.{Table, Row, Search, Transaction, Tunnel}
alias ExAliyunOts.Client.{Table, Row, Search, Transaction, Tunnel, SQL}
alias ExAliyunOts.{PlainBuffer, Config}

def create_table(instance_key, var_create_table) do
Expand Down Expand Up @@ -207,6 +207,34 @@ defmodule ExAliyunOts.Client do
Tunnel.remote_checkpoint(Config.get(instance_key), options)
end

def sql_query(instance_key, query) do
SQL.remote_sql_query(Config.get(instance_key), query)
end

def create_mapping_table(instance_key, query) do
SQL.create_mapping_table(Config.get(instance_key), query)
end

def drop_mapping_table(instance_key, table) do
SQL.drop_mapping_table(Config.get(instance_key), table)
end

def describe_mapping_table(instance_key, table) do
SQL.describe_mapping_table(Config.get(instance_key), table)
end

def alter_table_drop_column(instance_key, table, column) do
SQL.alter_table_drop_column(Config.get(instance_key), table, column)
end

def alter_table_add_column(instance_key, table, column, type) do
SQL.alter_table_add_column(Config.get(instance_key), table, column, type)
end

def query(instance_key, query) do
SQL.query(Config.get(instance_key), query)
end

defp remote_get_range(instance, var_get_range, next_start_primary_key) do
case Row.remote_get_range(instance, var_get_range, next_start_primary_key) do
{:ok, get_range_response} ->
Expand Down
81 changes: 81 additions & 0 deletions lib/ex_aliyun_ots/client/sql.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
defmodule ExAliyunOts.Client.SQL do
@moduledoc false

alias ExAliyunOts.{Http, PlainBuffer}
alias ExAliyunOts.TableStore.{SQLQueryRequest, SQLQueryResponse}

def remote_sql_query(instance, query) do
request_body =
%SQLQueryRequest{query: query} |> SQLQueryRequest.encode!() |> IO.iodata_to_binary()

instance
|> Http.client("/SQLQuery", request_body, &SQLQueryResponse.decode!/1)
|> Http.post()
|> case do
{:ok, response} ->
{:ok, %{response | rows: PlainBuffer.deserialize_rows(response.rows)}}

error ->
error
end
end

def create_mapping_table(instance, query) do
case remote_sql_query(instance, query) do
{:ok, %SQLQueryResponse{rows: []}} -> :ok
error -> error
end
end

def drop_mapping_table(instance, table) do
case remote_sql_query(instance, "DROP MAPPING TABLE IF EXISTS #{table}") do
{:ok, %SQLQueryResponse{rows: []}} -> :ok
error -> error
end
end

def describe_mapping_table(instance, table) do
case remote_sql_query(instance, "DESCRIBE #{table}") do
{:ok, %SQLQueryResponse{rows: rows}} ->
map =
for row <- rows, into: %{} do
transfer_row(row) |> Map.pop!("Field")
end

{:ok, map}

error ->
error
end
end

def alter_table_drop_column(instance, table, column) do
case remote_sql_query(instance, "ALTER TABLE #{table} DROP COLUMN #{column}") do
{:ok, %SQLQueryResponse{rows: []}} -> :ok
error -> error
end
end

def alter_table_add_column(instance, table, column, type) do
case remote_sql_query(instance, "ALTER TABLE #{table} ADD COLUMN #{column} #{type}") do
{:ok, %SQLQueryResponse{rows: []}} -> :ok
error -> error
end
end

def query(instance, query) do
case remote_sql_query(instance, query) do
{:ok, %SQLQueryResponse{rows: rows}} ->
{:ok, Enum.map(rows, &transfer_row/1)}

error ->
error
end
end

defp transfer_row({[], attrs}) do
for {attr_key, attr_value, _ts} <- attrs, into: %{} do
{attr_key, attr_value}
end
end
end
4 changes: 4 additions & 0 deletions lib/ex_aliyun_ots/compiler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ defmodule ExAliyunOts.Compiler do
def compute_split_points_by_size(table, split_size) do
ExAliyunOts.compute_split_points_by_size(@instance, table, split_size)
end

def sql_query(query) do
ExAliyunOts.sql_query(@instance, query)
end
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/ex_aliyun_ots/plainbuffer/crc.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
defmodule ExAliyunOts.CRC do
@moduledoc false

use Bitwise
import Bitwise

@crc8_table <<0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15,
0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d,
Expand Down
3 changes: 2 additions & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ defmodule ExAliyunOts.Mixfile do

defp deps do
[
{:tablestore_protos, "~> 0.1.4"},
#{:tablestore_protos, "~> 0.1.4"},
{:tablestore_protos, github: "feng19/tablestore_protos"},
{:finch, "~> 0.5"},
{:gen_state_machine, "~> 2.0"},
{:tesla, "~> 1.4"},
Expand Down
Loading

0 comments on commit f2b93b5

Please sign in to comment.