data_objects-0.10.16/0000755000004100000410000000000012540210163014323 5ustar www-datawww-datadata_objects-0.10.16/Rakefile0000644000004100000410000000107612540210163015774 0ustar www-datawww-datarequire 'pathname' require 'rubygems' require 'bundler' require 'rubygems/package_task' Bundler::GemHelper.install_tasks require 'rake' require 'rake/clean' ROOT = Pathname(__FILE__).dirname.expand_path require ROOT + 'lib/data_objects/version' JRUBY = RUBY_PLATFORM =~ /java/ IRONRUBY = defined?(RUBY_ENGINE) && RUBY_ENGINE == 'ironruby' WINDOWS = Gem.win_platform? || (JRUBY && ENV_JAVA['os.name'] =~ /windows/i) SUDO = WINDOWS ? '' : ('sudo' unless ENV['SUDOLESS']) CLEAN.include(%w[ pkg/ **/*.rbc ]) FileList['tasks/**/*.rake'].each { |task| import task } data_objects-0.10.16/spec/0000755000004100000410000000000012540210163015255 5ustar www-datawww-datadata_objects-0.10.16/spec/connection_spec.rb0000644000004100000410000000334312540210163020756 0ustar www-datawww-datarequire File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper')) require 'stringio' describe DataObjects::Connection do subject { connection } let(:connection) { described_class.new(uri) } after { connection.close } context 'should define a standard API' do let(:uri) { 'mock://localhost' } it { should respond_to(:dispose) } it { should respond_to(:create_command) } its(:to_s) { should == 'mock://localhost' } end describe 'initialization' do context 'with a connection uri as a Addressable::URI' do let(:uri) { Addressable::URI::parse('mock://localhost/database') } it { should be_kind_of(DataObjects::Mock::Connection) } it { should be_kind_of(DataObjects::Pooling) } its(:to_s) { should == 'mock://localhost/database' } end [ 'java:comp/env/jdbc/DataSource?driver=mock2', Addressable::URI.parse('java:comp/env/jdbc/DataSource?driver=mock2') ].each do |jndi_url| context 'should return the Connection specified by the scheme without pooling' do let(:uri) { jndi_url } it { should be_kind_of(DataObjects::Mock2::Connection) } it { should_not be_kind_of(DataObjects::Pooling) } end end %w( jdbc:mock:memory:: jdbc:mock://host/database jdbc:mock://host:6969/database jdbc:mock:thin:host:database jdbc:mock:thin:@host.domain.com:6969:database jdbc:mock://server:6969/database;property=value; jdbc:mock://[1111:2222:3333:4444:5555:6666:7777:8888]/database ).each do |jdbc_url| context "with JDBC URL '#{jdbc_url}'" do let(:uri) { jdbc_url } it { should be_kind_of(DataObjects::Mock::Connection) } end end end end data_objects-0.10.16/spec/uri_spec.rb0000644000004100000410000000353512540210163017421 0ustar www-datawww-datarequire File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper')) describe DataObjects::URI do subject { described_class.parse(uri) } context 'parsing parts' do let(:uri) { 'mock://username:password@localhost:12345/path?encoding=utf8#fragment' } its(:scheme) { should == 'mock' } its(:user) { should == 'username' } its(:password) { should == 'password' } its(:host) { should == 'localhost' } its(:port) { should == 12345 } its(:path) { should == '/path' } its(:query) { should == { 'encoding' => 'utf8' } } its(:fragment) { should == 'fragment' } it 'should provide a correct string representation' do subject.to_s.should == 'mock://username@localhost:12345/path?encoding=utf8#fragment' end end context 'parsing JDBC URL parts' do let(:uri) { 'jdbc:mock://username:password@localhost:12345/path?encoding=utf8#fragment' } its(:scheme) { should == 'jdbc' } its(:subscheme) { should == 'mock' } its(:user) { should == 'username' } its(:password) { should == 'password' } its(:host) { should == 'localhost' } its(:port) { should == 12345 } its(:path) { should == '/path' } its(:query) { should == { 'encoding' => 'utf8' } } its(:fragment) { should == 'fragment' } it 'should provide a correct string representation' do subject.to_s.should == 'jdbc:mock://username@localhost:12345/path?encoding=utf8#fragment' end end context 'parsing parts' do let(:uri) { 'java:comp/env/jdbc/TestDataSource' } its(:scheme) { should == 'java' } its(:path) { should == 'comp/env/jdbc/TestDataSource' } it 'should provide a correct string representation' do subject.to_s.should == 'java:comp/env/jdbc/TestDataSource' end end end data_objects-0.10.16/spec/spec_helper.rb0000644000004100000410000000063412540210163020076 0ustar www-datawww-datarequire 'rubygems' require 'data_objects' require 'rspec' module DataObjects::Pooling class << self remove_method :scavenger_interval if instance_methods(false).any? { |m| m.to_sym == :scavenger_interval } def scavenger_interval 0.5 end end end require File.expand_path(File.join(File.dirname(__FILE__), 'do_mock')) require File.expand_path(File.join(File.dirname(__FILE__), 'do_mock2')) data_objects-0.10.16/spec/pooling_spec.rb0000644000004100000410000000673512540210163020276 0ustar www-datawww-datarequire File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper')) require 'timeout' describe "DataObjects::Pooling" do before do Object.send(:remove_const, :Person) if defined?(Person) class ::Person include DataObjects::Pooling attr_accessor :name def initialize(name) @name = name end def dispose @name = nil end end Object.send(:remove_const, :Overwriter) if defined?(Overwriter) class ::Overwriter def self.new(*args) instance = allocate instance.send(:initialize, *args) instance.overwritten = true instance end include DataObjects::Pooling attr_accessor :name def initialize(name) @name = name @overwritten = false end def overwritten? @overwritten end def overwritten=(value) @overwritten = value end class << self remove_method :pool_size if instance_methods(false).any? { |m| m.to_sym == :pool_size } def pool_size pool_size = if RUBY_PLATFORM =~ /java/ 20 else 2 end pool_size end end def dispose @name = nil end end end after :each do DataObjects::Pooling.lock.synchronize do DataObjects::Pooling.pools.each do |pool| pool.lock.synchronize do pool.dispose end end end end it "should maintain a size of 1" do bob = Person.new('Bob') fred = Person.new('Fred') ted = Person.new('Ted') Person.__pools.each do |args, pool| pool.size.should == 1 end bob.release fred.release ted.release Person.__pools.each do |args, pool| pool.size.should == 1 end end it "should track the initialized pools" do bob = Person.new('Bob') # Ensure the pool is "primed" bob.name.should == 'Bob' bob.instance_variable_get(:@__pool).should_not be_nil Person.__pools.size.should == 1 bob.release Person.__pools.size.should == 1 DataObjects::Pooling::pools.should_not be_empty sleep(1.2) # NOTE: This assertion is commented out, as our MockConnection objects are # currently in the pool. # DataObjects::Pooling::pools.should be_empty bob.name.should be_nil end it "should allow you to overwrite Class#new" do bob = Overwriter.new('Bob') bob.should be_overwritten bob.release end it "should allow multiple threads to access the pool" do t1 = Thread.new do bob = Person.new('Bob') sleep(1) bob.release end lambda do bob = Person.new('Bob') t1.join bob.release end.should_not raise_error(DataObjects::Pooling::InvalidResourceError) end it "should allow you to flush a pool" do bob = Overwriter.new('Bob') Overwriter.new('Bob').release bob.release bob.name.should == 'Bob' Overwriter.__pools[['Bob']].size.should == 2 Overwriter.__pools[['Bob']].flush! Overwriter.__pools[['Bob']].size.should == 0 bob.name.should be_nil end it "should wake up the scavenger thread when exiting" do bob = Person.new('Bob') bob.release DataObjects.exiting = true sleep(1) DataObjects::Pooling.scavenger?.should be_false end it "should be able to detach an instance from the pool" do bob = Person.new('Bob') Person.__pools[['Bob']].size.should == 1 bob.detach Person.__pools[['Bob']].size.should == 0 end end data_objects-0.10.16/spec/reader_spec.rb0000644000004100000410000000114612540210163020060 0ustar www-datawww-datarequire File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper')) describe DataObjects::Reader do subject { command.execute_reader } let(:connection) { DataObjects::Connection.new('mock://localhost') } let(:command) { connection.create_command('SELECT * FROM example') } after { connection.close } context 'should define a standard API' do it { should be_a(Enumerable) } it { should respond_to(:close) } it { should respond_to(:next!) } it { should respond_to(:values) } it { should respond_to(:fields) } it { should respond_to(:each) } end end data_objects-0.10.16/spec/transaction_spec.rb0000644000004100000410000000247212540210163021146 0ustar www-datawww-datarequire File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper')) describe DataObjects::Transaction do before :each do @connection = mock("connection") DataObjects::Connection.should_receive(:new).with("mock://mock/mock").once.and_return(@connection) @transaction = DataObjects::Transaction.new("mock://mock/mock") end it "should have a HOST constant" do DataObjects::Transaction::HOST.should_not == nil? end describe "#initialize" do it "should provide a connection" do @transaction.connection.should == @connection end it "should provide an id" do @transaction.id.should_not == nil end it "should provide a unique id" do DataObjects::Connection.should_receive(:new).with("mock://mock/mock2").once.and_return(@connection) @transaction.id.should_not == DataObjects::Transaction.new("mock://mock/mock2").id end end describe "#close" do it "should close its connection" do @connection.should_receive(:close).once lambda { @transaction.close }.should_not raise_error(DataObjects::TransactionError) end end [:prepare, :commit_prepared, :rollback_prepared].each do |meth| it "should raise NotImplementedError on #{meth}" do lambda { @transaction.send(meth) }.should raise_error(NotImplementedError) end end end data_objects-0.10.16/spec/result_spec.rb0000644000004100000410000000114412540210163020132 0ustar www-datawww-datarequire File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper')) describe DataObjects::Result do subject { command.execute_non_query } let(:connection) { DataObjects::Connection.new('mock://localhost') } let(:command) { connection.create_command('SELECT * FROM example') } after { connection.close } context 'should define a standard API' do it 'should provide the number of affected rows' do should respond_to(:to_i) subject.to_i.should == 0 end it 'should provide the id of the inserted row' do should respond_to(:insert_id) end end end data_objects-0.10.16/spec/do_mock2.rb0000644000004100000410000000074312540210163017303 0ustar www-datawww-datamodule DataObjects module Mock2 class Connection < DataObjects::Connection def initialize(uri) @uri = uri end def dispose nil end end class Command < DataObjects::Command def execute_non_query(*args) Result.new(self, 0, nil) end def execute_reader(*args) Reader.new end end class Result < DataObjects::Result end class Reader < DataObjects::Reader end end end data_objects-0.10.16/spec/command_spec.rb0000644000004100000410000000130112540210163020225 0ustar www-datawww-datarequire File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper')) describe DataObjects::Command do before do @connection = DataObjects::Connection.new('mock://localhost') @command = DataObjects::Command.new(@connection, 'SQL STRING') end after do @connection.close end %w{connection execute_non_query execute_reader set_types}.each do |meth| it "should respond to ##{meth}" do @command.should respond_to(meth.intern) end end %w{execute_non_query execute_reader set_types}.each do |meth| it "should raise NotImplementedError on ##{meth}" do lambda { @command.send(meth.intern, nil) }.should raise_error(NotImplementedError) end end end data_objects-0.10.16/spec/do_mock.rb0000644000004100000410000000074212540210163017220 0ustar www-datawww-datamodule DataObjects module Mock class Connection < DataObjects::Connection def initialize(uri) @uri = uri end def dispose nil end end class Command < DataObjects::Command def execute_non_query(*args) Result.new(self, 0, nil) end def execute_reader(*args) Reader.new end end class Result < DataObjects::Result end class Reader < DataObjects::Reader end end end data_objects-0.10.16/lib/0000755000004100000410000000000012540210163015071 5ustar www-datawww-datadata_objects-0.10.16/lib/data_objects/0000755000004100000410000000000012540210163017513 5ustar www-datawww-datadata_objects-0.10.16/lib/data_objects/result.rb0000644000004100000410000000106112540210163021354 0ustar www-datawww-datamodule DataObjects # The Result class is returned from Connection#execute_non_query. class Result # The ID of a row inserted by the Command attr_accessor :insert_id # The number of rows affected by the Command attr_accessor :affected_rows # Create a new Result. Used internally in the adapters. def initialize(command, affected_rows, insert_id = nil) @command, @affected_rows, @insert_id = command, affected_rows, insert_id end # Return the number of affected rows def to_i @affected_rows end end end data_objects-0.10.16/lib/data_objects/connection.rb0000644000004100000410000001005412540210163022177 0ustar www-datawww-databegin require 'fastthread' rescue LoadError end module DataObjects # An abstract connection to a DataObjects resource. The physical connection may be broken and re-established from time to time. class Connection include Logging # Make a connection to the database using the DataObjects::URI given. # Note that the physical connection may be delayed until the first command is issued, so success here doesn't necessarily mean you can connect. def self.new(uri_s) uri = DataObjects::URI::parse(uri_s) case uri.scheme.to_sym when :java warn 'JNDI URLs (connection strings) are only for use with JRuby' unless RUBY_PLATFORM =~ /java/ driver = uri.query.delete('scheme') driver = uri.query.delete('driver') conn_uri = uri.to_s.gsub(/\?$/, '') when :jdbc warn 'JDBC URLs (connection strings) are only for use with JRuby' unless RUBY_PLATFORM =~ /java/ path = uri.subscheme driver = if path.split(':').first == 'sqlite' 'sqlite3' elsif path.split(':').first == 'postgresql' 'postgres' else path.split(':').first end conn_uri = uri_s # NOTE: for now, do not reformat this JDBC connection # string -- or, in other words, do not let # DataObjects::URI#to_s be called -- as it is not # correctly handling JDBC URLs, and in doing so, causing # java.sql.DriverManager.getConnection to throw a # 'No suitable driver found for...' exception. else driver = uri.scheme conn_uri = uri end # Exceptions to how a driver class is determined for a given URI driver_class = if driver == 'sqlserver' 'SqlServer' else driver.capitalize end clazz = DataObjects.const_get(driver_class)::Connection unless clazz.method_defined? :close if (uri.scheme.to_sym == :java) clazz.class_eval do alias close dispose end else clazz.class_eval do include Pooling alias close release end end end clazz.new(conn_uri) end # Ensure that all Connection subclasses handle pooling and logging uniformly. # See also DataObjects::Pooling and DataObjects::Logger def self.inherited(target) target.class_eval do # Allocate a Connection object from the pool, creating one if necessary. This method is active in Connection subclasses only. def self.new(*args) instance = allocate instance.send(:initialize, *args) instance end include Quoting end if driver_module_name = target.name.split('::')[-2] driver_module = DataObjects::const_get(driver_module_name) driver_module.class_eval <<-EOS, __FILE__, __LINE__ def self.logger @logger end def self.logger=(logger) @logger = logger end EOS driver_module.logger = DataObjects::Logger.new(nil, :off) end end ##################################################### # Standard API Definition ##################################################### # Show the URI for this connection, without # the password the connection was setup with def to_s @uri.to_s end def initialize(uri) #:nodoc: raise NotImplementedError.new end def dispose #:nodoc: raise NotImplementedError.new end # Create a Command object of the right subclass using the given text def create_command(text) self.class.concrete_command.new(self, text) end def extension driver_namespace.const_get('Extension').new(self) end private def driver_namespace DataObjects::const_get(self.class.name.split('::')[-2]) end def self.concrete_command @concrete_command ||= DataObjects::const_get(self.name.split('::')[-2]).const_get('Command') end end end data_objects-0.10.16/lib/data_objects/byte_array.rb0000644000004100000410000000040612540210163022201 0ustar www-datawww-data# This class has exists to represent binary data. This is mainly # used by DataObjects. Binary data sometimes needs to be quoted differently # than regular string data (even if the string is just plain ASCII). module Extlib class ByteArray < ::String; end end data_objects-0.10.16/lib/data_objects/uri.rb0000644000004100000410000000713612540210163020646 0ustar www-datawww-datarequire 'addressable/uri' module DataObjects # A DataObjects URI is of the form scheme://user:password@host:port/path#fragment # # The elements are all optional except scheme and path: # scheme:: The name of a DBMS for which you have a do_\<scheme\> adapter gem installed. If scheme is *jdbc*, the actual DBMS is in the _path_ followed by a colon. # user:: The name of the user to authenticate to the database # password:: The password to use in authentication # host:: The domain name (defaulting to localhost) where the database is available # port:: The TCP/IP port number to use for the connection # path:: The name or path to the database # query:: Parameters for the connection, for example encoding=utf8 # fragment:: Not currently known to be in use, but available to the adapters class URI attr_reader :scheme, :subscheme, :user, :password, :host, :port, :path, :query, :fragment # Make a DataObjects::URI object by parsing a string. Simply delegates to Addressable::URI::parse. def self.parse(uri) return uri if uri.kind_of?(self) if uri.kind_of?(Addressable::URI) scheme = uri.scheme else if uri[0,4] == 'jdbc' scheme = uri[0,4] uri = Addressable::URI::parse(uri[5, uri.length]) subscheme = uri.scheme else uri = Addressable::URI::parse(uri) scheme = uri.scheme subscheme = nil end end self.new( :scheme => scheme, :subscheme => subscheme, :user => uri.user, :password => uri.password, :host => uri.host, :port => uri.port, :path => uri.path, :query => uri.query_values, :fragment => uri.fragment, :relative => !!uri.to_s.index('//') # basic (naive) check for relativity / opaqueness ) end def initialize(*args) if (component = args.first).kind_of?(Hash) @scheme = component[:scheme] @subscheme = component[:subscheme] @user = component[:user] @password = component[:password] @host = component[:host] @port = component[:port] @path = component[:path] @query = component[:query] @fragment = component[:fragment] @relative = component[:relative] elsif args.size > 1 warn "DataObjects::URI.new with arguments is deprecated, use a Hash of URI components (#{caller.first})" @scheme, @user, @password, @host, @port, @path, @query, @fragment = *args else raise ArgumentError, "argument should be a Hash of URI components, was: #{args.inspect}" end end def opaque? !@relative end def relative? @relative end # Display this URI object as a string def to_s string = "" string << "#{scheme}:" if scheme string << "#{subscheme}:" if subscheme string << '//' if relative? if user string << "#{user}" string << "@" end string << "#{host}" if host string << ":#{port}" if port string << path.to_s if query string << "?" << query.map do |key, value| "#{key}=#{value}" end.join("&") end string << "##{fragment}" if fragment string end # Compare this URI to another for hashing def eql?(other) to_s.eql?(other.to_s) end # Hash this URI def hash to_s.hash end end end data_objects-0.10.16/lib/data_objects/spec/0000755000004100000410000000000012540210163020445 5ustar www-datawww-datadata_objects-0.10.16/lib/data_objects/spec/lib/0000755000004100000410000000000012540210163021213 5ustar www-datawww-datadata_objects-0.10.16/lib/data_objects/spec/lib/ssl.rb0000644000004100000410000000122712540210163022343 0ustar www-datawww-datarequire 'pathname' require 'cgi' module SSLHelpers CERTS_DIR = Pathname(__FILE__).dirname.join('ssl_certs').to_s CONFIG = OpenStruct.new CONFIG.ca_cert = File.join(CERTS_DIR, 'ca-cert.pem') CONFIG.ca_key = File.join(CERTS_DIR, 'ca-key.pem') CONFIG.server_cert = File.join(CERTS_DIR, 'server-cert.pem') CONFIG.server_key = File.join(CERTS_DIR, 'server-key.pem') CONFIG.client_cert = File.join(CERTS_DIR, 'client-cert.pem') CONFIG.client_key = File.join(CERTS_DIR, 'client-key.pem') CONFIG.cipher = 'AES128-SHA' def self.query(*keys) keys.map { |key| "ssl[#{key}]=#{CGI::escape(CONFIG.send(key))}" }.join('&') end end data_objects-0.10.16/lib/data_objects/spec/lib/pending_helpers.rb0000644000004100000410000000027712540210163024714 0ustar www-datawww-datamodule DataObjects::Spec module PendingHelpers def pending_if(message, boolean) if boolean pending(message) { yield } else yield end end end end data_objects-0.10.16/lib/data_objects/spec/shared/0000755000004100000410000000000012540210163021713 5ustar www-datawww-datadata_objects-0.10.16/lib/data_objects/spec/shared/typecast/0000755000004100000410000000000012540210163023547 5ustar www-datawww-datadata_objects-0.10.16/lib/data_objects/spec/shared/typecast/byte_array_spec.rb0000644000004100000410000000367312540210163027260 0ustar www-datawww-datashared_examples_for 'supporting ByteArray' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end describe 'reading a ByteArray' do describe 'with automatic typecasting' do before do @reader = @connection.create_command("SELECT cad_drawing FROM widgets WHERE ad_description = ?").execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(::Extlib::ByteArray) end it 'should return the correct result' do @values.first.should == "CAD \001 \000 DRAWING" end end describe 'with manual typecasting' do before do @command = @connection.create_command("SELECT cad_drawing FROM widgets WHERE ad_description = ?") @command.set_types(::Extlib::ByteArray) @reader = @command.execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(::Extlib::ByteArray) end it 'should return the correct result' do @values.first.should == "CAD \001 \000 DRAWING" end end end describe 'writing a ByteArray' do before do @reader = @connection.create_command("SELECT ad_description FROM widgets WHERE cad_drawing = ?").execute_reader(::Extlib::ByteArray.new("CAD \001 \000 DRAWING")) @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correct entry' do #Some of the drivers starts autoincrementation from 0 not 1 @values.first.should == 'Buy this product now!' end end end data_objects-0.10.16/lib/data_objects/spec/shared/typecast/bigdecimal_spec.rb0000644000004100000410000000520412540210163027167 0ustar www-datawww-datashared_examples_for 'supporting BigDecimal' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end describe 'reading a BigDecimal' do describe 'with manual typecasting' do before do @command = @connection.create_command("SELECT cost1 FROM widgets WHERE ad_description = ?") @command.set_types(BigDecimal) @reader = @command.execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(BigDecimal) end it 'should return the correct result' do # rounding seems necessary for the jruby do_derby driver @values.first.round(2).should == 10.23 end end describe 'with manual typecasting a nil value' do before do @command = @connection.create_command("SELECT cost2 FROM widgets WHERE id = ?") @command.set_types(BigDecimal) @reader = @command.execute_reader(6) @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(NilClass) end it 'should return the correct result' do @values.first.should be_nil end end end describe 'writing an Integer' do before do @reader = @connection.create_command("SELECT id FROM widgets WHERE id = ?").execute_reader(BigDecimal("2.0")) @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correct entry' do @values.first.should == 2 end end end shared_examples_for 'supporting BigDecimal autocasting' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end describe 'reading a BigDecimal' do describe 'with automatic typecasting' do before do @reader = @connection.create_command("SELECT cost2 FROM widgets WHERE ad_description = ?").execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(BigDecimal) end it 'should return the correct result' do @values.first.should == 50.23 end end end end data_objects-0.10.16/lib/data_objects/spec/shared/typecast/nil_spec.rb0000644000004100000410000000464212540210163025676 0ustar www-datawww-datashared_examples_for 'supporting Nil' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end describe 'reading a Nil' do describe 'with manual typecasting' do before do @command = @connection.create_command("SELECT flags FROM widgets WHERE ad_description = ?") @command.set_types(NilClass) @reader = @command.execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(NilClass) end it 'should return the correct result' do @values.first.should == nil end end end end shared_examples_for 'supporting writing an Nil' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end describe 'supporting writing an Nil' do # see as an example oracle # http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/sql_elements005.htm#sthref487 # http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/conditions013.htm#i1050801 describe 'as a parameter' do before do @reader = @connection.create_command("SELECT id FROM widgets WHERE ad_description IN (?) ORDER BY id").execute_reader(nil) end after do @reader.close end it 'should return the correct entry' do @reader.next!.should be_false end end end end shared_examples_for 'supporting Nil autocasting' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end describe 'reading a Nil' do describe 'with automatic typecasting' do before do @reader = @connection.create_command("SELECT ad_description FROM widgets WHERE id = ?").execute_reader(3) @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(NilClass) end it 'should return the correct result' do @values.first.should == nil end end end end data_objects-0.10.16/lib/data_objects/spec/shared/typecast/class_spec.rb0000644000004100000410000000232512540210163026215 0ustar www-datawww-datashared_examples_for 'supporting Class' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end describe 'reading a Class' do describe 'with manual typecasting' do before do @command = @connection.create_command("SELECT whitepaper_text FROM widgets WHERE ad_description = ?") @command.set_types(Class) @reader = @command.execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(Class) end it 'should return the correct result' do @values.first.should == String end end end describe 'writing a Class' do before do @reader = @connection.create_command("SELECT whitepaper_text FROM widgets WHERE whitepaper_text = ?").execute_reader(String) @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correct entry' do @values.first.should == "String" end end end data_objects-0.10.16/lib/data_objects/spec/shared/typecast/other_spec.rb0000644000004100000410000000152312540210163026230 0ustar www-datawww-dataclass ::CustomTextType def initialize(value) @value = value end def to_s @value.to_s end end shared_examples_for 'supporting other (unknown) type' do before :all do setup_test_environment end describe 'writing an object of unknown type' do before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end before do @command = @connection.create_command("SELECT ad_description FROM widgets WHERE ad_description = ?") @command.set_types(::CustomTextType) @reader = @command.execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correct entry' do @values.first.should == 'Buy this product now!' end end end data_objects-0.10.16/lib/data_objects/spec/shared/typecast/boolean_spec.rb0000644000004100000410000000614312540210163026531 0ustar www-datawww-datashared_examples_for 'supporting Boolean' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end describe 'reading a Boolean' do describe 'with manual typecasting' do before do @command = @connection.create_command("SELECT flags FROM widgets WHERE ad_description = ?") @command.set_types(TrueClass) @reader = @command.execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(FalseClass) end it 'should return the correct result' do @values.first.should == false end end describe 'with manual typecasting a true value' do before do @command = @connection.create_command("SELECT flags FROM widgets WHERE id = ?") @command.set_types(TrueClass) @reader = @command.execute_reader(2) @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(TrueClass) end it 'should return the correct result' do @values.first.should be_true end end describe 'with manual typecasting a nil value' do before do @command = @connection.create_command("SELECT flags FROM widgets WHERE id = ?") @command.set_types(TrueClass) @reader = @command.execute_reader(4) @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(NilClass) end it 'should return the correct result' do @values.first.should be_nil end end end describe 'writing an Boolean' do before do @reader = @connection.create_command("SELECT id FROM widgets WHERE flags = ?").execute_reader(true) @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correct entry' do @values.first.should == 2 end end end shared_examples_for 'supporting Boolean autocasting' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end describe 'reading a Boolean' do describe 'with automatic typecasting' do before do @reader = @connection.create_command("SELECT flags FROM widgets WHERE ad_description = ?").execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(FalseClass) end it 'should return the correct result' do @values.first.should == false end end end end data_objects-0.10.16/lib/data_objects/spec/shared/typecast/float_spec.rb0000644000004100000410000000546712540210163026227 0ustar www-datawww-datashared_examples_for 'supporting Float' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end describe 'reading a Float' do describe 'with manual typecasting' do before do @command = @connection.create_command("SELECT id FROM widgets WHERE ad_description = ?") @command.set_types(Float) @reader = @command.execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(Float) end it 'should return the correct result' do #Some of the drivers starts autoincrementation from 0 not 1 @values.first.should satisfy { |val| val == 1.0 or val == 0.0 } end end describe 'with manual typecasting a nil' do before do @command = @connection.create_command("SELECT cost1 FROM widgets WHERE id = ?") @command.set_types(Float) @reader = @command.execute_reader(5) @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(NilClass) end it 'should return the correct result' do @values.first.should be_nil end end end describe 'writing a Float' do before do @reader = @connection.create_command("SELECT id FROM widgets WHERE id = ?").execute_reader(2.0) @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correct entry' do #Some of the drivers starts autoincrementation from 0 not 1 @values.first.should satisfy { |val| val == 1 or val == 2 } end end end shared_examples_for 'supporting Float autocasting' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end describe 'reading a Float' do describe 'with automatic typecasting' do before do @reader = @connection.create_command("SELECT weight, cost1 FROM widgets WHERE ad_description = ?").execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(Float) @values.last.should be_kind_of(Float) end it 'should return the correct result' do @values.first.should == 13.4 BigDecimal.new(@values.last.to_s).round(2).should == 10.23 end end end end data_objects-0.10.16/lib/data_objects/spec/shared/typecast/range_spec.rb0000644000004100000410000000116012540210163026200 0ustar www-datawww-datashared_examples_for 'supporting Range' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end describe 'passing a Range as a parameter in execute_reader' do before do @reader = @connection.create_command("SELECT * FROM widgets WHERE id between ?").execute_reader(2..5) end after do @reader.close end it 'should return correct number of rows' do counter = 0 while(@reader.next!) do counter += 1 end counter.should == 4 end end end data_objects-0.10.16/lib/data_objects/spec/shared/typecast/time_spec.rb0000644000004100000410000000571412540210163026053 0ustar www-datawww-datashared_examples_for 'supporting Time' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end describe 'reading a Time' do describe 'with manual typecasting' do before do @command = @connection.create_command("SELECT release_date FROM widgets WHERE ad_description = ?") @command.set_types(Time) @reader = @command.execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(Time) end it 'should return the correct result' do @values.first.should == Time.local(2008, 2, 14) end end describe 'with manual typecasting a nil value' do before do @command = @connection.create_command("SELECT release_timestamp FROM widgets WHERE id = ?") @command.set_types(Time) @reader = @command.execute_reader(9) @reader.next! @values = @reader.values end after do @reader.close end it 'should return a nil class' do @values.first.should be_kind_of(NilClass) end it 'should return nil' do @values.first.should be_nil end end end describe 'writing an Time' do before do @reader = @connection.create_command("SELECT id FROM widgets WHERE release_datetime = ? ORDER BY id").execute_reader(Time.local(2008, 2, 14, 00, 31, 12)) @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correct entry' do #Some of the drivers starts autoincrementation from 0 not 1 @values.first.should satisfy { |val| val == 1 or val == 0 } end end end shared_examples_for 'supporting sub second Time' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) @connection.create_command(<<-EOF).execute_non_query(Time.parse('2010-12-15 14:32:08.49377-08').localtime) update widgets set release_timestamp = ? where id = 1 EOF @connection.create_command(<<-EOF).execute_non_query(Time.parse('2010-12-15 14:32:28.942694-08').localtime) update widgets set release_timestamp = ? where id = 2 EOF @command = @connection.create_command("SELECT release_timestamp FROM widgets WHERE id < ? order by id") @command.set_types(Time) @reader = @command.execute_reader(3) @reader.next! @values = @reader.values end after do @connection.close end it 'should handle variable subsecond lengths properly' do @values.first.to_f.should be_within(0.00002).of(Time.at(1292452328, 493770).to_f) @reader.next! @values = @reader.values @values.first.to_f.should be_within(0.00002).of(Time.at(1292452348, 942694).to_f) end end data_objects-0.10.16/lib/data_objects/spec/shared/typecast/ipaddr_spec.rb0000644000004100000410000000000012540210163026337 0ustar www-datawww-datadata_objects-0.10.16/lib/data_objects/spec/shared/typecast/integer_spec.rb0000644000004100000410000000445412540210163026552 0ustar www-datawww-datashared_examples_for 'supporting Integer' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end describe 'reading an Integer' do describe 'with automatic typecasting' do before do @reader = @connection.create_command("SELECT id FROM widgets WHERE ad_description = ?").execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(Integer) end it 'should return the correct result' do #Some of the drivers starts autoincrementation from 0 not 1 @values.first.should satisfy { |val| val == 1 or val == 0 } end end describe 'with manual typecasting' do before do @command = @connection.create_command("SELECT weight FROM widgets WHERE ad_description = ?") @command.set_types(Integer) @reader = @command.execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(Integer) end it 'should return the correct result' do @values.first.should == 13 end end end describe 'writing an Integer' do before do @reader = @connection.create_command("SELECT id FROM widgets WHERE id = ?").execute_reader(2) @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correct entry' do @values.first.should == 2 end end describe 'writing a big Integer' do before do @connection.create_command("UPDATE widgets SET super_number = ? WHERE id = 10").execute_non_query(2147483648) # bigger than Integer.MAX in java !! @reader = @connection.create_command("SELECT super_number FROM widgets WHERE id = ?").execute_reader(10) @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correct entry' do @values.first.should == 2147483648 end end end data_objects-0.10.16/lib/data_objects/spec/shared/typecast/string_spec.rb0000644000004100000410000000747712540210163026433 0ustar www-datawww-data# encoding: utf-8 shared_examples_for 'supporting String' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end describe 'reading a String' do describe 'with automatic typecasting' do before do @reader = @connection.create_command("SELECT code FROM widgets WHERE ad_description = ?").execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(String) end it 'should return the correct result' do @values.first.should == "W0000001" end end describe 'with manual typecasting' do before do @command = @connection.create_command("SELECT number_sold FROM widgets WHERE ad_description = ?") @command.set_types(String) @reader = @command.execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(String) end it 'should return the correct result' do @values.first.should == "0" end end end describe 'writing a String' do before do @reader = @connection.create_command("SELECT id FROM widgets WHERE id = ?").execute_reader("2") @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correct entry' do # Some of the drivers starts autoincrementation from 0 not 1 @values.first.should satisfy { |val| val == 1 or val == 2 } end end describe 'writing and reading a multibyte String' do ['Aslak Hellesøy', 'Пётр Алексе́евич Рома́нов', '歐陽龍'].each do |name| before do # SQL Server Unicode String Literals @n = 'N' if defined?(DataObjects::SqlServer::Connection) && @connection.kind_of?(DataObjects::SqlServer::Connection) end it 'should write a multibyte String' do @command = @connection.create_command('INSERT INTO users (name) VALUES(?)') expect { @command.execute_non_query(name) }.not_to raise_error(DataObjects::DataError) end it 'should read back the multibyte String' do @command = @connection.create_command('SELECT name FROM users WHERE name = ?') @reader = @command.execute_reader(name) @reader.next! @reader.values.first.should == name @reader.close end it 'should write a multibyte String (without query parameters)' do @command = @connection.create_command("INSERT INTO users (name) VALUES(#{@n}\'#{name}\')") expect { @command.execute_non_query }.not_to raise_error(DataObjects::DataError) end it 'should read back the multibyte String (without query parameters)' do @command = @connection.create_command("SELECT name FROM users WHERE name = #{@n}\'#{name}\'") @reader = @command.execute_reader @reader.next! @reader.values.first.should == name @reader.close end end end class ::StringWithExtraPowers < String; end describe 'writing a kind of (subclass of) String' do before do @reader = @connection.create_command("SELECT id FROM widgets WHERE id = ?").execute_reader(::StringWithExtraPowers.new("2")) @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correct entry' do # Some of the drivers starts autoincrementation from 0 not 1 @values.first.should satisfy { |val| val == 1 or val == 2 } end end end data_objects-0.10.16/lib/data_objects/spec/shared/typecast/datetime_spec.rb0000644000004100000410000000745512540210163026715 0ustar www-datawww-dataJRUBY = RUBY_PLATFORM =~ /java/ unless defined?(JRUBY) shared_examples_for 'supporting DateTime' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end describe 'reading a DateTime' do describe 'with manual typecasting' do before do @command = @connection.create_command("SELECT release_datetime FROM widgets WHERE ad_description = ?") @command.set_types(DateTime) @reader = @command.execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(DateTime) end it 'should return the correct result' do date = @values.first local_offset = Rational(Time.local(2008, 2, 14).utc_offset, 86400) date.should == DateTime.civil(2008, 2, 14, 00, 31, 12, local_offset) end end describe 'with manual typecasting a nil value' do before do @command = @connection.create_command("SELECT release_datetime FROM widgets WHERE id = ?") @command.set_types(DateTime) @reader = @command.execute_reader(8) @reader.next! @values = @reader.values end after do @reader.close end it 'should return a nil class' do @values.first.should be_kind_of(NilClass) end it 'should return nil' do @values.first.should be_nil end end describe 'with manual typecasting a datetime column' do before do @command = @connection.create_command("SELECT release_datetime FROM widgets WHERE id = ? OR id = ? ORDER BY id") @command.set_types(DateTime) @reader = @command.execute_reader(1, 10) @reader.next! @feb_row = @reader.values @reader.next! @jul_row = @reader.values end after do @reader.close end it 'should return the correct offset in Feb' do (@feb_row.first.offset * 86400).to_i.should == Time.local(2008, 2, 14, 0, 31, 12).utc_offset end it 'should return the correct offset in Jul' do (@jul_row.first.offset * 86400).to_i.should == Time.local(2008, 7, 14, 0, 31, 12).utc_offset end end end describe 'writing an DateTime' do before do local_offset = Rational(Time.local(2008, 2, 14).utc_offset, 86400) @reader = @connection.create_command("SELECT id FROM widgets WHERE release_datetime = ? ORDER BY id").execute_reader(DateTime.civil(2008, 2, 14, 00, 31, 12, local_offset)) @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correct entry' do #Some of the drivers starts autoincrementation from 0 not 1 @values.first.should satisfy { |val| val == 0 or val == 1 } end end end shared_examples_for 'supporting DateTime autocasting' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end describe 'reading a DateTime' do describe 'with automatic typecasting' do before do @reader = @connection.create_command("SELECT release_datetime FROM widgets WHERE ad_description = ?").execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(DateTime) end it 'should return the correct result' do @values.first.should == Time.local(2008, 2, 14, 00, 31, 12).send(:to_datetime) end end end end data_objects-0.10.16/lib/data_objects/spec/shared/typecast/date_spec.rb0000644000004100000410000000524612540210163026032 0ustar www-datawww-datashared_examples_for 'supporting Date' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end describe 'reading a Date' do describe 'with manual typecasting' do before do @command = @connection.create_command("SELECT release_datetime FROM widgets WHERE ad_description = ?") @command.set_types(Date) @reader = @command.execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(Date) end it 'should return the correct result' do @values.first.should == Date.civil(2008, 2, 14) end end describe 'with manual typecasting a nil value' do before do @command = @connection.create_command("SELECT release_date FROM widgets WHERE id = ?") @command.set_types(Date) @reader = @command.execute_reader(7) @reader.next! @values = @reader.values end after do @reader.close end it 'should return a nil class' do @values.first.should be_kind_of(NilClass) end it 'should return nil' do @values.first.should be_nil end end end describe 'writing an Date' do before do @reader = @connection.create_command("SELECT id FROM widgets WHERE release_date = ? ORDER BY id").execute_reader(Date.civil(2008, 2, 14)) @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correct entry' do #Some of the drivers starts autoincrementation from 0 not 1 @values.first.should satisfy { |val| val == 1 or val == 0 } end end end shared_examples_for 'supporting Date autocasting' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end describe 'reading a Date' do describe 'with automatic typecasting' do before do @reader = @connection.create_command("SELECT release_date FROM widgets WHERE ad_description = ?").execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return the correctly typed result' do @values.first.should be_kind_of(Date) end it 'should return the correct result' do @values.first.should == Date.civil(2008, 2, 14) end end end end data_objects-0.10.16/lib/data_objects/spec/shared/typecast/array_spec.rb0000644000004100000410000000116112540210163026223 0ustar www-datawww-datashared_examples_for 'supporting Array' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end describe 'passing an Array as a parameter in execute_reader' do before do @reader = @connection.create_command("SELECT * FROM widgets WHERE id in ?").execute_reader([2,3,4,5]) end after do @reader.close end it 'should return correct number of rows' do counter = 0 while(@reader.next!) do counter += 1 end counter.should == 4 end end end data_objects-0.10.16/lib/data_objects/spec/shared/encoding_spec.rb0000644000004100000410000001104512540210163025041 0ustar www-datawww-datashared_examples_for 'a driver supporting different encodings' do describe 'character_set' do before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end it { @connection.should respond_to(:character_set) } it 'uses utf8 by default' do @connection.character_set.should == 'UTF-8' end describe 'sets the character set through the URI' do before do # @latin1_connection = DataObjects::Connection.new("#{CONFIG.uri}?encoding=latin1") @latin1_connection = DataObjects::Connection.new("#{CONFIG.scheme}://#{CONFIG.user}:#{CONFIG.pass}@#{CONFIG.host}:#{CONFIG.port}#{CONFIG.database}?encoding=ISO-8859-1") end after { @latin1_connection.close } it { @latin1_connection.character_set.should == 'ISO-8859-1' } end describe 'uses UTF-8 when an invalid encoding is given' do before do @latin1_connection = DataObjects::Connection.new("#{CONFIG.scheme}://#{CONFIG.user}:#{CONFIG.pass}@#{CONFIG.host}:#{CONFIG.port}#{CONFIG.database}?encoding=ISO-INVALID") end after { @latin1_connection.close } it { @latin1_connection.character_set.should == 'UTF-8' } end end end shared_examples_for 'returning correctly encoded strings for the default database encoding' do if defined?(::Encoding) before :all do setup_test_environment end describe 'with encoded string support' do before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end describe 'reading a String' do before do @reader = @connection.create_command("SELECT name, whitepaper_text FROM widgets WHERE ad_description = ?").execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return UTF-8 encoded String' do @values.first.should be_kind_of(String) @values.first.encoding.name.should == 'UTF-8' @values.last.should be_kind_of(String) @values.last.encoding.name.should == 'UTF-8' end end describe 'reading a ByteArray' do before do @command = @connection.create_command("SELECT ad_image FROM widgets WHERE ad_description = ?") @command.set_types(Extlib::ByteArray) @reader = @command.execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return ASCII-8BIT encoded ByteArray' do @values.first.should be_kind_of(::Extlib::ByteArray) @values.first.encoding.name.should == 'ASCII-8BIT' end end end end end shared_examples_for 'returning correctly encoded strings for the default internal encoding' do if defined?(::Encoding) before :all do setup_test_environment end describe 'with encoded string support' do before do @encoding_before = Encoding.default_internal Encoding.default_internal = 'ISO-8859-1' @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close Encoding.default_internal = @encoding_before end describe 'reading a String' do before do @reader = @connection.create_command("SELECT name, whitepaper_text FROM widgets WHERE ad_description = ?").execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return ISO-8859-1 encoded String' do @values.first.should be_kind_of(String) @values.first.encoding.name.should == 'ISO-8859-1' @values.last.should be_kind_of(String) @values.last.encoding.name.should == 'ISO-8859-1' end end describe 'reading a ByteArray' do before do @command = @connection.create_command("SELECT ad_image FROM widgets WHERE ad_description = ?") @command.set_types(Extlib::ByteArray) @reader = @command.execute_reader('Buy this product now!') @reader.next! @values = @reader.values end after do @reader.close end it 'should return ASCII-8BIT encoded ByteArray' do @values.first.should be_kind_of(::Extlib::ByteArray) @values.first.encoding.name.should == 'ASCII-8BIT' end end end end end data_objects-0.10.16/lib/data_objects/spec/shared/connection_spec.rb0000644000004100000410000001552512540210163025421 0ustar www-datawww-datadef test_connection(conn) reader = conn.create_command(CONFIG.testsql || "SELECT 1").execute_reader reader.next! result = reader.values[0] result ensure reader.close conn.close end shared_examples_for 'a Connection' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) end after do @connection.close end it { @connection.should be_kind_of(DataObjects::Connection) } it { @connection.should be_kind_of(DataObjects::Pooling) } it { @connection.should respond_to(:dispose) } it 'should respond to #create_command' do @connection.should respond_to(:create_command) end describe 'create_command' do it 'should be a kind of Command' do @connection.create_command('This is a dummy command').should be_kind_of(DataObjects::Command) end end describe 'various connection URIs' do it 'should open with an uri object' do uri = DataObjects::URI.new( :scheme => @driver, :user => @user, :password => @password, :host => @host, :port => @port && @port.to_i, :path => @database ) conn = DataObjects::Connection.new(uri) test_connection(conn).should == 1 conn.close end it 'should work with non-JDBC URLs' do conn = DataObjects::Connection.new("#{CONFIG.uri.sub(/jdbc:/, '')}") test_connection(conn).should == 1 conn.close end end describe 'dispose' do describe 'on open connection' do it 'dispose should be true' do conn = DataObjects::Connection.new(CONFIG.uri) conn.detach conn.dispose.should be_true conn.close end end describe 'on closed connection' do before do @closed_connection = DataObjects::Connection.new(CONFIG.uri) @closed_connection.detach @closed_connection.dispose end after do @closed_connection.close @closed_connection = nil end it { @closed_connection.dispose.should be_false } it 'should raise an error on creating a command' do expect { @closed_connection.create_command("INSERT INTO non_existent_table (tester) VALUES (1)").execute_non_query }.to raise_error(DataObjects::ConnectionError) end end end end shared_examples_for 'a Connection with authentication support' do before :all do %w[ @driver @user @password @host @port @database ].each do |ivar| raise "+#{ivar}+ should be defined in before block" unless instance_variable_get(ivar) end end describe 'with an invalid URI' do # FIXME JRuby (and MRI): Should these be ArgumentError or DataObjects::SQLError? def connecting_with(uri) lambda { DataObjects::Connection.new(uri) } end it 'should raise an error if bad username is given' do connecting_with("#{@driver}://thisreallyshouldntexist:#{@password}@#{@host}:#{@port}#{@database}").should raise_error #(ArgumentError, DataObjects::Error) end it 'should raise an error if bad password is given' do connecting_with("#{@driver}://#{@user}:completelyincorrectpassword:#{@host}:#{@port}#{@database}").should raise_error #(ArgumentError, DataObjects::Error) end it 'should raise an error if an invalid port is given' do connecting_with("#{@driver}://#{@user}:#{@password}:#{@host}:648646543#{@database}").should raise_error #(ArgumentError, DataObjects::Error) end it 'should raise an error if an invalid database is given' do connecting_with("#{@driver}://#{@user}:#{@password}:#{@host}:#{@port}/someweirddatabase").should raise_error #(ArgumentError, DataObjects::Error) end end end shared_examples_for 'a Connection allowing default database' do describe 'with a URI without a database' do it 'should connect properly' do conn = DataObjects::Connection.new("#{@driver}://#{@user}:#{@password}@#{@host}:#{@port}") test_connection(conn).should == 1 end end end shared_examples_for 'a Connection with JDBC URL support' do it 'should work with JDBC URLs' do conn = DataObjects::Connection.new(CONFIG.jdbc_uri || "jdbc:#{CONFIG.uri.sub(/jdbc:/, '')}") test_connection(conn).should == 1 end end if defined? JRUBY_VERSION shared_examples_for 'a Connection with SSL support' do if DataObjectsSpecHelpers.test_environment_supports_ssl? describe 'connecting with SSL' do it 'should connect securely' do conn = DataObjects::Connection.new("#{CONFIG.uri}?#{CONFIG.ssl}") conn.secure?.should be_true conn.close end end end describe 'connecting without SSL' do it 'should not connect securely' do conn = DataObjects::Connection.new(CONFIG.uri) conn.secure?.should be_false conn.close end end end shared_examples_for 'a Connection via JDNI' do if defined? JRUBY_VERSION require 'java' begin require 'do_jdbc/spec/lib/tyrex-1.0.3.jar' require 'do_jdbc/spec/lib/javaee-api-6.0.jar' require 'do_jdbc/spec/lib/commons-dbcp-1.2.2.jar' require 'do_jdbc/spec/lib/commons-pool-1.3.jar' rescue LoadError pending 'JNDI specs currently require manual download of Tyrex and Apache Commons JARs' break end describe 'connecting with JNDI' do before(:all) do java_import java.lang.System java_import javax.naming.Context java_import javax.naming.NamingException java_import javax.naming.Reference java_import javax.naming.StringRefAddr java_import 'tyrex.naming.MemoryContext' java_import 'tyrex.tm.RuntimeContext' System.set_property(Context.INITIAL_CONTEXT_FACTORY, 'tyrex.naming.MemoryContextFactory') ref = Reference.new('javax.sql.DataSource', 'org.apache.commons.dbcp.BasicDataSourceFactory', nil) ref.add(StringRefAddr.new('driverClassName', CONFIG.jdbc_driver)) ref.add(StringRefAddr.new('url', (CONFIG.jdbc_uri || CONFIG.uri))) ref.add(StringRefAddr.new('username', CONFIG.user)) ref.add(StringRefAddr.new('password', CONFIG.pass)) @root = MemoryContext.new(nil) ctx = @root.createSubcontext('comp') ctx = ctx.createSubcontext('env') ctx = ctx.createSubcontext('jdbc') ctx.bind('mydb', ref) end before do runCtx = RuntimeContext.newRuntimeContext(@root, nil) RuntimeContext.setRuntimeContext(runCtx) end after do RuntimeContext.unsetRuntimeContext() end it 'should connect' do begin c = DataObjects::Connection.new("java:comp/env/jdbc/mydb?driver=#{CONFIG.driver}") c.should_not be_nil test_connection(c).should == 1 ensure c.close if c end end end end end data_objects-0.10.16/lib/data_objects/spec/shared/reader_spec.rb0000644000004100000410000001156512540210163024524 0ustar www-datawww-datashared_examples_for 'a Reader' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) @reader = @connection.create_command("SELECT code, name FROM widgets WHERE ad_description = ? order by id").execute_reader('Buy this product now!') @reader2 = @connection.create_command("SELECT code FROM widgets WHERE ad_description = ? order by id").execute_reader('Buy this product now!') end after do @reader.close @reader2.close @connection.close end it { @reader.should respond_to(:fields) } describe 'fields' do it 'should return the correct fields in the reader' do # we downcase the field names as some drivers such as do_derby, do_h2, # do_hsqldb, do_oracle return the field names as uppercase @reader.fields.should be_array_case_insensitively_equal_to(['code', 'name']) end it 'should return the field alias as the name, when the SQL AS keyword is specified' do reader = @connection.create_command("SELECT code AS codigo, name AS nombre FROM widgets WHERE ad_description = ? order by id").execute_reader('Buy this product now!') reader.fields.should_not be_array_case_insensitively_equal_to(['code', 'name']) reader.fields.should be_array_case_insensitively_equal_to(['codigo', 'nombre']) reader.close end end it { @reader.should respond_to(:values) } describe 'values' do describe 'when the reader is uninitialized' do it 'should raise an error' do expect { @reader.values }.to raise_error(DataObjects::DataError) end end describe 'when the reader is moved to the first result' do before do @reader.next! end it 'should return the correct first set of in the reader' do @reader.values.should == ["W0000001", "Widget 1"] end end describe 'when the reader is moved to the second result' do before do @reader.next!; @reader.next! end it 'should return the correct first set of in the reader' do @reader.values.should == ["W0000002", "Widget 2"] end end describe 'when the reader is moved to the end' do before do while @reader.next! ; end end it 'should raise an error again' do expect { @reader.values }.to raise_error(DataObjects::DataError) end end end it { @reader.should respond_to(:close) } describe 'close' do describe 'on an open reader' do it 'should return true' do @reader.close.should be_true end end describe 'on an already closed reader' do before do @reader.close end it 'should return false' do @reader.close.should be_false end end end it { @reader.should respond_to(:next!) } describe 'next!' do describe 'successfully moving the cursor initially' do it 'should return true' do @reader.next!.should be_true end end describe 'moving the cursor' do before do @reader.next! end it 'should move the cursor to the next value' do @reader.values.should == ["W0000001", "Widget 1"] lambda { @reader.next! }.should change { @reader.values } @reader.values.should == ["W0000002", "Widget 2"] end end describe 'arriving at the end of the reader' do before do while @reader.next!; end end it 'should return false when the end is reached' do @reader.next!.should be_false end end end it { @reader.should respond_to(:field_count) } describe 'field_count' do it 'should count the number of fields' do @reader.field_count.should == 2 end end it { @reader.should respond_to(:values) } describe 'each' do it 'should yield each row to the block for multiple columns' do rows_yielded = 0 @reader.each do |row| row.should respond_to(:[]) row.size.should == 2 # the field names need to be case insensitive as some drivers such as # do_derby, do_h2, do_hsqldb return the field names as uppercase (row['name'] || row['NAME']).should be_kind_of(String) (row['code'] || row['CODE']).should be_kind_of(String) rows_yielded += 1 end rows_yielded.should == 15 end it 'should yield each row to the block for a single column' do rows_yielded = 0 @reader2.each do |row| row.should respond_to(:[]) row.size.should == 1 # the field names need to be case insensitive as some drivers such as # do_derby, do_h2, do_hsqldb return the field names as uppercase (row['code'] || row['CODE']).should be_kind_of(String) rows_yielded += 1 end rows_yielded.should == 15 end it 'should return the reader' do @reader.each { |row| }.should equal(@reader) end end end data_objects-0.10.16/lib/data_objects/spec/shared/result_spec.rb0000644000004100000410000000344212540210163024573 0ustar www-datawww-datashared_examples_for 'a Result' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) @result = @connection.create_command("INSERT INTO users (name) VALUES (?)").execute_non_query("monkey") end after do @connection.close end it { @result.should respond_to(:affected_rows) } describe 'affected_rows' do it 'should return the number of affected rows' do @result.affected_rows.should == 1 end end end shared_examples_for 'a Result which returns inserted key with sequences' do describe 'insert_id' do before do setup_test_environment @connection = DataObjects::Connection.new(CONFIG.uri) command = @connection.create_command("INSERT INTO users (name) VALUES (?)") # execute the command twice and expose the second result command.execute_non_query("monkey") @result = command.execute_non_query("monkey") end after do @connection.close end it { @result.should respond_to(:affected_rows) } it 'should return the insert_id' do # This is actually the 2nd record inserted @result.insert_id.should == 2 end end end shared_examples_for 'a Result which returns nil without sequences' do describe 'insert_id' do before do setup_test_environment @connection = DataObjects::Connection.new(CONFIG.uri) command = @connection.create_command("INSERT INTO invoices (invoice_number) VALUES (?)") # execute the command twice and expose the second result @result = command.execute_non_query("monkey") end after do @connection.close end it 'should return the insert_id' do # This is actually the 2nd record inserted @result.insert_id.should be_nil end end end data_objects-0.10.16/lib/data_objects/spec/shared/error/0000755000004100000410000000000012540210163023044 5ustar www-datawww-datadata_objects-0.10.16/lib/data_objects/spec/shared/error/sql_error_spec.rb0000644000004100000410000000150412540210163026413 0ustar www-datawww-datashared_examples_for 'raising a SQLError' do before :all do setup_test_environment end describe "an invalid query" do it 'should raise an error' do @connection = DataObjects::Connection.new(CONFIG.uri) invalid_query = @connection.create_command("SLCT * FROM widgets WHERE ad_description = ? order by id") expect { invalid_query.execute_reader('Buy this product now!') }.to raise_error(DataObjects::SQLError) @connection.close end end describe "an invalid result set" do it 'should raise an error' do @connection = DataObjects::Connection.new(CONFIG.uri) invalid_result = @connection.create_command("SELECT MAX((SELECT 1 UNION SELECT 2))") expect { invalid_result.execute_reader }.to raise_error(DataObjects::SQLError) @connection.close end end end data_objects-0.10.16/lib/data_objects/spec/shared/quoting_spec.rb0000644000004100000410000000000012540210163024726 0ustar www-datawww-datadata_objects-0.10.16/lib/data_objects/spec/shared/command_spec.rb0000644000004100000410000001657012540210163024701 0ustar www-datawww-dataWINDOWS = Gem.win_platform? || (JRUBY && ENV_JAVA['os.name'] =~ /windows/i) shared_examples_for 'a Command' do before :all do setup_test_environment end before do @connection = DataObjects::Connection.new(CONFIG.uri) @command = @connection.create_command("INSERT INTO users (name) VALUES (?)") @reader = @connection.create_command("SELECT code, name FROM widgets WHERE ad_description = ?") @arg_command = @connection.create_command("INSERT INTO users (name, fired_at) VALUES (?, ?)") @arg_reader = @connection.create_command("SELECT code, name FROM widgets WHERE ad_description = ? AND whitepaper_text = ?") end after do @connection.close end it { @command.should be_kind_of(DataObjects::Command) } it { @command.should respond_to(:execute_non_query) } describe 'execute_non_query' do describe 'with an invalid statement' do before do @invalid_command = @connection.create_command("INSERT INTO non_existent_table (tester) VALUES (1)") end it 'should raise an error on an invalid query' do expect { @invalid_command.execute_non_query }.to raise_error(DataObjects::SQLError) end it 'should raise an error with too many binding parameters' do expect { @arg_command.execute_non_query("Too", Date.today, "Many") }.to raise_error(ArgumentError, /Binding mismatch: 3 for 2/) end it 'should raise an error with too few binding parameters' do expect { @arg_command.execute_non_query("Few") }.to raise_error(ArgumentError, /Binding mismatch: 1 for 2/) end end describe 'with a valid statement' do it 'should not raise an error with an explicit nil as parameter' do expect { @arg_command.execute_non_query(nil, nil) }.not_to raise_error(ArgumentError) end end describe 'with a valid statement and ? inside quotes' do before do @command_with_quotes = @connection.create_command("INSERT INTO users (name) VALUES ('will it work? ')") end it 'should not raise an error' do expect { @command_with_quotes.execute_non_query }.not_to raise_error(ArgumentError) end end end it { @command.should respond_to(:execute_reader) } describe 'execute_reader' do describe 'with an invalid reader' do before do @invalid_reader = @connection.create_command("SELECT * FROM non_existent_widgets WHERE ad_description = ? AND white_paper_text = ?") end it 'should raise an error on an invalid query' do # FIXME JRuby (and MRI): Should this be an ArgumentError or DataObjects::SQLError? expect { @invalid_reader.execute_reader }.to raise_error # (ArgumentError, DataObjects::SQLError) end it 'should raise an error with too many few binding parameters' do expect { @arg_reader.execute_reader("Too", "Many", "Args") }.to raise_error(ArgumentError, /Binding mismatch: 3 for 2/) end it 'should raise an error with too few binding parameters' do expect { @arg_reader.execute_reader("Few") }.to raise_error(ArgumentError, /Binding mismatch: 1 for 2/) end end describe 'with a valid reader' do it 'should not raise an error with an explicit nil as parameter' do expect { @arg_reader.execute_reader(nil, nil) }.not_to raise_error(ArgumentError) end unless defined?(JRUBY) it 'returns an empty reader if the query does not return a result' do runs_command = @connection.create_command("UPDATE widgets SET name = '' WHERE name = ''") res = runs_command.execute_reader res.fields.should == [] res.next!.should == false end end end describe 'with a valid reader and ? inside column alias' do before do @reader_with_quotes = @connection.create_command("SELECT code AS \"code?\", name FROM widgets WHERE ad_description = ?") end it 'should not raise an error' do expect { @reader_with_quotes.execute_reader(nil) }.not_to raise_error(ArgumentError) end end end it { @command.should respond_to(:set_types) } describe 'set_types' do describe 'is invalid when used with a statement' do before do @command.set_types(String) end it 'should raise an error when types are set' do expect { @arg_command.execute_non_query("Few") }.to raise_error(ArgumentError) end end describe 'with an invalid reader' do it 'should raise an error with too few types' do @reader.set_types(String) expect { @reader.execute_reader("One parameter") }.to raise_error(ArgumentError, /Field-count mismatch. Expected 1 fields, but the query yielded 2/) end it 'should raise an error with too many types' do @reader.set_types(String, String, BigDecimal) expect { @reader.execute_reader("One parameter") }.to raise_error(ArgumentError, /Field-count mismatch. Expected 3 fields, but the query yielded 2/) end end describe 'with a valid reader' do it 'should not raise an error with correct number of types' do @reader.set_types(String, String) expect { @result = @reader.execute_reader('Buy this product now!') }.not_to raise_error(ArgumentError) expect { @result.next! }.not_to raise_error(DataObjects::DataError) expect { @result.values }.not_to raise_error(DataObjects::DataError) @result.close end it 'should also support old style array argument types' do @reader.set_types([String, String]) expect { @result = @reader.execute_reader('Buy this product now!') }.not_to raise_error(ArgumentError) expect { @result.next! }.not_to raise_error(DataObjects::DataError) expect { @result.values }.not_to raise_error(DataObjects::DataError) @result.close end it 'should allow subtype types' do class MyString < String; end @reader.set_types(MyString, String) expect { @result = @reader.execute_reader('Buy this product now!') }.not_to raise_error(ArgumentError) expect { @result.next! }.not_to raise_error(DataObjects::DataError) expect { @result.values }.not_to raise_error(DataObjects::DataError) @result.close end end end it { @command.should respond_to(:to_s) } describe 'to_s' do end end shared_examples_for 'a Command with async' do before :all do setup_test_environment end describe 'running queries in parallel' do before do threads = [] @start = Time.now 4.times do |i| threads << Thread.new do begin connection = DataObjects::Connection.new(CONFIG.uri) command = connection.create_command(CONFIG.sleep) if CONFIG.sleep =~ /^SELECT/i reader = command.execute_reader reader.next! reader.close else result = command.execute_non_query end ensure # Always make sure the connection gets released back into the pool. connection.close end end end threads.each{|t| t.join } @finish = Time.now end it "should finish within 2 seconds" do pending_if("Ruby on Windows doesn't support asynchronous operations", WINDOWS) do (@finish - @start).should < 2 end end end end data_objects-0.10.16/lib/data_objects/spec/setup.rb0000644000004100000410000000022712540210163022133 0ustar www-datawww-dataRSpec::Matchers.define :be_array_case_insensitively_equal_to do |attribute| match do |model| model.map { |f| f.downcase } == attribute end end data_objects-0.10.16/lib/data_objects/command.rb0000644000004100000410000000434212540210163021461 0ustar www-datawww-datamodule DataObjects # Abstract base class for adapter-specific Command subclasses class Command # The Connection on which the command will be run attr_reader :connection # Create a new Command object on the specified connection def initialize(connection, text) raise ArgumentError.new("+connection+ must be a DataObjects::Connection") unless DataObjects::Connection === connection @connection, @text = connection, text end # Execute this command and return no dataset def execute_non_query(*args) raise NotImplementedError.new end # Execute this command and return a DataObjects::Reader for a dataset def execute_reader(*args) raise NotImplementedError.new end # Assign an array of types for the columns to be returned by this command def set_types(column_types) raise NotImplementedError.new end # Display the command text def to_s @text end private # Escape a string of SQL with a set of arguments. # The first argument is assumed to be the SQL to escape, # the remaining arguments (if any) are assumed to be # values to escape and interpolate. # # ==== Examples # escape_sql("SELECT * FROM zoos") # # => "SELECT * FROM zoos" # # escape_sql("SELECT * FROM zoos WHERE name = ?", "Dallas") # # => "SELECT * FROM zoos WHERE name = `Dallas`" # # escape_sql("SELECT * FROM zoos WHERE name = ? AND acreage > ?", "Dallas", 40) # # => "SELECT * FROM zoos WHERE name = `Dallas` AND acreage > 40" # # ==== Warning # This method is meant mostly for adapters that don't support # bind-parameters. def escape_sql(args) return @text if args.empty? sql = @text.dup vars = args.dup replacements = 0 mismatch = false sql.gsub!(/'[^']*'|"[^"]*"|`[^`]*`|\?/) do |x| next x unless x == '?' replacements += 1 if vars.empty? mismatch = true else var = vars.shift connection.quote_value(var) end end if !vars.empty? || mismatch raise ArgumentError, "Binding mismatch: #{args.size} for #{replacements}" else sql end end end end data_objects-0.10.16/lib/data_objects/logger.rb0000644000004100000410000001604112540210163021321 0ustar www-datawww-datarequire "time" # httpdate module DataObjects module Logging def log(message) logger = driver_namespace.logger if logger.level <= DataObjects::Logger::LEVELS[:debug] message = "(%.6f) %s" % [message.duration / 1000000.0, message.query] logger.debug message end end end class << self # The global logger for DataObjects attr_accessor :logger end # ==== Public DataObjects Logger API # # Logger taken from Merb :) # # To replace an existing logger with a new one: # DataObjects::Logger.set_log(log{String, IO},level{Symbol, String}) # # Available logging levels are # DataObjects::Logger::{ Fatal, Error, Warn, Info, Debug } # # Logging via: # DataObjects.logger.fatal(message) # DataObjects.logger.error(message) # DataObjects.logger.warn(message) # DataObjects.logger.info(message) # DataObjects.logger.debug(message) # # Flush the buffer to # DataObjects.logger.flush # # Remove the current log object # DataObjects.logger.close # # ==== Private DataObjects Logger API # # To initialize the logger you create a new object, proxies to set_log. # DataObjects::Logger.new(log{String, IO},level{Symbol, String}) # # Logger will not create the file until something is actually logged # This avoids file creation on DataObjects init when it creates the # default logger. class Logger # Use asynchronous I/O? attr_accessor :aio # delimiter to use between message sections attr_accessor :delimiter # a symbol representing the log level from {:off, :fatal, :error, :warn, :info, :debug} attr_reader :level # Direct access to the buffer attr_reader :buffer # The name of the log file attr_reader :log Message = Struct.new(:query, :start, :duration) # # Ruby (standard) logger levels: # off: absolutely nothing # fatal: an unhandleable error that results in a program crash # error: a handleable error condition # warn: a warning # info: generic (useful) information about system operation # debug: low-level information for developers # # DataObjects::Logger::LEVELS[:off, :fatal, :error, :warn, :info, :debug] LEVELS = { :off => 99999, :fatal => 7, :error => 6, :warn => 4, :info => 3, :debug => 0 } # Set the log level (use the level symbols as documented) def level=(new_level) @level = LEVELS[new_level.to_sym] reset_methods(:close) end private # The idea here is that instead of performing an 'if' conditional check on # each logging we do it once when the log object is setup def set_write_method @log.instance_eval do # Determine if asynchronous IO can be used def aio? @aio = !RUBY_PLATFORM.match(/java|mswin/) && !(@log == STDOUT) && @log.respond_to?(:write_nonblock) end # Define the write method based on if aio an be used undef write_method if defined? write_method if aio? alias :write_method :write_nonblock else alias :write_method :write end end end def initialize_log(log) close if @log # be sure that we don't leave open files laying around. @log = log || "log/dm.log" end def reset_methods(o_or_c) if o_or_c == :open alias internal_push push_opened elsif o_or_c == :close alias internal_push push_closed end end def push_opened(string) message = Time.now.httpdate message << delimiter message << string message << "\n" unless message[-1] == ?\n @buffer << message flush # Force a flush for now until we figure out where we want to use the buffering. end def push_closed(string) unless @log.respond_to?(:write) log = Pathname(@log) log.dirname.mkpath @log = log.open('a') @log.sync = true end set_write_method reset_methods(:open) push(string) end alias internal_push push_closed def prep_msg(message, level) level << delimiter << message end public # To initialize the logger you create a new object, proxies to set_log. # DataObjects::Logger.new(log{String, IO},level{Symbol, String}) # # @param log either an IO object or a name of a logfile. # @param log_level the message string to be logged # @param delimiter delimiter to use between message sections # @param log_creation log that the file is being created def initialize(*args) set_log(*args) end # To replace an existing logger with a new one: # DataObjects::Logger.set_log(log{String, IO},level{Symbol, String}) # # # @param log either an IO object or a name of a logfile. # @param log_level a symbol representing the log level from # {:off, :fatal, :error, :warn, :info, :debug} # @param delimiter delimiter to use between message sections # @param log_creation log that the file is being created def set_log(log, log_level = :off, delimiter = " ~ ", log_creation = false) delimiter ||= " ~ " if log_level && LEVELS[log_level.to_sym] self.level = log_level.to_sym else self.level = :debug end @buffer = [] @delimiter = delimiter initialize_log(log) DataObjects.logger = self self.info("Logfile created") if log_creation end # Flush the entire buffer to the log object. # DataObjects.logger.flush # def flush return unless @buffer.size > 0 @log.write_method(@buffer.slice!(0..-1).join) end # Close and remove the current log object. # DataObjects.logger.close # def close flush @log.close if @log.respond_to?(:close) @log = nil end # Appends a string and log level to logger's buffer. # # Note that the string is discarded if the string's log level less than the # logger's log level. # # Note that if the logger is aio capable then the logger will use # non-blocking asynchronous writes. # # @param level the logging level as an integer # @param string the message string to be logged def push(string) internal_push(string) end alias << push # Generate the following logging methods for DataObjects.logger as described # in the API: # :fatal, :error, :warn, :info, :debug # :off only gets an off? method LEVELS.each_pair do |name, number| unless name.to_sym == :off class_eval <<-EOS, __FILE__, __LINE__ # DOC def #{name}(message) self.<<( prep_msg(message, "#{name}") ) if #{name}? end EOS end class_eval <<-EOS, __FILE__, __LINE__ # DOC def #{name}? #{number} >= level end EOS end end # class Logger end # module DataObjects data_objects-0.10.16/lib/data_objects/utilities.rb0000644000004100000410000000116512540210163022056 0ustar www-datawww-data# This is here to remove DataObject's dependency on Extlib. module DataObjects # @param name The name of the constant to get, e.g. "Merb::Router". # # @return The constant corresponding to the name. def self.full_const_get(name) list = name.split("::") list.shift if list.first.nil? || list.first.strip.empty? obj = ::Object list.each do |x| # This is required because const_get tries to look for constants in the # ancestor chain, but we only want constants that are HERE obj = obj.const_defined?(x) ? obj.const_get(x) : obj.const_missing(x) end obj end end data_objects-0.10.16/lib/data_objects/pooling.rb0000644000004100000410000001534012540210163021512 0ustar www-datawww-datarequire 'set' require 'thread' module DataObjects def self.exiting= bool if bool && DataObjects.const_defined?('Pooling') if DataObjects::Pooling.scavenger? DataObjects::Pooling.scavenger.wakeup end end @exiting = true end def self.exiting return @exiting if defined?(@exiting) @exiting = false end # ==== Notes # Provides pooling support to class it got included in. # # Pooling of objects is a faster way of aquiring instances # of objects compared to regular allocation and initialization # because instances are keeped in memory reused. # # Classes that include Pooling module have re-defined new # method that returns instances acquired from pool. # # Term resource is used for any type of poolable objects # and should NOT be thought as DataMapper Resource or # ActiveResource resource and such. # # In Data Objects connections are pooled so that it is # unnecessary to allocate and initialize connection object # each time connection is needed, like per request in a # web application. # # Pool obviously has to be thread safe because state of # object is reset when it is released. module Pooling def self.scavenger? defined?(@scavenger) && !@scavenger.nil? && @scavenger.alive? end def self.scavenger unless scavenger? @scavenger = Thread.new do running = true while running do # Sleep before we actually start doing anything. # Otherwise we might clean up something we just made sleep(scavenger_interval) lock.synchronize do pools.each do |pool| # This is a useful check, but non-essential, and right now it breaks lots of stuff. # if pool.expired? pool.lock.synchronize do if pool.expired? pool.dispose end end # end end # The pool is empty, we stop the scavenger # It wil be restarted if new resources are added again if pools.empty? running = false end end end # loop end end @scavenger.priority = -10 @scavenger end def self.pools @pools ||= Set.new end def self.append_pool(pool) lock.synchronize do pools << pool end DataObjects::Pooling.scavenger end def self.lock @lock ||= Mutex.new end class InvalidResourceError < StandardError end def self.included(target) lock.synchronize do unless target.respond_to? :__pools target.class_eval do class << self alias __new new end @__pools = {} @__pool_lock = Mutex.new @__pool_wait = ConditionVariable.new def self.__pool_lock @__pool_lock end def self.__pool_wait @__pool_wait end def self.new(*args) (@__pools[args] ||= __pool_lock.synchronize { Pool.new(self.pool_size, self, args) }).new end def self.__pools @__pools end def self.pool_size 8 end end end end end def release @__pool.release(self) unless @__pool.nil? end def detach @__pool.delete(self) unless @__pool.nil? end class Pool attr_reader :available attr_reader :used def initialize(max_size, resource, args) raise ArgumentError.new("+max_size+ should be a Fixnum but was #{max_size.inspect}") unless Fixnum === max_size raise ArgumentError.new("+resource+ should be a Class but was #{resource.inspect}") unless Class === resource @max_size = max_size @resource = resource @args = args @available = [] @used = {} DataObjects::Pooling.append_pool(self) end def lock @resource.__pool_lock end def wait @resource.__pool_wait end def scavenge_interval @resource.scavenge_interval end def new instance = nil begin lock.synchronize do if @available.size > 0 instance = @available.pop @used[instance.object_id] = instance elsif @used.size < @max_size instance = @resource.__new(*@args) raise InvalidResourceError.new("#{@resource} constructor created a nil object") if instance.nil? raise InvalidResourceError.new("#{instance} is already part of the pool") if @used.include? instance instance.instance_variable_set(:@__pool, self) instance.instance_variable_set(:@__allocated_in_pool, Time.now) @used[instance.object_id] = instance else # Wait for another thread to release an instance. # If we exhaust the pool and don't release the active instance, # we'll wait here forever, so it's *very* important to always # release your services and *never* exhaust the pool within # a single thread. wait.wait(lock) end end end until instance instance end def release(instance) lock.synchronize do instance.instance_variable_set(:@__allocated_in_pool, Time.now) @used.delete(instance.object_id) @available.push(instance) unless @available.include?(instance) wait.signal end nil end def delete(instance) lock.synchronize do instance.instance_variable_set(:@__pool, nil) @used.delete(instance.object_id) wait.signal end nil end def size @used.size + @available.size end alias length size def inspect "# available=#{@available.size} used=#{@used.size} size=#{@max_size}>" end def flush! @available.pop.dispose until @available.empty? end def dispose flush! @resource.__pools.delete(@args) !DataObjects::Pooling.pools.delete?(self).nil? end def expired? @available.each do |instance| if DataObjects.exiting || instance.instance_variable_get(:@__allocated_in_pool) + DataObjects::Pooling.scavenger_interval <= (Time.now + 0.02) instance.dispose @available.delete(instance) end end size == 0 end end def self.scavenger_interval 60 end end # module Pooling end # module DataObjects data_objects-0.10.16/lib/data_objects/version.rb0000644000004100000410000000005512540210163021525 0ustar www-datawww-datamodule DataObjects VERSION = '0.10.16' end data_objects-0.10.16/lib/data_objects/error/0000755000004100000410000000000012540210163020644 5ustar www-datawww-datadata_objects-0.10.16/lib/data_objects/error/integrity_error.rb0000644000004100000410000000007712540210163024424 0ustar www-datawww-datamodule DataObjects class IntegrityError < SQLError end end data_objects-0.10.16/lib/data_objects/error/transaction_error.rb0000644000004100000410000000010112540210163024717 0ustar www-datawww-datamodule DataObjects class TransactionError < SQLError end end data_objects-0.10.16/lib/data_objects/error/syntax_error.rb0000644000004100000410000000007412540210163023731 0ustar www-datawww-datamodule DataObjects class SyntaxError < SQLError end end data_objects-0.10.16/lib/data_objects/error/data_error.rb0000644000004100000410000000007212540210163023312 0ustar www-datawww-datamodule DataObjects class DataError < SQLError end end data_objects-0.10.16/lib/data_objects/error/sql_error.rb0000644000004100000410000000074112540210163023203 0ustar www-datawww-datamodule DataObjects class SQLError < Error attr_reader :message attr_reader :code attr_reader :sqlstate attr_reader :query attr_reader :uri def initialize(message, code = nil, sqlstate = nil, query = nil, uri = nil) @message = message @code = code @sqlstate = sqlstate @query = query @uri = uri end def to_s "#{message} (code: #{code}, sql state: #{sqlstate}, query: #{query}, uri: #{uri})" end end end data_objects-0.10.16/lib/data_objects/error/connection_error.rb0000644000004100000410000000010012540210163024530 0ustar www-datawww-datamodule DataObjects class ConnectionError < SQLError end end data_objects-0.10.16/lib/data_objects/quoting.rb0000755000004100000410000000565412540210163021543 0ustar www-datawww-datamodule DataObjects module Quoting # Quote a value of any of the recognised data types def quote_value(value) return 'NULL' if value.nil? case value when Numeric then quote_numeric(value) when ::Extlib::ByteArray then quote_byte_array(value) when String then quote_string(value) when Time then quote_time(value) when DateTime then quote_datetime(value) when Date then quote_date(value) when TrueClass, FalseClass then quote_boolean(value) when Array then quote_array(value) when Range then quote_range(value) when Symbol then quote_symbol(value) when Regexp then quote_regexp(value) when Class then quote_class(value) else if value.respond_to?(:to_sql) value.to_sql else raise "Don't know how to quote #{value.class} objects (#{value.inspect})" end end end # Convert the Symbol to a String and quote that def quote_symbol(value) quote_string(value.to_s) end # Convert the Numeric to a String and quote that def quote_numeric(value) value.to_s end # Quote a String for SQL by doubling any embedded single-quote characters def quote_string(value) "'#{value.gsub("'", "''")}'" end # Quote a class by quoting its name def quote_class(value) quote_string(value.name) end # Convert a Time to standard YMDHMS format (with microseconds if necessary) def quote_time(value) offset = value.utc_offset if offset >= 0 offset_string = "+#{sprintf("%02d", offset / 3600)}:#{sprintf("%02d", (offset % 3600) / 60)}" elsif offset < 0 offset_string = "-#{sprintf("%02d", -offset / 3600)}:#{sprintf("%02d", (-offset % 3600) / 60)}" end "'#{value.strftime('%Y-%m-%dT%H:%M:%S')}" << (value.usec > 0 ? ".#{value.usec.to_s.rjust(6, '0')}" : "") << offset_string << "'" end # Quote a DateTime by relying on it's own to_s conversion def quote_datetime(value) "'#{value.dup}'" end # Convert a Date to standard YMD format def quote_date(value) "'#{value.strftime("%Y-%m-%d")}'" end # Quote true, false as the strings TRUE, FALSE def quote_boolean(value) value.to_s.upcase end # Quote an array as a list of quoted values def quote_array(value) "(#{value.map { |entry| quote_value(entry) }.join(', ')})" end # Quote a range by joining the quoted end-point values with AND. # It's not clear whether or when this is a useful or correct thing to do. def quote_range(value) "#{quote_value(value.first)} AND #{quote_value(value.last)}" end # Quote a Regex using its string value. Note that there's no attempt to make a valid SQL "LIKE" string. def quote_regexp(value) quote_string(value.source) end def quote_byte_array(value) quote_string(value) end end end data_objects-0.10.16/lib/data_objects/extension.rb0000644000004100000410000000022412540210163022052 0ustar www-datawww-datamodule DataObjects class Extension attr_reader :connection def initialize(connection) @connection = connection end end end data_objects-0.10.16/lib/data_objects/transaction.rb0000644000004100000410000000513412540210163022370 0ustar www-datawww-datarequire 'socket' require 'digest' require 'digest/sha2' module DataObjects class Transaction # The local host name. Do not attempt to resolve in DNS to prevent potentially long delay HOST = "#{Socket::gethostname}" rescue "localhost" @@counter = 0 # The connection object allocated for this transaction attr_reader :connection # A unique ID for this transaction attr_reader :id # Instantiate the Transaction subclass that's appropriate for this uri scheme def self.create_for_uri(uri) uri = uri.is_a?(String) ? URI::parse(uri) : uri DataObjects.const_get(uri.scheme.capitalize)::Transaction.new(uri) end # # Creates a Transaction bound to a connection for the given DataObjects::URI # def initialize(uri, connection = nil) @connection = connection || DataObjects::Connection.new(uri) # PostgreSQL can't handle the full 64 bytes. This should be enough for everyone. @id = Digest::SHA256.hexdigest("#{HOST}:#{$$}:#{Time.now.to_f}:#{@@counter += 1}")[0..-2] end # Close the connection for this Transaction def close @connection.close end def begin run "BEGIN" end def commit run "COMMIT" end def rollback run "ROLLBACK" end def prepare; not_implemented; end; def begin_prepared; not_implemented; end; def commit_prepared; not_implemented; end; def rollback_prepared; not_implemented; end; def prepare; not_implemented; end; protected def run(cmd) connection.create_command(cmd).execute_non_query end private def not_implemented raise NotImplementedError end end # class Transaction class SavePoint < Transaction # We don't bounce through DO::::SavePoint because there # doesn't appear to be any custom SQL to support this. def self.create_for_uri(uri, connection) uri = uri.is_a?(String) ? URI::parse(uri) : uri DataObjects::SavePoint.new(uri, connection) end # SavePoints can only occur in the context of a Transaction, thus they # re-use TXN's connection (which was acquired from the connection pool # legitimately via DO::Connection.new). We no-op #close in SP because # calling DO::Connection#close will release the connection back into the # pool (before the top-level Transaction might be done with it). def close # no-op end def begin run %{SAVEPOINT "#{@id}"} end def commit run %{RELEASE SAVEPOINT "#{@id}"} end def rollback run %{ROLLBACK TO SAVEPOINT "#{@id}"} end end # class SavePoint end data_objects-0.10.16/lib/data_objects/error.rb0000644000004100000410000000007312540210163021171 0ustar www-datawww-datamodule DataObjects class Error < StandardError end end data_objects-0.10.16/lib/data_objects/reader.rb0000644000004100000410000000211412540210163021300 0ustar www-datawww-datamodule DataObjects # Abstract class to read rows from a query result class Reader include Enumerable # Return the array of field names def fields raise NotImplementedError.new end # Return the array of field values for the current row. Not legal after next! has returned false or before it's been called def values raise NotImplementedError.new end # Close the reader discarding any unread results. def close raise NotImplementedError.new end # Discard the current row (if any) and read the next one (returning true), or return nil if there is no further row. def next! raise NotImplementedError.new end # Return the number of fields in the result set. def field_count raise NotImplementedError.new end # Yield each row to the given block as a Hash def each begin while next! row = {} fields.each_with_index { |field, index| row[field] = values[index] } yield row end ensure close end self end end end data_objects-0.10.16/lib/data_objects.rb0000644000004100000410000000127212540210163020042 0ustar www-datawww-datarequire 'data_objects/version' require 'data_objects/utilities' require 'data_objects/logger' require 'data_objects/byte_array' require 'data_objects/pooling' require 'data_objects/connection' require 'data_objects/uri' require 'data_objects/transaction' require 'data_objects/command' require 'data_objects/result' require 'data_objects/reader' require 'data_objects/quoting' require 'data_objects/extension' require 'data_objects/error' require 'data_objects/error/sql_error' require 'data_objects/error/connection_error' require 'data_objects/error/data_error' require 'data_objects/error/integrity_error' require 'data_objects/error/syntax_error' require 'data_objects/error/transaction_error' data_objects-0.10.16/README.markdown0000644000004100000410000000062512540210163017027 0ustar www-datawww-data# data_objects * ## Description A unified Ruby API for popular databases. ## License Licensed under the MIT license. Please see the {file:LICENSE} for more information. ## Contact **IRC**: **Join us on IRC in #datamapper on irc.freenode.net!**
**Git**:
**Author**: Dirkjan Bussink
**License**: MIT License data_objects-0.10.16/metadata.yml0000644000004100000410000001104612540210163016630 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: data_objects version: !ruby/object:Gem::Version version: 0.10.16 platform: ruby authors: - Dirkjan Bussink autorequire: bindir: bin cert_chain: [] date: 2015-05-17 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: addressable requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '2.1' type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '2.1' - !ruby/object:Gem::Dependency name: rspec requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '2.5' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '2.5' - !ruby/object:Gem::Dependency name: yard requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '0.5' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '0.5' description: Provide a standard and simplified API for communicating with RDBMS from Ruby email: d.bussink@gmail.com executables: [] extensions: [] extra_rdoc_files: - README.markdown files: - ChangeLog.markdown - LICENSE - README.markdown - Rakefile - lib/data_objects.rb - lib/data_objects/byte_array.rb - lib/data_objects/command.rb - lib/data_objects/connection.rb - lib/data_objects/error.rb - lib/data_objects/error/connection_error.rb - lib/data_objects/error/data_error.rb - lib/data_objects/error/integrity_error.rb - lib/data_objects/error/sql_error.rb - lib/data_objects/error/syntax_error.rb - lib/data_objects/error/transaction_error.rb - lib/data_objects/extension.rb - lib/data_objects/logger.rb - lib/data_objects/pooling.rb - lib/data_objects/quoting.rb - lib/data_objects/reader.rb - lib/data_objects/result.rb - lib/data_objects/spec/lib/pending_helpers.rb - lib/data_objects/spec/lib/ssl.rb - lib/data_objects/spec/setup.rb - lib/data_objects/spec/shared/command_spec.rb - lib/data_objects/spec/shared/connection_spec.rb - lib/data_objects/spec/shared/encoding_spec.rb - lib/data_objects/spec/shared/error/sql_error_spec.rb - lib/data_objects/spec/shared/quoting_spec.rb - lib/data_objects/spec/shared/reader_spec.rb - lib/data_objects/spec/shared/result_spec.rb - lib/data_objects/spec/shared/typecast/array_spec.rb - lib/data_objects/spec/shared/typecast/bigdecimal_spec.rb - lib/data_objects/spec/shared/typecast/boolean_spec.rb - lib/data_objects/spec/shared/typecast/byte_array_spec.rb - lib/data_objects/spec/shared/typecast/class_spec.rb - lib/data_objects/spec/shared/typecast/date_spec.rb - lib/data_objects/spec/shared/typecast/datetime_spec.rb - lib/data_objects/spec/shared/typecast/float_spec.rb - lib/data_objects/spec/shared/typecast/integer_spec.rb - lib/data_objects/spec/shared/typecast/ipaddr_spec.rb - lib/data_objects/spec/shared/typecast/nil_spec.rb - lib/data_objects/spec/shared/typecast/other_spec.rb - lib/data_objects/spec/shared/typecast/range_spec.rb - lib/data_objects/spec/shared/typecast/string_spec.rb - lib/data_objects/spec/shared/typecast/time_spec.rb - lib/data_objects/transaction.rb - lib/data_objects/uri.rb - lib/data_objects/utilities.rb - lib/data_objects/version.rb - spec/command_spec.rb - spec/connection_spec.rb - spec/do_mock.rb - spec/do_mock2.rb - spec/pooling_spec.rb - spec/reader_spec.rb - spec/result_spec.rb - spec/spec_helper.rb - spec/transaction_spec.rb - spec/uri_spec.rb - tasks/release.rake - tasks/spec.rake - tasks/yard.rake - tasks/yardstick.rake homepage: http://github.com/datamapper/do licenses: [] metadata: {} post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: dorb rubygems_version: 2.0.14 signing_key: specification_version: 3 summary: DataObjects basic API and shared driver specifications test_files: - spec/command_spec.rb - spec/connection_spec.rb - spec/do_mock.rb - spec/do_mock2.rb - spec/pooling_spec.rb - spec/reader_spec.rb - spec/result_spec.rb - spec/spec_helper.rb - spec/transaction_spec.rb - spec/uri_spec.rb data_objects-0.10.16/ChangeLog.markdown0000644000004100000410000000512212540210163017716 0ustar www-datawww-data## 0.10.16 2015-05-17 * Fix compile issue with do\_postgres on stock OS X Ruby ## 0.10.15 2015-02-15 * Ruby 2.2 support * Double after free fix in do\_postgres * utf8mb4 support on do\_mysql * Windows support on 2.1.x and 2.2.x ## 0.10.14 2014-02-13 * Don't do DNS lookup in transaction loading ## 0.10.13 2013-05-27 * Create binaries for Ruby 2.0 on Windows * Fix segfault in do\_postgres * Fix compilation of do\_oracle for Ruby 2.0 ## 0.10.12 2013-01-21 * Fix JRuby driver loading for newer jdbc-\* gems * Compatibility change for anscient MySQL versions ## 0.10.11 2012-12-29 * Rename C symbols to prevent name collitions ## 0.10.10 2012-10-11 * JRuby performance improvements * Reconnect added on JRuby * do\_sqlite3 C driver supports busy\_timeout ## 0.10.9 2012-08-13 * Don't try to escape queries when no binding parameters are given ## 0.10.8 2012-02-10 * Ruby 1.9.3 compatibility on Windows * Don't display password in URI ## 0.10.7 2011-10-13 * Ruby 1.9.3 compatibility ## 0.10.6 2011-05-22 Bugfixes * Fix an issue on some platforms when multiple DO drivers are loaded ## 0.10.5 2011-05-03 Bugfixes * Fix an issue with DateTime (do\_sqlite3) ## 0.10.4 2011-04-28 New features * Add save point to transactions (all) * JRuby 1.9 mode support (encodings etc.) Bugfixes * Fix segfault when no tuples are returned from a non select statement (do\_postgres) * Fix bug when using nested transactions in concurrent scenarios (all) * Use column aliases instead of names (jruby) * DST calculation fixes (all) * Attempt to add better support for ancient MySQL versions (do\_mysql) * Fix handling sub second precision for Time objects (do\_postgres) Other * Refactor to DRY up the adapters (all) * Many style fixes * Switch back to RSpec ## 0.10.3 2011-01-30 * Reworked transactions * Fix a DST bug that could cause datetimes in the wrong timezone ## 0.10.2 2010-05-19 * Support for Encoding.default_internal * Rework logging to adding a callback is possible ## 0.10.1 2010-01-08 * Removal of Extlib dependency: Pooling and Utilities code moved to DataObjects. * Switch to Jeweler for Gem building tasks (this change may be temporary). * Switch to using Bacon for running specs: This should make specs friendlier to new Ruby implementations that are not yet 100% MRI-compatible, and in turn, pave the road for our own IronRuby and MacRuby support. * Make DataObjects::Reader Enumerable. ## 0.10.0 2009-09-15 * No Changes since 0.9.11 ## 0.9.11 2009-01-19 * Fixes * Use Extlib `Object.full_const_get` instead of custom code * Remove Field as it was unused ## 0.9.9 2008-11-27 * No Changes since 0.9.8 data_objects-0.10.16/tasks/0000755000004100000410000000000012540210163015450 5ustar www-datawww-datadata_objects-0.10.16/tasks/yard.rake0000644000004100000410000000026412540210163017255 0ustar www-datawww-databegin require 'yard' YARD::Rake::YardocTask.new rescue LoadError task :yard do abort 'YARD is not available. In order to run yard, you must: gem install yard' end end data_objects-0.10.16/tasks/spec.rake0000644000004100000410000000045312540210163017250 0ustar www-datawww-datarequire 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) do |spec| spec.pattern = './spec/**/*_spec.rb' end RSpec::Core::RakeTask.new(:rcov) do |rcov| rcov.pattern = "./spec/**/*_spec.rb" rcov.rcov = true rcov.rcov_opts = File.read('spec/rcov.opts').split(/\s+/) end data_objects-0.10.16/tasks/yardstick.rake0000644000004100000410000000074512540210163020317 0ustar www-datawww-databegin require 'pathname' require 'yardstick/rake/measurement' require 'yardstick/rake/verify' # yardstick_measure task Yardstick::Rake::Measurement.new # verify_measurements task Yardstick::Rake::Verify.new do |verify| verify.threshold = 100 end rescue LoadError %w[ yardstick_measure verify_measurements ].each do |name| task name.to_s do abort "Yardstick is not available. In order to run #{name}, you must: gem install yardstick" end end end data_objects-0.10.16/tasks/release.rake0000644000004100000410000000061312540210163017734 0ustar www-datawww-datadesc 'Builds all gems (native, binaries for JRuby and Windows)' task :build_all do `rake clean` `rake build` end desc 'Release all gems (native, binaries for JRuby and Windows)' task :release_all => :build_all do Dir["pkg/data_objects-#{DataObjects::VERSION}*.gem"].each do |gem_path| command = "gem push #{gem_path}" puts "Executing #{command.inspect}:" sh command end end data_objects-0.10.16/LICENSE0000644000004100000410000000206712540210163015335 0ustar www-datawww-dataCopyright (c) 2007 - 2011 Yehuda Katz, Dirkjan Bussink Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.