Module: Gcloud::GRPCUtils

Defined in:
lib/gcloud/grpc_utils.rb,
lib/gcloud/datastore/grpc_utils.rb

Overview

This file adds Datastore methods to GRPCUtils.

Constant Summary collapse

PROP_FILTER_OPS =

rubocop:disable all

{ "<"            => :LESS_THAN,
"lt"           => :LESS_THAN,
"<="           => :LESS_THAN_OR_EQUAL,
"lte"          => :LESS_THAN_OR_EQUAL,
">"            => :GREATER_THAN,
"gt"           => :GREATER_THAN,
">="           => :GREATER_THAN_OR_EQUAL,
"gte"          => :GREATER_THAN_OR_EQUAL,
"="            => :EQUAL,
"eq"           => :EQUAL,
"eql"          => :EQUAL,
"~"            => :HAS_ANCESTOR,
"~>"           => :HAS_ANCESTOR,
"ancestor"     => :HAS_ANCESTOR,
"has_ancestor" => :HAS_ANCESTOR,
"has ancestor" => :HAS_ANCESTOR }

Class Method Summary collapse

Class Method Details

.decode_bytes(bytes) ⇒ Object



126
127
128
# File 'lib/gcloud/datastore/grpc_utils.rb', line 126

def self.decode_bytes bytes
  bytes.to_s.unpack("m").first.force_encoding Encoding::ASCII_8BIT
end

.encode_bytes(bytes) ⇒ Object



122
123
124
# File 'lib/gcloud/datastore/grpc_utils.rb', line 122

def self.encode_bytes bytes
  Array(bytes.to_s).pack("m").chomp.encode("ASCII-8BIT")
end

.from_value(grpc_value) ⇒ Object

Gets an object from a Google::Datastore::V1beta3::Value.



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/gcloud/datastore/grpc_utils.rb', line 52

def self.from_value grpc_value
  if grpc_value.value_type == :null_value
    return nil
  elsif grpc_value.value_type == :key_value
    return Gcloud::Datastore::Key.from_grpc(grpc_value.key_value)
  elsif grpc_value.value_type == :entity_value
    return Gcloud::Datastore::Entity.from_grpc(grpc_value.entity_value)
  elsif grpc_value.value_type == :boolean_value
    return grpc_value.boolean_value
  elsif grpc_value.value_type == :double_value
    return grpc_value.double_value
  elsif grpc_value.value_type == :integer_value
    return grpc_value.integer_value
  elsif grpc_value.value_type == :string_value
    return grpc_value.string_value
  elsif grpc_value.value_type == :array_value
    return Array(grpc_value.array_value.values).map { |v| from_value v }
  elsif grpc_value.value_type == :timestamp_value
    return Time.at grpc_value.timestamp_value.seconds,
                   grpc_value.timestamp_value.nanos/1000.0
  elsif grpc_value.value_type == :geo_point_value
    return grpc_value.geo_point_value.to_hash
  elsif grpc_value.value_type == :blob_value
    return StringIO.new(grpc_value.blob_value.force_encoding("ASCII-8BIT"))
  else
    nil
  end
end

.hash_to_struct(hash) ⇒ Object



25
26
27
28
29
# File 'lib/gcloud/grpc_utils.rb', line 25

def self.hash_to_struct hash
  # TODO: ArgumentError if hash is not a Hash
  Google::Protobuf::Struct.new fields:
    Hash[hash.map { |k, v| [String(k), object_to_value(v)] }]
end

.map_to_hash(map) ⇒ Object



78
79
80
81
82
83
84
85
# File 'lib/gcloud/grpc_utils.rb', line 78

def self.map_to_hash map
  if map.respond_to? :to_h
    map.to_h
  else
    # Enumerable doesn't have to_h on ruby 2.0...
    Hash[map.to_a]
  end
end

.object_to_value(obj) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/gcloud/grpc_utils.rb', line 59

def self.object_to_value obj
  case obj
  when String then Google::Protobuf::Value.new string_value: obj
  when Array then Google::Protobuf::ListValue.new(values:
    obj.map { |o| object_to_value(o) })
  when Hash then Google::Protobuf::Value.new struct_value:
    hash_to_struct(obj)
  when Numeric then Google::Protobuf::Value.new number_value: obj
  when TrueClass then Google::Protobuf::Value.new bool_value: true
  when FalseClass then Google::Protobuf::Value.new bool_value: false
  when NilClass then Google::Protobuf::Value.new null_value: :NULL_VALUE
  else
    # We could raise ArgumentError here, or we could convert to a string...
    Google::Protobuf::Value.new string_value: obj.to_s
  end
end

.struct_to_hash(struct) ⇒ Object



33
34
35
36
# File 'lib/gcloud/grpc_utils.rb', line 33

def self.struct_to_hash struct
  # TODO: ArgumentError if struct is not a Google::Protobuf::Struct
  Hash[struct.fields.map { |k, v| [k, value_to_object(v)] }]
end

.to_prop_filter_op(op) ⇒ Object

Get a property filter operator from op



46
47
48
# File 'lib/gcloud/datastore/grpc_utils.rb', line 46

def self.to_prop_filter_op op
  PROP_FILTER_OPS[op.to_s.downcase] || :EQUAL
end

.to_value(value) ⇒ Object

Stores an object into a Google::Datastore::V1beta3::Value.



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/gcloud/datastore/grpc_utils.rb', line 83

def self.to_value value
  v = Google::Datastore::V1beta3::Value.new
  if NilClass === value
    v.null_value = :NULL_VALUE
  elsif TrueClass === value
    v.boolean_value = true
  elsif FalseClass === value
    v.boolean_value = false
  elsif Integer === value
    v.integer_value = value
  elsif Float === value
    v.double_value = value
  elsif defined?(BigDecimal) && BigDecimal === value
    v.double_value = value
  elsif Gcloud::Datastore::Key === value
    v.key_value = value.to_grpc
  elsif Gcloud::Datastore::Entity === value
    v.entity_value = value.to_grpc
  elsif String === value
    v.string_value = value
  elsif Array === value
    v.array_value = Google::Datastore::V1beta3::ArrayValue.new(
      values: value.map { |v| to_value v }
    )
  elsif value.respond_to? :to_time
    v.timestamp_value = Google::Protobuf::Timestamp.new(
      seconds: value.to_time.to_i, nanos: value.to_time.nsec)
  elsif value.respond_to?(:to_hash) && value.keys.sort == [:latitude, :longitude]
    v.geo_point_value = Google::Type::LatLng.new(value)
  elsif value.respond_to?(:read) && value.respond_to?(:rewind)
    value.rewind
    v.blob_value = value.read.force_encoding("ASCII-8BIT")
  else
    fail Gcloud::Datastore::PropertyError,
         "A property of type #{value.class} is not supported."
  end
  v
end

.value_to_object(value) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/gcloud/grpc_utils.rb', line 40

def self.value_to_object value
  # TODO: ArgumentError if struct is not a Google::Protobuf::Value
  if value.null_value
    nil
  elsif value.number_value
    value.number_value
  elsif value.struct_value
    struct_to_hash value.struct_value
  elsif value.list_value
    value.list_value.values.map { |v| value_to_object(v) }
  elsif !value.bool_value.nil? # Make sure its a bool, not nil
    value.bool_value
  else
    nil # just in case
  end
end