Packages
erlcloud
2.2.4
3.8.3
3.8.2
3.8.1
3.7.6
3.7.4
3.7.3
3.7.2
3.7.1
3.7.0
3.6.8
3.6.7
3.6.5
3.6.4
3.6.3
3.6.2
3.6.1
3.6.0
3.5.16
3.5.15
3.5.14
3.5.13
3.5.12
3.5.11
3.5.10
3.5.9
3.5.8
3.5.7
3.5.6
3.5.5
3.5.4
3.5.3
3.5.2
3.5.1
3.5.0
3.4.5
3.4.3
3.4.1
3.4.0
3.3.9
3.3.8
3.3.7
3.3.6
3.3.5
3.3.4
3.3.3
3.3.2
3.3.1
3.3.0
3.2.18
3.2.17
3.2.16
3.2.15
3.2.14
3.2.13
3.2.12
3.2.11
3.2.10
3.2.7
3.2.6
3.2.5
3.2.4
3.2.3
3.2.2
3.2.1
3.2.0
3.1.17
3.1.16
3.1.14
3.1.13
3.1.12
3.1.11
3.1.9
3.1.8
3.1.7
3.1.6
3.1.5
3.1.4
3.1.3
3.1.2
3.1.1
3.1.0
3.0.5
3.0.4
3.0.3
3.0.2
3.0.1
2.2.16
2.2.15
2.2.14
2.2.13
2.2.12
2.2.11
2.2.10
2.2.9
2.2.8
2.2.7
2.2.6
2.2.5
2.2.4
2.2.2
2.2.1
2.2.0
2.1.0
2.0.5
2.0.4
2.0.3
2.0.0
0.13.10
0.13.9
0.13.8
0.13.6
0.13.5
0.13.4
0.13.3
0.13.2
0.13.0
0.12.0
0.11.0
0.9.2
0.9.2-rc.1
0.9.1
0.9.0
AWS APIs library for Erlang
Current section
Files
Jump to
Current section
Files
src/erlcloud_sdb.erl
-module(erlcloud_sdb).
-type sdb_attribute() :: {string(), string() | {replace, string()}}.
-type sdb_attributes() :: [sdb_attribute()].
-type sdb_conditional() :: {string(), string() | exists | not_exists}.
-type sdb_conditionals() :: [sdb_conditional()].
-type sdb_delete_attribute() :: {string(), string()} | string().
-type sdb_delete_attributes() :: [sdb_delete_attribute()].
%% Library initialization.
-export([configure/2, configure/3, new/2, new/3]).
%% SDB API Functions
-export([
%% Domains
create_domain/1, create_domain/2,
delete_domain/1, delete_domain/2,
domain_metadata/1, domain_metadata/2,
list_domains/0, list_domains/1, list_domains/2, list_domains/3,
%% Items
batch_put_attributes/2, batch_put_attributes/3,
delete_attributes/2, delete_attributes/3,
delete_attributes/4, delete_attributes/5,
get_attributes/2, get_attributes/3, get_attributes/4, get_attributes/5,
put_attributes/3, put_attributes/4, put_attributes/5,
select/1, select/2, select/3, select/4,
select_all/1, select_all/2, select_all/3
]).
-ifdef(TEST).
-export([extract_token/1]).
-endif.
-include("erlcloud.hrl").
-include("erlcloud_aws.hrl").
-define(API_VERSION, "2009-04-15").
-define(SDB_TIMEOUT, 10000).
-spec new(string(), string()) -> aws_config().
new(AccessKeyID, SecretAccessKey) ->
#aws_config{access_key_id=AccessKeyID,
secret_access_key=SecretAccessKey}.
-spec new(string(), string(), string()) -> aws_config().
new(AccessKeyID, SecretAccessKey, Host) ->
#aws_config{access_key_id=AccessKeyID,
secret_access_key=SecretAccessKey,
sdb_host=Host}.
-spec configure(string(), string()) -> ok.
configure(AccessKeyID, SecretAccessKey) ->
put(aws_config, new(AccessKeyID, SecretAccessKey)),
ok.
-spec configure(string(), string(), string()) -> ok.
configure(AccessKeyID, SecretAccessKey, Host) ->
put(aws_config, new(AccessKeyID, SecretAccessKey, Host)),
ok.
default_config() -> erlcloud_aws:default_config().
-spec create_domain(string()) -> proplist().
create_domain(Name) ->
create_domain(Name, default_config()).
-spec create_domain(string(), aws_config()) -> proplist().
create_domain(Name, Config)
when is_list(Name) ->
sdb_simple_request(Config, "CreateDomain", [{"DomainName", Name}]).
-spec delete_domain(string()) -> proplist().
delete_domain(Name) ->
delete_domain(Name, default_config()).
-spec delete_domain(string(), aws_config()) -> proplist().
delete_domain(Name, Config)
when is_list(Name) ->
sdb_simple_request(Config, "DeleteDomain", [{"DomainName", Name}]).
-spec domain_metadata(string()) -> proplist().
domain_metadata(Name) ->
domain_metadata(Name, default_config()).
-spec domain_metadata(string(), aws_config()) -> proplist().
domain_metadata(Name, Config)
when is_list(Name) ->
{Doc, Result} = sdb_request(Config, "DomainMetadata", [{"DomainName", Name}]),
MR = hd(xmerl_xpath:string("/DomainMetadataResponse/DomainMetadataResult", Doc)),
Metadata = erlcloud_xml:decode([
{item_count, "ItemCount", integer},
{item_names_size_bytes, "ItemNamesSizeBytes", integer},
{attribute_name_count, "AttributeNameCount", integer},
{attribute_names_size_bytes, "AttributeNamesSizeBytes", integer},
{attribute_value_count, "AttributeValueCount", integer},
{attribute_values_size_bytes, "AttributeValuesSizeBytes", integer},
{timestamp, "Timestamp", integer}
], MR),
[{domain_metadata, Metadata}|Result].
-spec batch_put_attributes(string(), [{string(), sdb_attributes()}]) -> proplist().
batch_put_attributes(DomainName, Items) ->
batch_put_attributes(DomainName, Items, default_config()).
-spec batch_put_attributes(string(), [{string(), sdb_attributes()}], aws_config()) -> proplist().
batch_put_attributes(DomainName, Items, Config)
when is_list(DomainName), is_list(Items) ->
ItemParams = [[{"ItemName", Name}|attributes_list(Attrs)] || {Name, Attrs} <- Items],
sdb_simple_request(Config, "BatchPutAttributes",
[{"DomainName", DomainName}|erlcloud_aws:param_list(ItemParams, "Item")]).
-spec delete_attributes(string(), string()) -> proplist().
delete_attributes(DomainName, ItemName) ->
delete_attributes(DomainName, ItemName, []).
-spec delete_attributes(string(), string(), sdb_delete_attributes() | aws_config()) -> proplist().
delete_attributes(DomainName, ItemName, Config)
when is_record(Config, aws_config) ->
delete_attributes(DomainName, ItemName, [], Config);
delete_attributes(DomainName, ItemName, Attributes) ->
delete_attributes(DomainName, ItemName, Attributes, []).
-spec delete_attributes(string(), string(), sdb_delete_attributes(), sdb_conditionals() | aws_config()) -> proplist().
delete_attributes(DomainName, ItemName, Attributes, Config)
when is_record(Config, aws_config) ->
delete_attributes(DomainName, ItemName, Attributes, [], Config);
delete_attributes(DomainName, ItemName, Attributes, Conditionals) ->
delete_attributes(DomainName, ItemName, Attributes, Conditionals, default_config()).
-spec delete_attributes(string(), string(), sdb_delete_attributes(), sdb_conditionals(), aws_config()) -> proplist().
delete_attributes(DomainName, ItemName, Attributes, Conditionals, Config)
when is_list(DomainName), is_list(ItemName), is_list(Attributes),
is_list(Conditionals) ->
Params = [{"DomainName", DomainName}, {"ItemName", ItemName}|
delete_attributes_list(Attributes)] ++ conditionals_list(Conditionals),
sdb_simple_request(Config, "DeleteAttributes", Params).
-spec get_attributes(string(), string()) -> proplist().
get_attributes(DomainName, ItemName) ->
get_attributes(DomainName, ItemName, []).
-spec get_attributes(string(), string(), [string()] | boolean() | aws_config()) -> proplist().
get_attributes(DomainName, ItemName, Config)
when is_record(Config, aws_config) ->
get_attributes(DomainName, ItemName, [], Config);
get_attributes(DomainName, ItemName, ConsistentRead)
when is_boolean(ConsistentRead) ->
get_attributes(DomainName, ItemName, [], ConsistentRead);
get_attributes(DomainName, ItemName, AttributeNames) ->
get_attributes(DomainName, ItemName, AttributeNames, false).
-spec get_attributes(string(), string(), [string()], boolean() | aws_config()) -> proplist().
get_attributes(DomainName, ItemName, AttributeNames, Config)
when is_record(Config, aws_config) ->
get_attributes(DomainName, ItemName, AttributeNames, false, Config);
get_attributes(DomainName, ItemName, AttributeNames, ConsistentRead) ->
get_attributes(DomainName, ItemName, AttributeNames, ConsistentRead,
default_config()).
-spec get_attributes(string(), string(), [string()], boolean(), aws_config()) -> proplist().
get_attributes(DomainName, ItemName, AttributeNames, ConsistentRead, Config) ->
{Doc, Result} = sdb_request(Config, "GetAttributes",
[{"DomainName", DomainName}, {"ItemName", ItemName},
{"ConsistentRead", ConsistentRead}|
erlcloud_aws:param_list(AttributeNames, "AttributeName")]),
[{attributes,
extract_attributes(xmerl_xpath:string("/GetAttributesResponse/GetAttributesResult/Attribute", Doc))}|
Result].
extract_attributes(Attributes) ->
[extract_attribute(Attr) || Attr <- Attributes].
extract_attribute(Node) ->
{erlcloud_xml:get_text("Name", Node), erlcloud_xml:get_text("Value", Node)}.
-spec list_domains() -> proplist().
list_domains() ->
list_domains(default_config()).
-spec list_domains(string() | 1..100 | none | aws_config()) -> proplist().
list_domains(Config) when is_record(Config, aws_config) ->
list_domains("", Config);
list_domains(MaxDomains) when is_integer(MaxDomains); MaxDomains =:= none ->
list_domains("", MaxDomains);
list_domains(FirstToken) ->
list_domains(FirstToken, none).
-spec list_domains(string(), 1..100 | none | aws_config()) -> proplist().
list_domains(FirstToken, Config) when is_record(Config, aws_config) ->
list_domains(FirstToken, none, Config);
list_domains(FirstToken, MaxDomains) ->
list_domains(FirstToken, MaxDomains, default_config()).
maybe_add_maxdomains(none, Params) ->
Params;
maybe_add_maxdomains(MaxDomains, Params) ->
[{"MaxNumberOfDomains", MaxDomains} | Params].
maybe_add_nexttoken([], Params) ->
Params;
maybe_add_nexttoken(Token, Params) ->
[{"NextToken", Token} | Params].
-spec list_domains(string(), 1..100 | none, aws_config()) -> proplist().
list_domains(FirstToken, MaxDomains, Config)
when is_list(FirstToken),
is_integer(MaxDomains) orelse MaxDomains =:= none ->
Params =
maybe_add_nexttoken(FirstToken,
maybe_add_maxdomains(MaxDomains, [])),
{Doc, Result} = sdb_request(Config, "ListDomains", Params),
[{domains, erlcloud_xml:get_list("/ListDomainsResponse/ListDomainsResult/DomainName", Doc)},
{next_token, erlcloud_xml:get_text("/ListDomainsResponse/ListDomainsResult/NextToken", Doc)}|Result].
-spec put_attributes(string(), string(), sdb_attributes()) -> proplist().
put_attributes(DomainName, ItemName, Attributes) ->
put_attributes(DomainName, ItemName, Attributes, []).
-spec put_attributes(string(), string(), sdb_attributes(), sdb_conditionals() | aws_config()) -> proplist().
put_attributes(DomainName, ItemName, Attributes, Config)
when is_record(Config, aws_config) ->
put_attributes(DomainName, ItemName, Attributes, [], Config);
put_attributes(DomainName, ItemName, Attributes, Conditionals) ->
put_attributes(DomainName, ItemName, Attributes, Conditionals, default_config()).
-spec put_attributes(string(), string(), sdb_attributes(), sdb_conditionals(), aws_config()) -> proplist().
put_attributes(DomainName, ItemName, Attributes, Conditionals, Config)
when is_list(DomainName), is_list(ItemName), is_list(Attributes),
is_list(Conditionals) ->
Params = [{"DomainName", DomainName}, {"ItemName", ItemName}|
attributes_list(Attributes)] ++ conditionals_list(Conditionals),
sdb_simple_request(Config, "PutAttributes", Params).
%% These functions will return the first page of results along with
%% a token to retrieve the next page, if any.
-spec select(string()) -> proplist().
select(SelectExpression) -> select(SelectExpression, none).
-spec select(string(), string() | none | boolean() | aws_config()) -> proplist().
select(SelectExpression, Config)
when is_record(Config, aws_config) ->
select(SelectExpression, none, Config);
select(SelectExpression, ConsistentRead)
when is_boolean(ConsistentRead) ->
select(SelectExpression, none, ConsistentRead);
select(SelectExpression, NextToken) ->
select(SelectExpression, NextToken, false).
-spec select(string(), string() | none, boolean() | aws_config()) -> proplist().
select(SelectExpression, NextToken, Config)
when is_record(Config, aws_config) ->
select(SelectExpression, NextToken, false, Config);
select(SelectExpression, NextToken, ConsistentRead) ->
select(SelectExpression, NextToken, ConsistentRead, default_config()).
-spec select(string(), string() | none, boolean(), aws_config()) -> proplist().
select(SelectExpression, NextToken, ConsistentRead, Config)
when is_list(SelectExpression),
is_list(NextToken) orelse NextToken =:= none,
is_boolean(ConsistentRead) ->
{Items, NewNextToken, Metadata} = sdb_select_request(SelectExpression,
NextToken,
ConsistentRead,
Config),
Metadata2 = case NewNextToken of
done -> Metadata;
Token -> [{next_token, Token}|Metadata]
end,
[{items, Items}|Metadata2].
%% These functions will make multiple requests until all
%% pages of results have been consumed.
-spec select_all(string()) -> proplist().
select_all(SelectExpression) ->
select_all(SelectExpression, false).
-spec select_all(string(), boolean()) -> proplist().
select_all(SelectExpression, ConsistentRead)
when is_boolean(ConsistentRead) ->
select_all(SelectExpression, ConsistentRead, default_config());
select_all(SelectExpression, Config) ->
select_all(SelectExpression, false, Config).
-spec select_all(string(), boolean(), aws_config()) -> proplist().
select_all(SelectExpression, ConsistentRead, Config)
when is_list(SelectExpression),
is_boolean(ConsistentRead) ->
select_all(SelectExpression, none, ConsistentRead, Config, [], []).
-spec select_all(string(), string() | none | done, boolean(), aws_config(), proplist(), proplist()) -> proplist().
select_all(_, done, _, _, Items, Metadata) ->
[{items, Items}|Metadata];
select_all(SelectExpression, NextToken, ConsistentRead, Config, Items, Metadata) ->
{NewItems, NewNextToken, NewMetadata} = sdb_select_request(SelectExpression,
NextToken,
ConsistentRead,
Config),
select_all(SelectExpression, NewNextToken, ConsistentRead,
Config, Items ++ NewItems, Metadata ++ NewMetadata).
sdb_select_request(SelectExpression, NextToken, ConsistentRead, Config) ->
{Doc, Metadata} = sdb_request(Config, "Select",
[{"SelectExpression", SelectExpression},
{"NextToken", NextToken},
{"ConsistentRead", ConsistentRead}]),
NewNextToken = extract_token(Doc),
Items = extract_items(xmerl_xpath:string("/SelectResponse/SelectResult/Item", Doc)),
{Items, NewNextToken, Metadata}.
extract_token(Doc) ->
case xmerl_xpath:string("/SelectResponse/SelectResult/NextToken", Doc) of
[] ->
done;
[Token] ->
erlcloud_xml:get_text(Token)
end.
extract_items(Items) ->
[extract_item(Item) || Item <- Items].
extract_item(Item) ->
[
{name, erlcloud_xml:get_text("Name", Item)},
{attributes, extract_attributes(xmerl_xpath:string("Attribute", Item))}
].
sdb_request(Config, Action, Params) ->
case sdb_request_with_retry(Config, Action, Params, 1, ?SDB_TIMEOUT, os:timestamp()) of
{ok, {Doc, Metadata}} ->
{Doc, Metadata};
{error, Error} ->
erlang:error({aws_error, Error})
end.
sdb_request_with_retry(Config, Action, Params, Try, Timeout, StartTime) ->
case sdb_request_safe(Config, Action, Params) of
{ok, Doc, Metadata} ->
{ok, {Doc, Metadata}};
{error, {http_error, 503, _StatusLine, _Body}} ->
%% Convert from microseconds to milliseconds
Waited = timer:now_diff(os:timestamp(), StartTime) / 1000.0,
case Waited of
_TooLong when Waited > Timeout ->
{error, retry_timeout};
_ ->
Wait = math:pow(2, Try) * 200.0,
%% Not exactly random since we're relying on the
%% calling process to hold our PRNG state.
FuzzWait = erlcloud_util:rand_uniform(round(Wait)),
timer:sleep(FuzzWait),
sdb_request_with_retry(Config, Action, Params,
Try + 1, Timeout, StartTime)
end;
{error, _} = Error ->
Error
end.
sdb_request_safe(Config, Action, Params) ->
QParams = [{"Action", Action}, {"Version", ?API_VERSION}|Params],
case erlcloud_aws:aws_request_xml2(post, Config#aws_config.sdb_host,
"/", QParams, Config) of
{ok, Doc} ->
{ok, Doc, [{box_usage, erlcloud_xml:get_float("/*/ResponseMetadata/BoxUsage", Doc)}]};
{error, Error} ->
{error, Error}
end.
sdb_simple_request(Config, Action, Params) ->
{_Doc, Result} = sdb_request(Config, Action, Params),
Result.
delete_attributes_list(Attrs) ->
erlcloud_aws:param_list(
[case Attr of
{Name, Value} -> [{"Name", Name}, {"Value", Value}];
Name when is_list(Name) -> [{"Name", Name}]
end || Attr <- Attrs],
"Attribute").
attributes_list(Attrs) ->
erlcloud_aws:param_list(
[[{"Name", Name}|
case Value of
{replace, V} -> [{"Value", V}, {"Replace", true}];
V -> [{"Value", V}]
end] ||
{Name, Value} <- Attrs],
"Attribute").
conditionals_list(Conditionals) ->
erlcloud_aws:param_list(
[[{"Name", Name},
case Value of
exists -> {"Exists", "true"};
not_exists -> {"Exists", "false"};
V -> {"Value", V}
end] ||
{Name, Value} <- Conditionals],
"Expected").