Class: SkyDB::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/skydb/client.rb

Defined Under Namespace

Classes: ServerError

Constant Summary collapse

DEFAULT_HOST =

The default host to connect to if one is not specified.

'localhost'
DEFAULT_PORT =

The default port to connect to if one is not specified.

8585

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Client

Initializes the client.



38
39
40
41
# File 'lib/skydb/client.rb', line 38

def initialize(options={})
  self.host = options[:host] || DEFAULT_HOST
  self.port = options[:port] || DEFAULT_PORT
end

Instance Attribute Details

#hostObject

The name of the host to conect to.



51
52
53
# File 'lib/skydb/client.rb', line 51

def host
  @host
end

#portObject

The port on the host to connect to.



54
55
56
# File 'lib/skydb/client.rb', line 54

def port
  @port
end

Instance Method Details

#add_event(table, object_id, event, options = {}) ⇒ Event

Adds an event to an object.

Parameters:

  • table (Table)

    the table the object belongs to.

  • object_id (String)

    the object’s identifier.

  • event (Event)

    the event to add.

Returns:

Raises:

  • (ArgumentError)


200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/skydb/client.rb', line 200

def add_event(table, object_id, event, options={})
  options = {:method => :merge}.merge(options)
  
  raise ArgumentError.new("Table required") if table.nil?
  raise ArgumentError.new("Object identifier required") if object_id.nil?
  raise ArgumentError.new("Event required") if event.nil?
  event = Event.new(event) if event.is_a?(Hash)
  raise ArgumentError.new("Event timestamp required") if event.timestamp.nil?

  # The insertion method is communicated to the server through the HTTP method.
  http_method = case options[:method]
    when :replace then :put
    when :merge then :patch
    else raise ArgumentError.new("Invalid event insertion method: #{options[:method]}")
    end

  # Send the event and parse it when it comes back. It could have changed.
  data = send(http_method, "/tables/#{table.name}/objects/#{object_id}/events/#{SkyDB.format_timestamp(event.timestamp)}", event.to_hash)
  return event.from_hash(data)
end

#create_property(table, property, options = {}) ⇒ Object

Creates a property on a table.

Parameters:

  • property (Property)

    the property to create.

Raises:

  • (ArgumentError)


134
135
136
137
138
139
140
# File 'lib/skydb/client.rb', line 134

def create_property(table, property, options={})
  raise ArgumentError.new("Table required") if table.nil?
  raise ArgumentError.new("Property required") if property.nil?
  property = Property.new(property) if property.is_a?(Hash)
  data = send(:post, "/tables/#{table.name}/properties", property.to_hash)
  return property.from_hash(data)
end

#create_table(table, options = {}) ⇒ Object

Creates a table on the server.

Parameters:

  • table (Table)

    the table to create.

Raises:

  • (ArgumentError)


85
86
87
88
89
90
91
# File 'lib/skydb/client.rb', line 85

def create_table(table, options={})
  raise ArgumentError.new("Table required") if table.nil?
  table = Table.new(table) if table.is_a?(Hash)
  table.client = self
  data = send(:post, "/tables", table.to_hash)
  return table.from_hash(data)
end

#delete_event(table, object_id, event, options = {}) ⇒ Object

Deletes an event for an object on a table.

Parameters:

  • table (Table)

    the table the object belongs to.

  • object_id (String)

    the object’s identifier.

  • event (Event)

    the event to delete.

Raises:

  • (ArgumentError)


226
227
228
229
230
231
232
233
234
# File 'lib/skydb/client.rb', line 226

def delete_event(table, object_id, event, options={})
  raise ArgumentError.new("Table required") if table.nil?
  raise ArgumentError.new("Object identifier required") if object_id.nil?
  raise ArgumentError.new("Event required") if event.nil?
  event = Event.new(event) if event.is_a?(Hash)
  raise ArgumentError.new("Event timestamp required") if event.timestamp.nil?
  send(:delete, "/tables/#{table.name}/objects/#{object_id}/events/#{SkyDB.format_timestamp(event.timestamp)}")
  return nil
end

#delete_property(table, property, options = {}) ⇒ Object

Deletes a property on a table.

Parameters:

  • property (Property)

    the property to delete.

Raises:

  • (ArgumentError)


157
158
159
160
161
162
163
164
# File 'lib/skydb/client.rb', line 157

def delete_property(table, property, options={})
  raise ArgumentError.new("Table required") if table.nil?
  raise ArgumentError.new("Property required") if property.nil?
  raise ArgumentError.new("Property name required") if property.name.to_s == ''
  property = Property.new(property) if property.is_a?(Hash)
  send(:delete, "/tables/#{table.name}/properties/#{property.name}")
  return nil
end

#delete_table(table, options = {}) ⇒ Object

Deletes a table on the server.

Parameters:

  • table (Table)

    the table to delete.

Raises:

  • (ArgumentError)


96
97
98
99
100
101
102
# File 'lib/skydb/client.rb', line 96

def delete_table(table, options={})
  raise ArgumentError.new("Table required") if table.nil?
  table = Table.new(table) if table.is_a?(Hash)
  table.client = self
  send(:delete, "/tables/#{table.name}")
  return nil
end

#get_event(table, object_id, timestamp, options = {}) ⇒ Event

Retrieves the event that occurred at a given point in time for an object.

Returns:

Raises:

  • (ArgumentError)


185
186
187
188
189
190
191
# File 'lib/skydb/client.rb', line 185

def get_event(table, object_id, timestamp, options={})
  raise ArgumentError.new("Table required") if table.nil?
  raise ArgumentError.new("Object identifier required") if object_id.nil?
  raise ArgumentError.new("Timestamp required") if timestamp.nil?
  data = send(:get, "/tables/#{table.name}/objects/#{object_id}/events/#{SkyDB.format_timestamp(timestamp)}")
  return Event.new().from_hash(data)
end

#get_events(table, object_id, options = {}) ⇒ Array

Retrieves all events for a given object.

Returns:

  • (Array)

    the list of events on the table.

Raises:

  • (ArgumentError)


174
175
176
177
178
179
180
# File 'lib/skydb/client.rb', line 174

def get_events(table, object_id, options={})
  raise ArgumentError.new("Table required") if table.nil?
  raise ArgumentError.new("Object identifier required") if object_id.nil?
  events = send(:get, "/tables/#{table.name}/objects/#{object_id}/events")
  events.map!{|e| Event.new().from_hash(e)}
  return events
end

#get_properties(table, options = {}) ⇒ Array

Retrieves a list of all properties on a table.

Returns:

  • (Array)

    the list of properties on the table.

Raises:

  • (ArgumentError)


112
113
114
115
116
117
# File 'lib/skydb/client.rb', line 112

def get_properties(table, options={})
  raise ArgumentError.new("Table required") if table.nil?
  properties = send(:get, "/tables/#{table.name}/properties")
  properties.map!{|p| Property.new().from_hash(p)}
  return properties
end

#get_property(table, name, options = {}) ⇒ Array

Retrieves a single property by name.

Parameters:

  • table (Table)

    The table to retrieve from.

  • name (String)

    The name of the property to retrieve.

Returns:

  • (Array)

    the list of properties on the table.

Raises:

  • (ArgumentError)


125
126
127
128
129
# File 'lib/skydb/client.rb', line 125

def get_property(table, name, options={})
  raise ArgumentError.new("Table required") if table.nil?
  data = send(:get, "/tables/#{table.name}/properties/#{name}")
  return Property.new().from_hash(data)
end

#get_table(name, options = {}) ⇒ Object

Retrieves a single table from the server.

Raises:

  • (ArgumentError)


75
76
77
78
79
80
# File 'lib/skydb/client.rb', line 75

def get_table(name, options={})
  raise ArgumentError.new("Table name required") if name.nil?
  data = send(:get, "/tables/#{name}")
  table = Table.new(:client => self).from_hash(data)
  return table
end

#get_tables(options = {}) ⇒ Object

Retrieves a list of tables on the server.



68
69
70
71
72
# File 'lib/skydb/client.rb', line 68

def get_tables(options={})
  data = send(:get, "/tables")
  tables = data.map {|i| Table.new(:client => self).from_hash(i)}
  return tables
end

#ping(options = {}) ⇒ Boolean

Pings the server to determine if it is running.

Returns:

  • (Boolean)

    true if the server is running, otherwise false.



262
263
264
265
266
267
268
269
# File 'lib/skydb/client.rb', line 262

def ping(options={})
  begin
    send(:get, "/ping")
  rescue
    return false
  end
  return true
end

#query(table, q) ⇒ Results

Runs a query against a given table.

Parameters:

  • table (Table)

    The table to query.

  • q (Hash)

    The query definition to run.

Returns:

  • (Results)

    the results of the query.

Raises:

  • (ArgumentError)


247
248
249
250
251
252
# File 'lib/skydb/client.rb', line 247

def query(table, q)
  raise ArgumentError.new("Table required") if table.nil?
  raise ArgumentError.new("Query definition required") if q.nil?
  q = {:steps => q} if q.is_a?(Array)
  return send(:post, "/tables/#{table.name}/query", q)
end

#send(method, path, data = nil) ⇒ Object

Executes a RESTful JSON over HTTP POST.



277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/skydb/client.rb', line 277

def send(method, path, data=nil)
  # Generate a JSON request.
  request = case method
    when :get then Net::HTTP::Get.new(path)
    when :post then Net::HTTP::Post.new(path)
    when :patch then Net::HTTP::Patch.new(path)
    when :put then Net::HTTP::Put.new(path)
    when :delete then Net::HTTP::Delete.new(path)
    end
  request.add_field('Content-Type', 'application/json')
  request.body = JSON.generate(data, :max_nesting => 200) unless data.nil?
  response = Net::HTTP.new(host, port).start {|http| http.request(request) }
  
  # Parse the body as JSON.
  json = JSON.parse(response.body) rescue nil
  message = json['message'] rescue nil
  
  warn("#{method.to_s.upcase} #{path}: #{request.body} -> #{response.body}") if SkyDB.debug

  # Process based on the response code.
  case response
  when Net::HTTPSuccess then
    return json
  else
    e = ServerError.new(message)
    e.status = response.code
    raise e
  end
end

#update_property(table, property, options = {}) ⇒ Object

Updates a property on a table.

Parameters:

  • property (Property)

    the property to update.

Raises:

  • (ArgumentError)


145
146
147
148
149
150
151
152
# File 'lib/skydb/client.rb', line 145

def update_property(table, property, options={})
  raise ArgumentError.new("Table required") if table.nil?
  raise ArgumentError.new("Property required") if property.nil?
  raise ArgumentError.new("Property name required") if property.name.to_s == ''
  property = Property.new(property) if property.is_a?(Hash)
  data = send(:patch, "/tables/#{table.name}/properties/#{property.name}", property.to_hash)
  return property.from_hash(data)
end