crate_ruby 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 89005d37bce3036b7cc74a9cf521a85493f8695e
4
- data.tar.gz: d92405d8c41d5c191cd6a943cc45a3227fd2c01b
3
+ metadata.gz: 4a726eb5a922ba00e842ae5128897f44ebc348ed
4
+ data.tar.gz: 0d3d601ffb7c5bbecfd3c6f80a55905b434559e7
5
5
  SHA512:
6
- metadata.gz: 7fc3c5596813c4de4565c91f4d4a8b8ff5447143a66734956fbf342d997209cde01b042949721184868948c916e0beabd0a985353722bbc7c5d7e17b5afce279
7
- data.tar.gz: f7dd74c16239b2e5f6bb5811529c44513b184c77a4849bf45431c4e3ddfa1bf6ebcb121ca71c4b044886f545ee48d1b02bf8cfdff7374b064877e50dcfec3d40
6
+ metadata.gz: 5a55318fc2253b2244ffe7ec3fa88496903ed9f42171b7b1b036f002ffd69e3e7781836678e5e7a1362cc2f20e79c44e3f2c6b69c5dbf5114ec26eade980c578
7
+ data.tar.gz: b09c8a6e7d4449746105721e8cc3903f7c18cd2231f2359c5e749cdc43f3af5c5c01a3197356d8e04d14c060b20ec2b6bc550ee912c32c723f8590e5650768e8
data/.gitignore CHANGED
@@ -18,3 +18,4 @@ tmp
18
18
  .idea/*
19
19
  .rvmrc
20
20
  log/crate.log
21
+ crate_test_server.*
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # CrateRuby
2
2
 
3
- Official ruby library to access a (Crate)[http://crate.io] database.
3
+ Official Ruby library to access a [Crate](http://crate.io) database.
4
4
 
5
5
  ## Installation
6
6
 
@@ -8,10 +8,6 @@ Add this line to your application's Gemfile:
8
8
 
9
9
  gem 'crate_ruby'
10
10
 
11
- And then execute:
12
-
13
- $ bundle
14
-
15
11
  Or install it yourself as:
16
12
 
17
13
  $ gem install crate_ruby
@@ -21,13 +17,15 @@ Or install it yourself as:
21
17
  ### Issueing SQL statements
22
18
  require 'crate_ruby'
23
19
 
24
- # optional args :host, :port, :logger
25
20
  client = CrateRuby::Client.new
21
+
26
22
  result = client.execute("Select * from posts")
27
23
  => #<CrateRuby::ResultSet:0x00000002a9c5e8 @rowcount=1, @duration=5>
24
+
28
25
  result.each do |row|
29
- puts row.inspect # [1, "test", 5]
26
+ puts row.inspect
30
27
  end
28
+ => [1, "test", 5]
31
29
 
32
30
  result.cols
33
31
  => ["id", "my_column", "my_integer_col"]
@@ -48,11 +46,26 @@ Or install it yourself as:
48
46
  #deletion
49
47
  client.blob_delete(table_name, digest)
50
48
 
49
+ ## Tests
50
+
51
+ To run the tests start up the crate server first
52
+
53
+ ruby spec/test_server.rb
54
+
51
55
  ## Contributing
52
56
 
53
- 1. Fork it ( http://github.com/<my-github-username>/crate_ruby/fork )
57
+ 1. Fork it ( `http://github.com/crate /crate_ruby/fork` )
54
58
  2. Create your feature branch (`git checkout -b my-new-feature`)
55
59
  3. Add some tests
56
60
  4. Commit your changes (`git commit -am 'Add some feature'`)
57
61
  5. Push to the branch (`git push origin my-new-feature`)
58
62
  6. Create new Pull Request
63
+
64
+ ##Maintainer
65
+
66
+ * [Christoph Klocker](http://www.vedanova.com), [@corck](http://www.twitter.com/corck)
67
+
68
+ ##License
69
+
70
+ MIT License. Copyright 2014 Vedanova. [http://vedanova.com](http://vedanova.com)
71
+
data/lib/crate_ruby.rb CHANGED
@@ -10,7 +10,7 @@ module CrateRuby
10
10
  @logger ||= begin
11
11
  require 'logger'
12
12
  log = Logger.new(File.join(File.dirname(__FILE__), "../log/crate.log"), 10, 1024000)
13
- log.level = Logger::DEBUG
13
+ log.level = Logger::INFO
14
14
  log
15
15
  end
16
16
  end
@@ -11,6 +11,7 @@ module CrateRuby
11
11
  # @param [Array] servers An Array of servers including ports [127.0.0.1:4200, 10.0.0.1:4201]
12
12
  # @param [opts] Optional paramters
13
13
  # * logger: Custom Logger
14
+ # @return [CrateRuby::Client]
14
15
  def initialize(servers = [], opts = {})
15
16
  @servers = servers
16
17
  @servers << "#{DEFAULT_HOST}:#{DEFAULT_PORT}" if servers.empty?
@@ -18,7 +19,7 @@ module CrateRuby
18
19
  end
19
20
 
20
21
  def inspect
21
- %Q{#<CrateRuby::Client:#{object_id}, @uri="#{@uri}">}
22
+ %Q{#<CrateRuby::Client:#{object_id}>}
22
23
  end
23
24
 
24
25
  # Creates a table
@@ -26,7 +27,7 @@ module CrateRuby
26
27
  # @param [String] table_name
27
28
  # @param [Hash] column_definition
28
29
  # @option column_definition [String] key sets column name, value sets column type. an array passed as value can be used to set options like primary keys
29
- # @return [Boolean]
30
+ # @return [ResultSet]
30
31
  #
31
32
  def create_table(table_name, column_definition = {}, blob=false)
32
33
  cols = column_definition.to_a.map { |a| a.join(' ') }.join(', ')
@@ -38,7 +39,7 @@ module CrateRuby
38
39
  # @param [String] name Table name
39
40
  # @param [Integer] shard Shard count, defaults to 5
40
41
  # @param [Integer] number Number of replicas, defaults to 0
41
- # @return [Boolean]
42
+ # @return [ResultSet]
42
43
  #
43
44
  # client.create_blob_table("blob_table")
44
45
  def create_blob_table(name, shard_count=5, replicas=0)
@@ -49,7 +50,7 @@ module CrateRuby
49
50
  # Drop table
50
51
  # @param [String] table_name, Name of table to drop
51
52
  # @param [Boolean] blob Needs to be set to true if table is a blob table
52
- # @return [Boolean]
53
+ # @return [ResultSet]
53
54
  def drop_table(table_name, blob=false)
54
55
  tbl = blob ? "BLOB TABLE" : "TABLE"
55
56
  stmt = %Q{DROP #{tbl} "#{table_name}"}
@@ -59,25 +60,30 @@ module CrateRuby
59
60
  # List all user tables
60
61
  # @return [ResultSet]
61
62
  def show_tables
62
- execute("select * from information_schema.tables where schema_name = 'doc'")
63
+ execute("select table_name from information_schema.tables where schema_name = 'doc'")
64
+ end
65
+
66
+ # Returns all tables in schema 'doc'
67
+ # @return [Array] Array of table names
68
+ def tables
69
+ execute("select table_name from information_schema.tables where schema_name = 'doc'").map(&:first)
63
70
  end
64
71
 
65
72
  # Executes a SQL statement against the Crate HTTP REST endpoint.
66
73
  # @param [String] sql statement to execute
67
- # @return [ResultSet, false]
74
+ # @return [ResultSet]
68
75
  def execute(sql)
76
+ @logger.debug sql
69
77
  req = Net::HTTP::Post.new("/_sql", initheader = {'Content-Type' => 'application/json'})
70
78
  req.body = {"stmt" => sql}.to_json
71
79
  response = request(req)
80
+ @logger.debug response.body
72
81
  success = case response.code
73
- when "200"
82
+ when /^2\d{2}/
74
83
  ResultSet.new response.body
75
- when "400"
76
- @logger.info(response.body)
77
- false
78
84
  else
79
85
  @logger.info(response.body)
80
- false
86
+ raise CrateRuby::CrateError.new(response.body)
81
87
  end
82
88
  success
83
89
  end
@@ -141,6 +147,30 @@ module CrateRuby
141
147
  success
142
148
  end
143
149
 
150
+
151
+ # Return the table structure
152
+ # @param [String] table_name Table name to get structure
153
+ # @param [ResultSet]
154
+ def table_structure(table_name)
155
+ execute("select * from information_schema.columns where schema_name = 'doc' AND table_name = '#{table_name}'")
156
+ end
157
+
158
+
159
+ def insert(table_name, attributes)
160
+ vals = attributes.values.map { |x| x.is_a?(String) ? "'#{x}'" : x }.join(', ')
161
+ stmt = %Q{INSERT INTO "#{table_name}" (#{attributes.keys.join(', ')}) VALUES (#{vals})}
162
+ execute(stmt)
163
+ end
164
+
165
+ # Crate is eventually consistent, If you don't query by primary key,
166
+ # it is not guaranteed that an insert record is found on the next
167
+ # query. Default refresh value is 1000ms.
168
+ # Using refresh_table you can force a refresh
169
+ # @param [String] table_name Name of table to refresh
170
+ def refresh_table(table_name)
171
+ execute "refresh table #{table_name}"
172
+ end
173
+
144
174
  private
145
175
 
146
176
  def blob_path(table, digest)
@@ -151,7 +181,7 @@ module CrateRuby
151
181
  host, port = @servers.first.split(':');
152
182
  Net::HTTP.new(host, port)
153
183
  end
154
-
184
+
155
185
  def request(req)
156
186
  connection.start { |http| http.request(req) }
157
187
  end
@@ -4,7 +4,7 @@ module CrateRuby
4
4
 
5
5
  attr_reader :rowcount, :duration, :cols
6
6
 
7
- # @param [String] Crate result
7
+ # @param [String] result
8
8
  def initialize(result)
9
9
  result = JSON.parse(result)
10
10
  @cols = result['cols']
@@ -23,13 +23,17 @@ module CrateRuby
23
23
 
24
24
  def each(&block)
25
25
  @rows.each(&block)
26
- nil
27
26
  end
28
27
 
29
28
  def [](val)
30
29
  @rows[val]
31
30
  end
32
31
 
32
+ # @return [Array] Returns all rows as Array of arrays
33
+ def values
34
+ @rows
35
+ end
36
+
33
37
  # @param [Array] ary Column names to filer on
34
38
  # @return [Array] Filtered rows
35
39
  def select_columns(ary, &block)
@@ -1,3 +1,3 @@
1
1
  module CrateRuby
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -1,47 +1,46 @@
1
1
  require_relative '../spec_helper'
2
2
 
3
3
  describe CrateRuby::Client do
4
+ TABLE_NAME = 'blob_table'
4
5
  describe '#create_table' do
5
- let(:client) { CrateRuby::Client.new }
6
+ let(:client) { CrateRuby::Client.new(["localhost:#{TEST_PORT}"]) }
6
7
 
7
- describe 'blob mangament' do
8
- let(:table_name) { 'blob_table' }
8
+ describe 'blob management' do
9
9
  let(:file) { 'logo-crate.png' }
10
- #let(:file) { 'text.txt' }
11
10
  let(:path) { File.join(File.dirname(__FILE__), '../uploads/') }
12
11
  let(:file_path) { File.join(path, file) }
13
12
  let(:digest) { Digest::SHA1.file(file_path).hexdigest }
14
13
  let(:store_location) { File.join(path, "get_#{file}") }
15
14
 
16
- before do
17
- client.execute("create blob TABLE #{table_name}")
15
+ before(:all) do
16
+ CrateRuby::Client.new(["localhost:#{TEST_PORT}"]).execute("create blob TABLE #{TABLE_NAME}")
18
17
  end
19
18
 
20
- after do
21
- client.execute("drop blog TABLE #{table_name}")
19
+ after(:all) do
20
+ CrateRuby::Client.new(["localhost:#{TEST_PORT}"]).execute("drop blob TABLE #{TABLE_NAME}")
22
21
  end
23
22
 
24
23
  describe '#blob_put' do
25
24
 
26
25
  after do
27
- client.blob_delete(table_name, digest)
26
+ client.blob_delete(TABLE_NAME, digest)
28
27
  end
29
28
 
30
29
  context 'file' do
31
30
 
32
31
  it 'should upload a file to the blob table' do
33
32
  f = File.read(file_path)
34
- client.blob_put(table_name, digest, f).should be_true
33
+ client.blob_put(TABLE_NAME, digest, f).should be_true
35
34
  end
36
35
  end
37
36
 
38
37
  context '#string' do
39
- let(:string) {"my crazy"}
40
- let(:digest) {Digest::SHA1.hexdigest(string)}
38
+ let(:string) { "my crazy" }
39
+ let(:digest) { Digest::SHA1.hexdigest(string) }
41
40
 
42
41
  it 'should upload a string to the blob table' do
43
- client.blob_delete(table_name, digest)
44
- client.blob_put table_name, digest, string
42
+ client.blob_delete(TABLE_NAME, digest)
43
+ client.blob_put TABLE_NAME, digest, string
45
44
  end
46
45
  end
47
46
  end
@@ -50,11 +49,11 @@ describe CrateRuby::Client do
50
49
 
51
50
  before do
52
51
  f = File.read(file_path)
53
- client.blob_put(table_name, digest, f)
52
+ client.blob_put(TABLE_NAME, digest, f)
54
53
  end
55
54
 
56
55
  it 'should download a blob' do
57
- data = client.blob_get(table_name, digest)
56
+ data = client.blob_get(TABLE_NAME, digest)
58
57
  data.should_not be_false
59
58
  open(store_location, "wb") { |file|
60
59
  file.write(data)
@@ -62,31 +61,31 @@ describe CrateRuby::Client do
62
61
  end
63
62
 
64
63
  after do
65
- client.blob_delete(table_name, digest)
64
+ client.blob_delete(TABLE_NAME, digest)
66
65
  end
67
66
  end
68
67
 
69
68
  describe '#blob_delete' do
70
69
  before do
71
70
  f = File.read(file_path)
72
- client.blob_put(table_name, digest, f)
71
+ client.blob_put(TABLE_NAME, digest, f)
73
72
  end
74
73
 
75
74
  it 'should delete a blob' do
76
- client.blob_delete(table_name, digest)
75
+ client.blob_delete(TABLE_NAME, digest)
77
76
  end
78
77
  end
79
78
  end
80
79
 
81
80
  describe '#execute' do
82
- let(:table_name) { "post" }
81
+ let(:TABLE_NAME) { "post" }
83
82
 
84
83
  after do
85
- client.execute("drop TABLE #{table_name}").should be_true
84
+ client.execute("drop TABLE #{TABLE_NAME}").should be_true
86
85
  end
87
86
 
88
87
  it 'should create a new table' do
89
- client.execute("CREATE TABLE #{table_name} (id int)").should be_true
88
+ client.execute("CREATE TABLE #{TABLE_NAME} (id int)").should be_true
90
89
  end
91
90
 
92
91
  end
@@ -96,10 +95,54 @@ describe CrateRuby::Client do
96
95
 
97
96
  it 'should use host and ports parameters' do
98
97
  logger = double()
99
- client = CrateRuby::Client.new ["10.0.0.1:5000"],logger: logger
98
+ client = CrateRuby::Client.new ["10.0.0.1:5000"], logger: logger
100
99
  client.instance_variable_get(:@servers).should eq(["10.0.0.1:5000"])
101
100
  end
101
+ end
102
+
103
+ describe '#tables' do
104
+ before do
105
+ client.create_table "posts", id: :integer
106
+ client.create_table "comments", id: :integer
107
+ end
108
+
109
+ after do
110
+ client.drop_table "posts"
111
+ client.drop_table "comments"
112
+ end
113
+
114
+ it 'should return all user tables as an array of string values' do
115
+ client.tables.should eq ['posts', 'comments']
116
+ end
117
+ end
102
118
 
119
+
120
+ describe '#insert' do
121
+ before do
122
+ client.create_table("posts", id: [:string, "primary key"],
123
+ title: :string,
124
+ views: :integer)
125
+ end
126
+
127
+ after do
128
+ client.drop_table "posts"
129
+ end
130
+
131
+ it 'should insert the record' do
132
+ expect do
133
+ client.insert('posts', id: SecureRandom.uuid, title: "Test" )
134
+ sleep(1)
135
+ result_set = client.execute("Select * from posts where title = 'Test'")
136
+ result_set.rowcount.should eq 1
137
+ end.not_to raise_exception
138
+ end
139
+ end
140
+
141
+ describe '#refresh table' do
142
+ it 'should issue the proper refresh statment' do
143
+ client.should_receive(:execute).with("refresh table posts")
144
+ client.refresh_table('posts')
145
+ end
103
146
  end
104
147
 
105
148
  end
@@ -56,6 +56,12 @@ describe ResultSet do
56
56
  end
57
57
  end
58
58
 
59
+ describe '#values' do
60
+ it 'should return all rows as an array of arrays' do
61
+ result_set.values.should eq json_result['rows']
62
+ end
63
+ end
64
+
59
65
  end
60
66
 
61
67
 
data/spec/spec_helper.rb CHANGED
@@ -1 +1,2 @@
1
1
  require_relative '../lib/crate_ruby'
2
+ TEST_PORT = 4209
@@ -0,0 +1,70 @@
1
+ require 'net/http'
2
+ class TestServer
3
+ CRATE_PATH = "~/crate"
4
+ TEST_PORT = 4209
5
+ NAME = "TestCluster"
6
+
7
+
8
+ def initialize(crate_home = nil, port = nil, host = "127.0.0.1")
9
+ @crate_home = crate_home || CRATE_PATH
10
+ @port = port || TEST_PORT
11
+ @host = host
12
+ end
13
+
14
+ def start
15
+ cmd = "sh #{CRATE_PATH}/bin/crate #{start_params}"
16
+ @pid = spawn(cmd, :out => "/tmp/crate_test_server.out", :err => "/tmp/crate_test_server.err")
17
+ Process.detach(@pid)
18
+ puts 'starting'
19
+ time_slept = 0
20
+ while true
21
+ puts "Crate not yet fully available. Waiting since #{time_slept} seconds..." unless alive?
22
+ sleep(2)
23
+ time_slept += 2
24
+ end
25
+ end
26
+
27
+ def stop
28
+ Process.kill("HUP", @pid)
29
+ end
30
+
31
+ private
32
+
33
+
34
+ def crate_exec
35
+ end
36
+
37
+ def crate_config
38
+ end
39
+
40
+ def start_params
41
+ "-Des.index.storage.type=memory " +
42
+ "-Des.node.name=#{NAME} " +
43
+ "-Des.cluster.name=Testing#{@port} " +
44
+ "-Des.http.port=#{@port}-#{@port} " +
45
+ "-Des.network.host=localhost " +
46
+ "-Des.discovery.type=zen " +
47
+ "-Des.discovery.zen.ping.multicast.enabled=false"
48
+ end
49
+
50
+ def alive?
51
+ req = Net::HTTP::Get.new('/')
52
+ resp = Net::HTTP.new(@host, @port)
53
+ begin
54
+ response = resp.start { |http| http.request(req) }
55
+ response.code == "200" ? true : false
56
+ rescue Errno::ECONNREFUSED
57
+ false
58
+ end
59
+ end
60
+
61
+ end
62
+
63
+ server = TestServer.new.start *ARGV
64
+
65
+ trap("INT") do
66
+ puts "Script terminated by user."
67
+ server.stop
68
+ puts "Server stopped"
69
+ exit
70
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crate_ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christoph Klocker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-09 00:00:00.000000000 Z
11
+ date: 2014-04-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -74,6 +74,7 @@ files:
74
74
  - spec/crate_ruby/client_spec.rb
75
75
  - spec/crate_ruby/result_set_spec.rb
76
76
  - spec/spec_helper.rb
77
+ - spec/test_server.rb
77
78
  - spec/uploads/get_logo-crate.png
78
79
  - spec/uploads/logo-crate.png
79
80
  - spec/uploads/text.txt
@@ -105,6 +106,7 @@ test_files:
105
106
  - spec/crate_ruby/client_spec.rb
106
107
  - spec/crate_ruby/result_set_spec.rb
107
108
  - spec/spec_helper.rb
109
+ - spec/test_server.rb
108
110
  - spec/uploads/get_logo-crate.png
109
111
  - spec/uploads/logo-crate.png
110
112
  - spec/uploads/text.txt