Permalink
Browse files

initial conversion to yajl-ruby. HTTP request JSON responses are now …

…parsed directly off the socket *as it's being received*

Signed-off-by: Ken Robertson <ken@qgyen.net>
  • Loading branch information...
1 parent 6547d67 commit c3fc68b89047756548ffd086c640ca8f8ce17088 @brianmario brianmario committed with Jun 23, 2009
Showing with 59 additions and 73 deletions.
  1. +1 −1 Rakefile
  2. +1 −0 lib/do_dbslayer.rb
  3. +23 −27 lib/do_dbslayer/command.rb
  4. +27 −35 spec/command_spec.rb
  5. +4 −5 spec/reader_spec.rb
  6. +3 −5 spec/spec_helper.rb
View
@@ -21,7 +21,7 @@ spec = Gem::Specification.new do |s|
s.require_path = 'lib'
s.files = FileList[ '{lib,spec}/**/*.rb', 'spec/spec.opts', 'Rakefile', *s.extra_rdoc_files ]
s.add_dependency('dm-core', '= 0.9.0')
- s.add_dependency('json_pure')
+ s.add_dependency('yajl-ruby')
end
task :default => [ :spec ]
View
@@ -1,4 +1,5 @@
require 'rubygems'
+require 'yajl/http_stream'
require 'data_objects'
require 'do_dbslayer/connection.rb'
require 'do_dbslayer/command.rb'
View
@@ -1,5 +1,4 @@
-require 'net/http'
-require 'json/pure'
+require 'uri'
module DataObjects
module Dbslayer
@@ -29,38 +28,35 @@ def execute_reader(*args)
end
def execute(args)
- query = query_url(args)
- response = Net::HTTP.get_response(query.host, "#{query.path}?#{query.query}", query.port)
-
- if response.is_a?(Net::HTTPSuccess)
- dbresponse = JSON.parse(response.body)
-
- if dbresponse['MYSQL_ERROR']
- raise DbslayerException, "MySQL Error #{dbresponse['MYSQL_ERRNO']}: #{dbresponse['MYSQL_ERROR']}"
- elsif dbresponse['RESULT']
- result = dbresponse['RESULT']
- case result
- when Hash
- return result
- when Array
- result.map { |r| return r }
- else
- raise DbslayerException, "Unknown format for SQL results from DBSlayer"
- end
- elsif dbresponse['SUCCESS']
- return dbresponse['SUCCESS']
- else
- raise DbslayerException, "Unknown response type from DBSlayer"
+ uri = ::URI.parse(query_url(args).to_s)
+ dbresponse = Yajl::HttpStream.get(uri)
+
+ if dbresponse['MYSQL_ERROR']
+ raise DbslayerException, "MySQL Error #{dbresponse['MYSQL_ERRNO']}: #{dbresponse['MYSQL_ERROR']}"
+ elsif dbresponse['RESULT']
+ result = dbresponse['RESULT']
+ case result
+ when Hash
+ return result
+ when Array
+ result.map { |r| return r }
+ else
+ raise DbslayerException, "Unknown format for SQL results from DBSlayer"
end
-
+ elsif dbresponse['SUCCESS']
+ return dbresponse['SUCCESS']
else
- raise DbslayerWebException, "Web error #{response.class}: #{response.body}"
+ raise DbslayerException, "Unknown response type from DBSlayer"
end
+ rescue Yajl::ParseError => e
+ raise Yajl::ParseError, "JSON parsing error #{e.class}: #{e.message}"
+ rescue Exception => e
+ raise DbslayerWebException, "Web error #{e.class}: #{e.message}"
end
def query_url(args)
sql = args.size > 0 ? escape_sql(args) : @text
- query = URI.encode({ 'SQL' => sql }.to_json)
+ query = ::URI.encode(Yajl::Encoder.encode({ 'SQL' => sql }))
Addressable::URI.parse("#{@connection.db_url}?#{query}")
end
View
@@ -7,58 +7,50 @@
@connection = DataObjects::Dbslayer::Connection.new('dbslayer://localhost')
end
+ before(:each) do
+ @http_response = "HTTP/1.0 200 OK\r\n"
+ @http_response << "Vary: Accept-Encoding\r\n"
+ @http_response << "Content-Type: application/json\r\n"
+ @http_response << "Accept-Ranges: bytes\r\n"
+ @http_response << "Last-Modified: Thu, 30 Apr 2009 04:36:11 GMT\r\n"
+ @http_response << "Connection: close\r\n"
+ @http_response << "Date: Fri, 08 May 2009 06:21:36 GMT\r\n"
+ @http_response << "Server: lighttpd/1.4.22\r\n"
+ end
+
it 'should return a proper command type' do
command = @connection.create_command 'FAKE QUERY'
command.class.should == DataObjects::Dbslayer::Command
end
it 'should return proper result on a non-reader query' do
- response = Net::HTTPOK.new('get', 200, 'found')
- response.expects(:body).returns(@non_query)
- Net::HTTP.expects(:get_response).returns(response)
-
+ @http_response << "Content-Length: #{@non_query.size}\r\n"
+ @http_response << "\r\n" # end of the headers
+ @http_response << @non_query
+ @http_response << "\r\n" # end of the response body
+ non_query = StringIO.new(@http_response)
+ TCPSocket.should_receive(:new).and_return(non_query)
+ non_query.should_receive(:write)
+ non_query.should_receive(:close)
command = @connection.create_command('FAKE QUERY')
result = command.execute_non_query
result.affected_rows.should == 5
end
it 'should return a reader when executing a query' do
- response = Net::HTTPOK.new('get', 200, 'found')
- response.expects(:body).returns(@reader_query)
- Net::HTTP.expects(:get_response).returns(response)
-
+ @http_response << "Content-Length: #{@non_query.size}\r\n"
+ @http_response << "\r\n" # end of the headers
+ @http_response << @reader_query
+ @http_response << "\r\n" # end of the response body
+ reader_query = StringIO.new(@http_response)
+ TCPSocket.should_receive(:new).and_return(reader_query)
+ reader_query.should_receive(:write)
+ reader_query.should_receive(:close)
command = @connection.create_command('FAKE QUERY')
result = command.execute_reader
result.class.should == DataObjects::Dbslayer::Reader
end
- it 'should escape strings properly' do
- command = @connection.create_command('FAKE QUERY ?')
- query = command.escape_sql(['blah'])
- query.should == "FAKE QUERY 'blah'"
- end
-
- it 'should escape dates properly' do
- date = Date.parse('Sun May 18 16:22:47 -0700 2008')
- command = @connection.create_command('FAKE QUERY ?')
- query = command.escape_sql([date])
- query.should == "FAKE QUERY '2008-05-18'"
- end
-
- it 'should escape times properly' do
- time = Time.parse('Sun May 18 16:22:47 -0700 2008')
- command = @connection.create_command('FAKE QUERY ?')
- query = command.escape_sql([time])
- query.should == "FAKE QUERY '2008-05-18 16:22:47'"
- end
-
- it 'should escape DateTimes properly' do
- datetime = DateTime.parse('Sun May 18 16:22:47 -0700 2008')
- command = @connection.create_command('FAKE QUERY ?')
- query = command.escape_sql([datetime])
- query.should == "FAKE QUERY '2008-05-18 16:22:47'"
- end
-
it 'should return an escaped query URL' do
command = @connection.create_command('FAKE QUERY ?')
query = command.query_url(['blah'])
View
@@ -2,11 +2,10 @@
describe DataObjects::Dbslayer::Reader do
before :all do
- @reader_query = File.new(File.join(File.dirname(__FILE__), 'fixtures', 'reader_result.txt')).read
- @types_query = File.new(File.join(File.dirname(__FILE__), 'fixtures', 'types_test.txt')).read
- @reader = DataObjects::Dbslayer::Reader.new( JSON.parse(@reader_query)['RESULT'] )
-
- @types_reader = DataObjects::Dbslayer::Reader.new( JSON.parse(@types_query)['RESULT'] )
+ @reader_query = File.new(File.join(File.dirname(__FILE__), 'fixtures', 'reader_result.txt'))
+ @types_query = File.new(File.join(File.dirname(__FILE__), 'fixtures', 'types_test.txt'))
+ @reader = DataObjects::Dbslayer::Reader.new( Yajl::Parser.parse(@reader_query)['RESULT'] )
+ @types_reader = DataObjects::Dbslayer::Reader.new( Yajl::Parser.parse(@types_query)['RESULT'] )
@types_reader.next!
end
View
@@ -1,14 +1,12 @@
require 'rubygems'
+require 'stringio'
gem 'rspec', '>=1.1.3'
require 'spec'
require 'pathname'
require 'data_mapper'
+require 'yajl'
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
DataMapper.setup(:default, 'mysql://localhost/test')
-require 'dbslayer_adapter'
-
-Spec::Runner.configure do |config|
- config.mock_with :mocha
-end
+require 'dbslayer_adapter'

0 comments on commit c3fc68b

Please sign in to comment.