lib/swift/adapter.rb in swift-0.10.0 vs lib/swift/adapter.rb in swift-0.11.0

- old
+ new

@@ -2,14 +2,10 @@ # Adapter. # # @abstract # @see Swift::DB See Swift::DB for concrete adapters. - # @todo For the time being all adapters are SQL and DBIC++ centric. It would be super easy to abstract though I - # don't know if you would be better off doing it at the Ruby or DBIC++ level (or both). - #-- - # TODO: Extension methods are undocumented. class Adapter attr_reader :options # Select by id(s). # @@ -27,73 +23,10 @@ def get scheme, keys resource = scheme.new(keys) prepare_get(scheme).execute(*resource.tuple.values_at(*scheme.header.keys)).first end - # Select one or more. - # - # @example All. - # Swif.db.all(User) - # @example All with conditions and binds. - # Swift.db.all(User, ':name = ? and :age > ?', 'Apple Arthurton', 32) - # @example Block form iterator. - # Swift.db.all(User, ':age > ?', 32) do |user| - # puts user.name - # end - # - # @param [Swift::Scheme] scheme Concrete scheme subclass to load. - # @param [String] conditions Optional SQL 'where' fragment. - # @param [Object, ...] *binds Optional bind values that accompany conditions SQL fragment. - # @param [Proc] &block Optional 'each' iterator block. - # @return [Swift::Result] - # @see Swift::Scheme.all - def all scheme, conditions = '', *binds, &block - where = "where #{exchange_names(scheme, conditions)}" unless conditions.empty? - prepare(scheme, "select * from #{scheme.store} #{where}").execute(*binds, &block) - end - - # Select one. - # - # @example First. - # Swif.db.first(User) - # @example First with conditions and binds. - # Swift.db.first(User, ':name = ? and :age > ?', 'Apple Arthurton', 32) - # @example Block form iterator. - # Swift.db.first(User, ':age > ?', 32) do |user| - # puts user.name - # end - # - # @param [Swift::Scheme] scheme Concrete scheme subclass to load. - # @param [String] conditions Optional SQL 'where' fragment. - # @param [Object, ...] *binds Optional bind values that accompany conditions SQL fragment. - # @param [Proc] &block Optional 'each' iterator block. - # @return [Swift::Scheme, nil] - # @see Swift::Scheme.first - def first scheme, conditions = '', *binds, &block - where = "where #{exchange_names(scheme, conditions)}" unless conditions.empty? - prepare(scheme, "select * from #{scheme.store} #{where} limit 1").execute(*binds, &block).first - end - - # Delete one or more. - # - # The SQL condition form of Swift::Adapter.destroy. - # - # @example All. - # Swift.db.delete(User) - # @example All with conditions and binds. - # Swift.db.delete(User, ':name = ? and :age > ?', 'Apple Arthurton', 32) - # - # @param [Swift::Scheme] scheme Concrete scheme subclass - # @param [String] conditions Optional SQL 'where' fragment. - # @param [Object, ...] *binds Optional bind values that accompany conditions SQL fragment. - # @return [Swift::Result] - def delete scheme, conditions = '', *binds - sql = "delete from #{scheme.store}" - sql += " where #{exchange_names(scheme, conditions)}" unless conditions.empty? - execute(sql, *binds) - end - # Create one or more. # # @example Scheme. # user = User.new(name: 'Apply Arthurton', age: 32) # Swift.db.create(User, user) @@ -150,11 +83,11 @@ # Swift.db.update(User, [apple.tuple, benny.tuple]) # #=> Array<Swift::Scheme> # # @param [Swift::Scheme] scheme Concrete scheme subclass to load. # @param [Swift::Scheme, Hash, Array<Swift::Scheme, Hash>] resources The resources to be updated. - # @return [Swift::Scheme, Swift::Result<Swift::Scheme>] + # @return [Swift::Scheme, Swift::Result] # @note Hashes will be coerced into a Swift::Scheme resource via Swift::Scheme#new # @note Passing a scalar will result in a scalar. # @see Swift::Scheme#update def update scheme, resources statement = prepare_update(scheme) @@ -170,37 +103,37 @@ resource end resources.kind_of?(Array) ? result : result.first end - # Destroy one or more. + # Delete one or more. # # @example Scheme. # user = Swift.db.create(User, name: 'Apply Arthurton', age: 32) # user.name = 'Arthur Appleton' - # Swift.db.destroy(User, user) + # Swift.db.delete(User, user) # @example Coerce hash to scheme. # user = Swift.db.create(User, name: 'Apply Arthurton', age: 32) # user.name = 'Arthur Appleton' - # Swif.db.destroy(User, user.tuple) + # Swif.db.delete(User, user.tuple) # @example Multiple resources. # apple = Swift.db.create(User, name: 'Apple Arthurton', age: 32) # benny = Swift.db.create(User, name: 'Benny Arthurton', age: 30) - # Swift.db.destroy(User, [apple, benny]) + # Swift.db.delete(User, [apple, benny]) # @example Coerce multiple resources. # apple = Swift.db.create(User, name: 'Apple Arthurton', age: 32) # benny = Swift.db.create(User, name: 'Benny Arthurton', age: 30) - # Swift.db.destroy(User, [apple.tuple, benny.tuple]) + # Swift.db.delete(User, [apple.tuple, benny.tuple]) # # @param [Swift::Scheme] scheme Concrete scheme subclass to load. - # @param [Swift::Scheme, Hash, Array<Swift::Scheme, Hash>] resources The resources to be destroyed. + # @param [Swift::Scheme, Hash, Array<Swift::Scheme, Hash>] resources The resources to be deleteed. # @return [Swift::Scheme, Array<Swift::Scheme>] # @note Hashes will be coerced into a Swift::Scheme resource via Swift::Scheme#new # @note Passing a scalar will result in a scalar. - # @see Swift::Scheme#destroy - def destroy scheme, resources - statement = prepare_destroy(scheme) + # @see Swift::Scheme#delete + def delete scheme, resources + statement = prepare_delete(scheme) result = [resources].flatten.map do |resource| resource = scheme.new(resource) unless resource.kind_of?(scheme) keys = resource.tuple.values_at(*scheme.header.keys) # TODO: Name the key field(s) missing. @@ -213,78 +146,24 @@ result end resources.kind_of?(Array) ? result : result.first end - - def migrate! scheme - keys = scheme.header.keys - fields = scheme.header.map{|p| field_definition(p)}.join(', ') - fields += ", primary key (#{keys.join(', ')})" unless keys.empty? - - execute("drop table if exists #{scheme.store} cascade") - execute("create table #{scheme.store} (#{fields})") - end - protected - def exchange_names scheme, query - query.gsub(/:(\w+)/){ scheme.send($1.to_sym).field } - end - - def returning? + def prepare_get scheme raise NotImplementedError end - def prepare_cached scheme, name, &block - @prepared ||= Hash.new{|h,k| h[k] = Hash.new} # Autovivification please Matz! - @prepared[scheme][name] ||= prepare(scheme, yield) - end - - def prepare_get scheme - prepare_cached(scheme, :get) do - where = scheme.header.keys.map{|key| "#{key} = ?"}.join(' and ') - "select * from #{scheme.store} where #{where} limit 1" - end - end - def prepare_create scheme - prepare_cached(scheme, :create) do - values = (['?'] * scheme.header.insertable.size).join(', ') - returning = "returning #{scheme.header.serial}" if scheme.header.serial and returning? - "insert into #{scheme.store} (#{scheme.header.insertable.join(', ')}) values (#{values}) #{returning}" - end + raise NotImplementedError end def prepare_update scheme - prepare_cached(scheme, :update) do - set = scheme.header.updatable.map{|field| "#{field} = ?"}.join(', ') - where = scheme.header.keys.map{|key| "#{key} = ?"}.join(' and ') - "update #{scheme.store} set #{set} where #{where}" - end + raise NotImplementedError end - def prepare_destroy scheme - prepare_cached(scheme, :destroy) do - where = scheme.header.keys.map{|key| "#{key} = ?"}.join(' and ') - "delete from #{scheme.store} where #{where}" - end + def prepare_delete scheme + raise NotImplementedError end - def field_definition attribute - "#{attribute.field} " + field_type(attribute) - end - - def field_type attribute - case attribute - when Type::String then 'text' - when Type::Integer then attribute.serial ? 'serial' : 'integer' - when Type::Float then 'float' - when Type::BigDecimal then 'numeric' - when Type::Time then 'timestamp' - when Type::Date then 'date' - when Type::Boolean then 'boolean' - when Type::IO then 'blob' - else 'text' - end - end end # Adapter end # Swift