Skip to content

Commit

Permalink
improvement(model/kv): default empty Kv array for RangeResult
Browse files Browse the repository at this point in the history
  • Loading branch information
caspiano committed Jan 15, 2020
1 parent dd0c2a1 commit b5b7545
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 145 deletions.
2 changes: 1 addition & 1 deletion shard.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: etcd
version: 0.2.0
version: 0.2.1

authors:
- Caspian Baska <[email protected]>
Expand Down
2 changes: 1 addition & 1 deletion src/etcd/api.cr
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class Etcd::Api
when String
value.as(String)
when Bool
value.as(Bool)
value
else
value.to_s
end
Expand Down
278 changes: 140 additions & 138 deletions src/etcd/kv.cr
Original file line number Diff line number Diff line change
@@ -1,156 +1,158 @@
require "./model/kv"
require "./utils"

class Etcd::Kv
include Utils
module Etcd
class Kv
include Utils

private getter client : Etcd::Client
private getter client : Etcd::Client

def initialize(@client = Etcd::Client.new)
end

# Sets a key and value in etcd.
# key key is the string that will be base64 encoded and associated with value in the kv store String
# value value is the string that will be base64 encoded and associated with key in the kv store String
# opts
# lease lease is the lease ID to associate with the key in the key-value store. A lease value of 0 indicates no lease. Int64
# prev_kv If prev_kv is set, etcd gets the previous key-value pair before changing it.
# The previous key-value pair will be returned in the put response. Bool
# ignore_value If ignore_value is set, etcd updates the key using its current value. Returns an error if the key does not exist Bool
# ignore_lease If ignore_lease is set, etcd updates the key using its current lease. Returns an error if the key does not exist Bool
def put(
key : String,
value,
lease : Int64 = 0_i64,
prev_kv : Bool? = nil,
ignore_value : Bool? = nil,
ignore_lease : Bool? = nil
)
options = {
:key => Base64.strict_encode(key),
:value => Base64.strict_encode(value.to_s),
:lease => lease,
:prev_kv => prev_kv,
:ignore_value => ignore_value,
:ignore_lease => ignore_lease,
}.compact
response = client.api.post("/kv/put", options)

Model::PutResponse.from_json(response.body)
end

# Deletes key or range of keys
def delete(key, range_end : String? = nil, base64_keys : Bool = true)
# Otherwise bypass encoding keys
if base64_keys
key = Base64.strict_encode(key)
range_end = range_end.try &->Base64.strict_encode(String)
def initialize(@client = Etcd::Client.new)
end

post_body = {
:key => key,
:range_end => range_end,
}.compact
response = client.api.post("/kv/deleterange", post_body)

Model::DeleteResponse.from_json(response.body)
end
# Sets a key and value in etcd.
# key key is the string that will be base64 encoded and associated with value in the kv store String
# value value is the string that will be base64 encoded and associated with key in the kv store String
# opts
# lease lease is the lease ID to associate with the key in the key-value store. A lease value of 0 indicates no lease. Int64
# prev_kv If prev_kv is set, etcd gets the previous key-value pair before changing it.
# The previous key-value pair will be returned in the put response. Bool
# ignore_value If ignore_value is set, etcd updates the key using its current value. Returns an error if the key does not exist Bool
# ignore_lease If ignore_lease is set, etcd updates the key using its current lease. Returns an error if the key does not exist Bool
def put(
key : String,
value,
lease : Int64 = 0_i64,
prev_kv : Bool? = nil,
ignore_value : Bool? = nil,
ignore_lease : Bool? = nil
)
options = {
:key => Base64.strict_encode(key),
:value => Base64.strict_encode(value.to_s),
:lease => lease,
:prev_kv => prev_kv,
:ignore_value => ignore_value,
:ignore_lease => ignore_lease,
}.compact
response = client.api.post("/kv/put", options)

Model::PutResponse.from_json(response.body)
end

# Deletes an entire keyspace prefix
def delete_prefix(prefix)
encoded_prefix = Base64.strict_encode(prefix)
range_end = prefix_range_end encoded_prefix
delete(encoded_prefix, range_end, base64_keys: false)
end
# Deletes key or range of keys
def delete(key, range_end : String? = nil, base64_keys : Bool = true)
# Otherwise bypass encoding keys
if base64_keys
key = Base64.strict_encode(key)
range_end = range_end.try &->Base64.strict_encode(String)
end

post_body = {
:key => key,
:range_end => range_end,
}.compact
response = client.api.post("/kv/deleterange", post_body)

Model::DeleteResponse.from_json(response.body)
end

# Queries a range of keys
def range(key, range_end : String? = nil, base64_keys : Bool = true)
# Otherwise bypass encoding keys
if base64_keys
key = Base64.strict_encode(key)
range_end = range_end.try &->Base64.strict_encode(String)
# Deletes an entire keyspace prefix
def delete_prefix(prefix)
encoded_prefix = Base64.strict_encode(prefix)
range_end = prefix_range_end encoded_prefix
delete(encoded_prefix, range_end, base64_keys: false)
end

post_body = {
:key => key,
:range_end => range_end,
}.compact
response = client.api.post("/kv/range", post_body)
# Queries a range of keys
def range(key, range_end : String? = nil, base64_keys : Bool = true)
# Otherwise bypass encoding keys
if base64_keys
key = Base64.strict_encode(key)
range_end = range_end.try &->Base64.strict_encode(String)
end

post_body = {
:key => key,
:range_end => range_end,
}.compact
response = client.api.post("/kv/range", post_body)

Model::RangeResponse.from_json(response.body)
end

Model::RangeResponse.from_json(response.body)
end
# Query keys beneath a prefix
def range_prefix(prefix)
encoded_prefix = Base64.strict_encode(prefix)
range_end = prefix_range_end encoded_prefix
range(encoded_prefix, range_end, base64_keys: false)
end

# Query keys beneath a prefix
def range_prefix(prefix)
encoded_prefix = Base64.strict_encode(prefix)
range_end = prefix_range_end encoded_prefix
range(encoded_prefix, range_end, base64_keys: false)
end
# Query all keys >= key
def range_greater_than_or_equal(key)
encoded_key = Base64.strict_encode(key)
range_end = "\0"
range(encoded_key, range_end, base64_keys: false)
end

# Query all keys >= key
def range_greater_than_or_equal(key)
encoded_key = Base64.strict_encode(key)
range_end = "\0"
range(encoded_key, range_end, base64_keys: false)
end
# Non-Standard Requests
##############################################################################

# Non-Standard Requests
##############################################################################

# Sets a key if the key is not already present.
#
# Wrapper over the etcd transaction API.
def put_not_exists(key : String, value, lease : Int64 = 0_i64) : Bool
key = Base64.strict_encode(key)
value = Base64.strict_encode(value.to_s)
post_body = {
:compare => [{
:key => key,
:value => Base64.strict_encode("0"),
:target => "VERSION",
:result => "EQUAL",
}],
:success => [{
:request_put => {
:key => key,
:value => value,
:lease => lease,
:ignore_lease => false,
},
}],
}

response = client.api.post("/kv/txn", post_body)
Model::TxnResponse.from_json(response.body).succeeded
end
# Sets a key if the key is not already present.
#
# Wrapper over the etcd transaction API.
def put_not_exists(key : String, value, lease : Int64 = 0_i64) : Bool
key = Base64.strict_encode(key)
value = Base64.strict_encode(value.to_s)
post_body = {
:compare => [{
:key => key,
:value => Base64.strict_encode("0"),
:target => "VERSION",
:result => "EQUAL",
}],
:success => [{
:request_put => {
:key => key,
:value => value,
:lease => lease,
:ignore_lease => false,
},
}],
}

response = client.api.post("/kv/txn", post_body)
Model::TxnResponse.from_json(response.body).succeeded
end

# Sets a `key` if the given `previous_value` matches the existing value for `key`
#
# Wrapper over the etcd transaction API.
def compare_and_swap(key, value, previous_value) : Bool
key = Base64.strict_encode(key)
value = Base64.strict_encode(value.to_s)
previous_value = Base64.strict_encode(previous_value.to_s)
post_body = {
:compare => [{
:key => key,
:value => previous_value,
:target => "VALUE",
:result => "EQUAL",
}],
:success => [{
:request_put => {
:key => key,
:value => value,
},
}],
}

response = client.api.post("/kv/txn", post_body)
Model::TxnResponse.from_json(response.body).succeeded
end
# Sets a `key` if the given `previous_value` matches the existing value for `key`
#
# Wrapper over the etcd transaction API.
def compare_and_swap(key, value, previous_value) : Bool
key = Base64.strict_encode(key)
value = Base64.strict_encode(value.to_s)
previous_value = Base64.strict_encode(previous_value.to_s)
post_body = {
:compare => [{
:key => key,
:value => previous_value,
:target => "VALUE",
:result => "EQUAL",
}],
:success => [{
:request_put => {
:key => key,
:value => value,
},
}],
}

response = client.api.post("/kv/txn", post_body)
Model::TxnResponse.from_json(response.body).succeeded
end

def get(key) : String?
result = range(key)
result.try(&.kvs).try(&.first?).try(&.value)
def get(key) : String?
range(key).kvs.first?.try(&.value)
end
end
end
10 changes: 5 additions & 5 deletions src/etcd/model/kv.cr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module Etcd::Model
@[JSON::Field(converter: Etcd::Model::Base64Converter)]
getter key : String
@[JSON::Field(converter: Etcd::Model::Base64Converter)]
getter value : String?
getter value : String
@[JSON::Field(converter: Etcd::Model::StringTypeConverter(UInt64))]
getter create_revision : UInt64?
@[JSON::Field(converter: Etcd::Model::StringTypeConverter(UInt64))]
Expand All @@ -19,8 +19,8 @@ module Etcd::Model
class RangeResponse < Base
getter header : Header?
@[JSON::Field(converter: Etcd::Model::StringTypeConverter(Int32))]
getter count : Int32?
getter kvs : Array(Kv)?
getter count : Int32 = 0
getter kvs : Array(Etcd::Model::Kv) = [] of Etcd::Model::Kv
end

class PutResponse < Base
Expand All @@ -31,8 +31,8 @@ module Etcd::Model
class DeleteResponse < Base
getter header : Header
@[JSON::Field(converter: Etcd::Model::StringTypeConverter(Int32))]
getter deleted : Int32?
getter prev_kvs : Array(Kv)?
getter deleted : Int32 = 0
getter prev_kvs : Array(Etcd::Model::Kv) = [] of Etcd::Model::Kv
end

class TxnResponse < Base
Expand Down

0 comments on commit b5b7545

Please sign in to comment.