puffs 0.2.05 → 0.2.06
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/relation.rb +56 -62
- data/lib/sql_object/associatable.rb +96 -76
- data/lib/sql_object/searchable.rb +32 -0
- data/lib/sql_object/sql_object.rb +15 -45
- data/puffs.gemspec +1 -1
- metadata +3 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: ffc8090b37bd60c44f6e9ab1c3b03a13efdd8245
         | 
| 4 | 
            +
              data.tar.gz: ee5f09a1613a4536a6ce8e22bae477d532b5b94e
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 29c2b60efd307a57c81242884f8285d17496fdbec2363063132d28b9b0315b5dfcfbcf7d3694c0c68dd4f450c785849ef9b36e606f7e80cde6c1bb18d7a7c27d
         | 
| 7 | 
            +
              data.tar.gz: 37f8b2b9207f48566161989d72892203640cae3fa92b2f544f1ccd1cb8d0344c802b5f2e7d0dd8b0404ca8e5bc1817f10616ae87520aa68575d8582319c51773
         | 
    
        data/lib/relation.rb
    CHANGED
    
    | @@ -1,7 +1,5 @@ | |
| 1 | 
            -
            require_relative './../lib/db_connection'
         | 
| 2 | 
            -
            require_relative 'sql_object/sql_object'
         | 
| 3 | 
            -
             | 
| 4 1 | 
             
            module Puffs
         | 
| 2 | 
            +
              # Queries made through Puffs::SQLObject return instance of SQLRelation
         | 
| 5 3 | 
             
              class SQLRelation
         | 
| 6 4 | 
             
                def self.build_association(base, included, method_name)
         | 
| 7 5 | 
             
                  base.included_relations << included
         | 
| @@ -19,13 +17,13 @@ module Puffs | |
| 19 17 |  | 
| 20 18 | 
             
                  match = proc do
         | 
| 21 19 | 
             
                    selection = included.select do |i_sql_obj|
         | 
| 22 | 
            -
                      i_sql_obj.send(i_send) ==  | 
| 20 | 
            +
                      i_sql_obj.send(i_send) == send(b_send)
         | 
| 23 21 | 
             
                    end
         | 
| 24 22 |  | 
| 25 23 | 
             
                    associated = has_many ? selection : selection.first
         | 
| 26 24 |  | 
| 27 | 
            -
                    #After we find our values iteratively, we overwrite the method again
         | 
| 28 | 
            -
                    #to the result values to reduce future lookup time to O(1).
         | 
| 25 | 
            +
                    # After we find our values iteratively, we overwrite the method again
         | 
| 26 | 
            +
                    # to the result values to reduce future lookup time to O(1).
         | 
| 29 27 | 
             
                    new_match = proc { associated }
         | 
| 30 28 | 
             
                    Puffs::SQLObject.define_singleton_method_by_proc(
         | 
| 31 29 | 
             
                      self, method_name, new_match)
         | 
| @@ -33,8 +31,9 @@ module Puffs | |
| 33 31 | 
             
                    associated
         | 
| 34 32 | 
             
                  end
         | 
| 35 33 |  | 
| 36 | 
            -
                  # | 
| 37 | 
            -
                  #collection so that it points to our cached relation and | 
| 34 | 
            +
                  # We overwrite the association method for each SQLObject in the
         | 
| 35 | 
            +
                  # collection so that it points to our cached relation and
         | 
| 36 | 
            +
                  # doesn't fire a query.
         | 
| 38 37 | 
             
                  base.collection.each do |b_sql_obj|
         | 
| 39 38 | 
             
                    Puffs::SQLObject.define_singleton_method_by_proc(
         | 
| 40 39 | 
             
                      b_sql_obj, method_name, match)
         | 
| @@ -46,21 +45,20 @@ module Puffs | |
| 46 45 |  | 
| 47 46 | 
             
                def initialize(options)
         | 
| 48 47 | 
             
                  defaults =
         | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 52 | 
            -
                     | 
| 53 | 
            -
             | 
| 48 | 
            +
                    {
         | 
| 49 | 
            +
                      loaded: false,
         | 
| 50 | 
            +
                      collection: []
         | 
| 51 | 
            +
                    }
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                  merged_options = defaults.merge(options)
         | 
| 54 54 |  | 
| 55 55 | 
             
                  @klass      = options[:klass]
         | 
| 56 | 
            -
                  @collection =  | 
| 57 | 
            -
                  @loaded     =  | 
| 56 | 
            +
                  @collection = merged_options[:collection]
         | 
| 57 | 
            +
                  @loaded     = merged_options[:loaded]
         | 
| 58 58 | 
             
                end
         | 
| 59 59 |  | 
| 60 60 | 
             
                def <<(item)
         | 
| 61 | 
            -
                  if item.class == klass
         | 
| 62 | 
            -
                    @collection << item
         | 
| 63 | 
            -
                  end
         | 
| 61 | 
            +
                  @collection << item if item.class == klass
         | 
| 64 62 | 
             
                end
         | 
| 65 63 |  | 
| 66 64 | 
             
                def count
         | 
| @@ -87,13 +85,13 @@ module Puffs | |
| 87 85 | 
             
                end
         | 
| 88 86 |  | 
| 89 87 | 
             
                def load
         | 
| 90 | 
            -
                   | 
| 88 | 
            +
                  unless loaded
         | 
| 91 89 | 
             
                    puts "LOADING #{table_name}"
         | 
| 92 | 
            -
             | 
| 90 | 
            +
                    results = Puffs::DBConnection.execute(<<-SQL, sql_params[:values])
         | 
| 93 91 | 
             
                      SELECT
         | 
| 94 | 
            -
                        #{sql_count ?  | 
| 92 | 
            +
                        #{sql_count ? 'COUNT(*)' : table_name.to_s + '.*'}
         | 
| 95 93 | 
             
                      FROM
         | 
| 96 | 
            -
                        #{ | 
| 94 | 
            +
                        #{table_name}
         | 
| 97 95 | 
             
                      #{sql_params[:where]}
         | 
| 98 96 | 
             
                        #{sql_params[:params]}
         | 
| 99 97 | 
             
                      #{order_by_string}
         | 
| @@ -103,56 +101,49 @@ module Puffs | |
| 103 101 | 
             
                    results = sql_count ? results.first.values.first : parse_all(results)
         | 
| 104 102 | 
             
                  end
         | 
| 105 103 |  | 
| 106 | 
            -
                  results  | 
| 107 | 
            -
             | 
| 108 | 
            -
                  unless includes_params.empty?
         | 
| 109 | 
            -
                    results = load_includes(results)
         | 
| 110 | 
            -
                  end
         | 
| 111 | 
            -
             | 
| 104 | 
            +
                  results ||= self
         | 
| 105 | 
            +
                  results = load_includes(results) unless includes_params.empty?
         | 
| 112 106 | 
             
                  results
         | 
| 113 107 | 
             
                end
         | 
| 114 108 |  | 
| 115 109 | 
             
                def load_includes(relation)
         | 
| 116 110 | 
             
                  includes_params.each do |param|
         | 
| 117 | 
            -
                     | 
| 118 | 
            -
             | 
| 119 | 
            -
             | 
| 120 | 
            -
             | 
| 121 | 
            -
             | 
| 122 | 
            -
             | 
| 123 | 
            -
             | 
| 124 | 
            -
             | 
| 125 | 
            -
             | 
| 126 | 
            -
             | 
| 127 | 
            -
             | 
| 128 | 
            -
             | 
| 129 | 
            -
             | 
| 130 | 
            -
             | 
| 131 | 
            -
             | 
| 132 | 
            -
             | 
| 133 | 
            -
             | 
| 134 | 
            -
             | 
| 135 | 
            -
             | 
| 136 | 
            -
             | 
| 137 | 
            -
             | 
| 138 | 
            -
             | 
| 139 | 
            -
                      included = assoc.model_class.parse_all(results)
         | 
| 140 | 
            -
                      SQLRelation.build_association(relation, included, param)
         | 
| 141 | 
            -
                    end
         | 
| 111 | 
            +
                    next unless relation.klass.has_association?(param)
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                    puts "LOADING #{param}"
         | 
| 114 | 
            +
                    assoc = klass.assoc_options[param]
         | 
| 115 | 
            +
                    f_k = assoc.foreign_key
         | 
| 116 | 
            +
                    p_k = assoc.primary_key
         | 
| 117 | 
            +
                    includes_table = assoc.table_name.to_s
         | 
| 118 | 
            +
                    in_ids = relation.collection.map(&:id).join(', ')
         | 
| 119 | 
            +
                    has_many = assoc.class == HasManyOptions
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                    results = Puffs::DBConnection.execute(<<-SQL)
         | 
| 122 | 
            +
                      SELECT
         | 
| 123 | 
            +
                        #{includes_table}.*
         | 
| 124 | 
            +
                      FROM
         | 
| 125 | 
            +
                        #{includes_table}
         | 
| 126 | 
            +
                      WHERE
         | 
| 127 | 
            +
                        #{includes_table}.#{has_many ? f_k : p_k}
         | 
| 128 | 
            +
                      IN
         | 
| 129 | 
            +
                        (#{in_ids});
         | 
| 130 | 
            +
                    SQL
         | 
| 131 | 
            +
                    included = assoc.model_class.parse_all(results)
         | 
| 132 | 
            +
                    SQLRelation.build_association(relation, included, param)
         | 
| 142 133 | 
             
                  end
         | 
| 143 134 |  | 
| 144 135 | 
             
                  relation
         | 
| 145 136 | 
             
                end
         | 
| 146 137 |  | 
| 147 138 | 
             
                def method_missing(method, *args, &block)
         | 
| 148 | 
            -
                   | 
| 139 | 
            +
                  to_a.send(method, *args, &block)
         | 
| 149 140 | 
             
                end
         | 
| 150 141 |  | 
| 151 142 | 
             
                def order(params)
         | 
| 152 143 | 
             
                  if params.is_a?(Hash)
         | 
| 153 144 | 
             
                    order_params_hash.merge!(params)
         | 
| 154 145 | 
             
                  else
         | 
| 155 | 
            -
                    order_params_hash | 
| 146 | 
            +
                    order_params_hash[params] = :asc
         | 
| 156 147 | 
             
                  end
         | 
| 157 148 | 
             
                  self
         | 
| 158 149 | 
             
                end
         | 
| @@ -164,17 +155,20 @@ module Puffs | |
| 164 155 | 
             
                def order_by_string
         | 
| 165 156 | 
             
                  hash_string = order_params_hash.map do |column, asc_desc|
         | 
| 166 157 | 
             
                    "#{column} #{asc_desc.to_s.upcase}"
         | 
| 167 | 
            -
                  end.join( | 
| 158 | 
            +
                  end.join(', ')
         | 
| 168 159 |  | 
| 169 | 
            -
                  hash_string.empty? ?  | 
| 160 | 
            +
                  hash_string.empty? ? '' : "ORDER BY #{hash_string}"
         | 
| 170 161 | 
             
                end
         | 
| 171 162 |  | 
| 172 163 | 
             
                def parse_all(attributes)
         | 
| 173 | 
            -
                  klass.parse_all(attributes) | 
| 164 | 
            +
                  klass.parse_all(attributes)
         | 
| 165 | 
            +
                       .where(where_params_hash)
         | 
| 166 | 
            +
                       .includes(includes_params)
         | 
| 174 167 | 
             
                end
         | 
| 175 168 |  | 
| 176 169 | 
             
                def sql_params
         | 
| 177 | 
            -
                  params | 
| 170 | 
            +
                  params = []
         | 
| 171 | 
            +
                  values = []
         | 
| 178 172 |  | 
| 179 173 | 
             
                  i = 1
         | 
| 180 174 | 
             
                  where_params_hash.map do |attribute, value|
         | 
| @@ -183,8 +177,8 @@ module Puffs | |
| 183 177 | 
             
                    i += 1
         | 
| 184 178 | 
             
                  end
         | 
| 185 179 |  | 
| 186 | 
            -
                  { params: params.join( | 
| 187 | 
            -
                    where: params.empty? ? nil :  | 
| 180 | 
            +
                  { params: params.join(' AND '),
         | 
| 181 | 
            +
                    where: params.empty? ? nil : 'WHERE',
         | 
| 188 182 | 
             
                    values: values }
         | 
| 189 183 | 
             
                end
         | 
| 190 184 |  | 
| @@ -193,7 +187,7 @@ module Puffs | |
| 193 187 | 
             
                end
         | 
| 194 188 |  | 
| 195 189 | 
             
                def to_a
         | 
| 196 | 
            -
                   | 
| 190 | 
            +
                  load.collection
         | 
| 197 191 | 
             
                end
         | 
| 198 192 |  | 
| 199 193 | 
             
                def where_params_hash
         | 
| @@ -1,99 +1,119 @@ | |
| 1 1 | 
             
            require 'active_support/inflector'
         | 
| 2 2 |  | 
| 3 | 
            -
             | 
| 4 | 
            -
             | 
| 5 | 
            -
             | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 3 | 
            +
            # Used in HasManyOptions and BelongsToOptions
         | 
| 4 | 
            +
            class AssocOptions
         | 
| 5 | 
            +
              attr_accessor(
         | 
| 6 | 
            +
                :foreign_key,
         | 
| 7 | 
            +
                :class_name,
         | 
| 8 | 
            +
                :primary_key
         | 
| 9 | 
            +
              )
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              def model_class
         | 
| 12 | 
            +
                class_name.constantize
         | 
| 13 | 
            +
              end
         | 
| 14 14 |  | 
| 15 | 
            -
             | 
| 16 | 
            -
             | 
| 17 | 
            -
                end
         | 
| 15 | 
            +
              def table_name
         | 
| 16 | 
            +
                model_class.table_name
         | 
| 18 17 | 
             
              end
         | 
| 18 | 
            +
            end
         | 
| 19 19 |  | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
                   | 
| 25 | 
            -
             | 
| 20 | 
            +
            # Used to build belongs_to associations.
         | 
| 21 | 
            +
            class BelongsToOptions < AssocOptions
         | 
| 22 | 
            +
              def initialize(name, options = {})
         | 
| 23 | 
            +
                defaults = {
         | 
| 24 | 
            +
                  primary_key: :id,
         | 
| 25 | 
            +
                  foreign_key: "#{name}_id".to_sym,
         | 
| 26 | 
            +
                  class_name: name.to_s.capitalize
         | 
| 27 | 
            +
                }
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                merged_options = defaults.merge(options)
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                @primary_key = merged_options[:primary_key]
         | 
| 32 | 
            +
                @foreign_key = merged_options[:foreign_key]
         | 
| 33 | 
            +
                @class_name = merged_options[:class_name]
         | 
| 26 34 | 
             
              end
         | 
| 35 | 
            +
            end
         | 
| 27 36 |  | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 32 | 
            -
                   | 
| 33 | 
            -
             | 
| 37 | 
            +
            # Used to build has_many associations.
         | 
| 38 | 
            +
            class HasManyOptions < AssocOptions
         | 
| 39 | 
            +
              def initialize(name, self_class_name, options = {})
         | 
| 40 | 
            +
                defaults = {
         | 
| 41 | 
            +
                  primary_key: :id,
         | 
| 42 | 
            +
                  foreign_key: "#{self_class_name.to_s.underscore}_id".to_sym,
         | 
| 43 | 
            +
                  class_name: name.to_s.singularize.camelcase
         | 
| 44 | 
            +
                }
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                merged_options = defaults.merge(options)
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                @primary_key = merged_options[:primary_key]
         | 
| 49 | 
            +
                @foreign_key = merged_options[:foreign_key]
         | 
| 50 | 
            +
                @class_name = merged_options[:class_name]
         | 
| 34 51 | 
             
              end
         | 
| 52 | 
            +
            end
         | 
| 35 53 |  | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 54 | 
            +
            # Used to map association methods.
         | 
| 55 | 
            +
            module Associatable
         | 
| 56 | 
            +
              def belongs_to(name, options = {})
         | 
| 57 | 
            +
                options = BelongsToOptions.new(name, options)
         | 
| 58 | 
            +
                assoc_options[name] = options
         | 
| 40 59 |  | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 60 | 
            +
                define_method(name) do
         | 
| 61 | 
            +
                  foreign_key_value = send(options.foreign_key)
         | 
| 62 | 
            +
                  return nil if foreign_key_value.nil?
         | 
| 44 63 |  | 
| 45 | 
            -
             | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 48 | 
            -
                  end
         | 
| 64 | 
            +
                  options.model_class
         | 
| 65 | 
            +
                         .where(options.primary_key => foreign_key_value)
         | 
| 66 | 
            +
                         .first
         | 
| 49 67 | 
             
                end
         | 
| 68 | 
            +
              end
         | 
| 50 69 |  | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 53 | 
            -
             | 
| 54 | 
            -
             | 
| 55 | 
            -
                  define_method(name) do
         | 
| 56 | 
            -
                    target_key_value = self.send(options.primary_key)
         | 
| 57 | 
            -
                    return nil if target_key_value.nil?
         | 
| 58 | 
            -
                    options.model_class
         | 
| 59 | 
            -
                           .where(options.foreign_key => target_key_value)
         | 
| 60 | 
            -
                           .to_a
         | 
| 61 | 
            -
                  end
         | 
| 62 | 
            -
                end
         | 
| 70 | 
            +
              def has_many(name, options = {})
         | 
| 71 | 
            +
                options = HasManyOptions.new(name, to_s, options)
         | 
| 72 | 
            +
                assoc_options[name] = options
         | 
| 63 73 |  | 
| 64 | 
            -
                 | 
| 65 | 
            -
                   | 
| 74 | 
            +
                define_method(name) do
         | 
| 75 | 
            +
                  target_key_value = send(options.primary_key)
         | 
| 76 | 
            +
                  return nil if target_key_value.nil?
         | 
| 77 | 
            +
                  options.model_class
         | 
| 78 | 
            +
                         .where(options.foreign_key => target_key_value)
         | 
| 79 | 
            +
                         .to_a
         | 
| 66 80 | 
             
                end
         | 
| 81 | 
            +
              end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
              def assoc_options
         | 
| 84 | 
            +
                @assoc_options ||= {}
         | 
| 85 | 
            +
              end
         | 
| 67 86 |  | 
| 68 | 
            -
             | 
| 69 | 
            -
             | 
| 87 | 
            +
              def has_one_through(name, through_name, source_name)
         | 
| 88 | 
            +
                through_options = assoc_options[through_name]
         | 
| 70 89 |  | 
| 71 | 
            -
             | 
| 72 | 
            -
             | 
| 73 | 
            -
             | 
| 74 | 
            -
             | 
| 75 | 
            -
             | 
| 90 | 
            +
                define_method(name) do
         | 
| 91 | 
            +
                  source_options =
         | 
| 92 | 
            +
                    through_options.model_class.assoc_options[source_name]
         | 
| 93 | 
            +
                  through_pk = through_options.primary_key
         | 
| 94 | 
            +
                  key_val = send(through_options.foreign_key)
         | 
| 76 95 |  | 
| 77 | 
            -
             | 
| 78 | 
            -
             | 
| 79 | 
            -
             | 
| 96 | 
            +
                  source_options.model_class
         | 
| 97 | 
            +
                                .includes(through_options.model_class)
         | 
| 98 | 
            +
                                .where(through_pk => key_val)
         | 
| 99 | 
            +
                                .first
         | 
| 80 100 | 
             
                end
         | 
| 101 | 
            +
              end
         | 
| 81 102 |  | 
| 82 | 
            -
             | 
| 83 | 
            -
             | 
| 84 | 
            -
             | 
| 85 | 
            -
             | 
| 86 | 
            -
             | 
| 87 | 
            -
             | 
| 88 | 
            -
             | 
| 89 | 
            -
             | 
| 90 | 
            -
             | 
| 91 | 
            -
             | 
| 92 | 
            -
             | 
| 93 | 
            -
             | 
| 94 | 
            -
             | 
| 95 | 
            -
             | 
| 96 | 
            -
                  end
         | 
| 103 | 
            +
              def has_many_through(name, through_name, source_name)
         | 
| 104 | 
            +
                through_options = assoc_options[through_name]
         | 
| 105 | 
            +
                define_method(name) do
         | 
| 106 | 
            +
                  through_fk = through_options.foreign_key
         | 
| 107 | 
            +
                  through_class = through_options.model_class
         | 
| 108 | 
            +
                  key_val = send(through_options.primary_key)
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                  # 2 queries, we could reduce to 1 by writing Puffs::SQLRelation.join.
         | 
| 111 | 
            +
                  through_class.where(through_fk => key_val)
         | 
| 112 | 
            +
                               .includes(source_name)
         | 
| 113 | 
            +
                               .load
         | 
| 114 | 
            +
                               .included_relations
         | 
| 115 | 
            +
                               .first
         | 
| 116 | 
            +
                               .to_a
         | 
| 97 117 | 
             
                end
         | 
| 98 118 | 
             
              end
         | 
| 99 119 | 
             
            end
         | 
| @@ -0,0 +1,32 @@ | |
| 1 | 
            +
            # Search methods for Puffs::SQLObject
         | 
| 2 | 
            +
            module Searchable
         | 
| 3 | 
            +
              RELATION_METHODS = [
         | 
| 4 | 
            +
                :limit, :includes, :where, :order
         | 
| 5 | 
            +
              ].freeze
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              RELATION_METHODS.each do |method|
         | 
| 8 | 
            +
                define_method(method) do |arg|
         | 
| 9 | 
            +
                  Puffs::SQLRelation.new(klass: self).send(method, arg)
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              def all
         | 
| 14 | 
            +
                where({})
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              def count
         | 
| 18 | 
            +
                all.count
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              def find(id)
         | 
| 22 | 
            +
                where(id: id).first
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              def first
         | 
| 26 | 
            +
                all.limit(1).first
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              def last
         | 
| 30 | 
            +
                all.order(id: :desc).limit(1).first
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
            end
         | 
| @@ -1,48 +1,30 @@ | |
| 1 | 
            +
            require 'active_support/inflector'
         | 
| 1 2 | 
             
            require_relative '../../lib/db_connection'
         | 
| 2 3 | 
             
            require_relative 'associatable'
         | 
| 3 4 | 
             
            require_relative '../relation'
         | 
| 4 | 
            -
             | 
| 5 | 
            -
            # require_relative '../puffs'
         | 
| 5 | 
            +
            require_relative 'searchable'
         | 
| 6 6 |  | 
| 7 7 | 
             
            module Puffs
         | 
| 8 | 
            +
              # Base Model class for Puffs Orm.
         | 
| 8 9 | 
             
              class SQLObject
         | 
| 9 10 | 
             
                extend Associatable
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                RELATION_METHODS = [
         | 
| 12 | 
            -
                  :limit, :includes, :where, :order
         | 
| 13 | 
            -
                ]
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                RELATION_METHODS.each do |method|
         | 
| 16 | 
            -
                  define_singleton_method(method) do |arg|
         | 
| 17 | 
            -
                    Puffs::SQLRelation.new(klass: self).send(method, arg)
         | 
| 18 | 
            -
                  end
         | 
| 19 | 
            -
                end
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                def self.all
         | 
| 22 | 
            -
                  where({})
         | 
| 23 | 
            -
                end
         | 
| 11 | 
            +
                extend Searchable
         | 
| 24 12 |  | 
| 25 13 | 
             
                def self.columns
         | 
| 26 14 | 
             
                  Puffs::DBConnection.columns(table_name)
         | 
| 27 15 | 
             
                end
         | 
| 28 16 |  | 
| 29 | 
            -
                def self.count
         | 
| 30 | 
            -
                  all.count
         | 
| 31 | 
            -
                end
         | 
| 32 | 
            -
             | 
| 33 17 | 
             
                def self.define_singleton_method_by_proc(obj, name, block)
         | 
| 34 18 | 
             
                  metaclass = class << obj; self; end
         | 
| 35 19 | 
             
                  metaclass.send(:define_method, name, block)
         | 
| 36 20 | 
             
                end
         | 
| 37 21 |  | 
| 38 22 | 
             
                def self.destroy_all!
         | 
| 39 | 
            -
                   | 
| 40 | 
            -
                    entry.destroy!
         | 
| 41 | 
            -
                  end
         | 
| 23 | 
            +
                  all.each(&:destroy!)
         | 
| 42 24 | 
             
                end
         | 
| 43 25 |  | 
| 44 26 | 
             
                def self.finalize!
         | 
| 45 | 
            -
                   | 
| 27 | 
            +
                  columns.each do |column|
         | 
| 46 28 | 
             
                    define_method(column) do
         | 
| 47 29 | 
             
                      attributes[column]
         | 
| 48 30 | 
             
                    end
         | 
| @@ -53,26 +35,14 @@ module Puffs | |
| 53 35 | 
             
                  end
         | 
| 54 36 | 
             
                end
         | 
| 55 37 |  | 
| 56 | 
            -
                def self.find(id)
         | 
| 57 | 
            -
                  where(id: id).first
         | 
| 58 | 
            -
                end
         | 
| 59 | 
            -
             | 
| 60 | 
            -
                def self.first
         | 
| 61 | 
            -
                  all.limit(1).first
         | 
| 62 | 
            -
                end
         | 
| 63 | 
            -
             | 
| 64 38 | 
             
                def self.has_association?(association)
         | 
| 65 39 | 
             
                  assoc_options.keys.include?(association)
         | 
| 66 40 | 
             
                end
         | 
| 67 41 |  | 
| 68 | 
            -
                def self.last
         | 
| 69 | 
            -
                  all.order(id: :desc).limit(1).first
         | 
| 70 | 
            -
                end
         | 
| 71 | 
            -
             | 
| 72 42 | 
             
                def self.parse_all(results)
         | 
| 73 43 | 
             
                  relation = Puffs::SQLRelation.new(klass: self, loaded: true)
         | 
| 74 44 | 
             
                  results.each do |result|
         | 
| 75 | 
            -
                    relation <<  | 
| 45 | 
            +
                    relation << new(result)
         | 
| 76 46 | 
             
                  end
         | 
| 77 47 |  | 
| 78 48 | 
             
                  relation
         | 
| @@ -83,7 +53,7 @@ module Puffs | |
| 83 53 | 
             
                end
         | 
| 84 54 |  | 
| 85 55 | 
             
                def self.table_name
         | 
| 86 | 
            -
                  @table_name ||=  | 
| 56 | 
            +
                  @table_name ||= to_s.downcase.tableize
         | 
| 87 57 | 
             
                end
         | 
| 88 58 |  | 
| 89 59 | 
             
                def initialize(params = {})
         | 
| @@ -92,7 +62,7 @@ module Puffs | |
| 92 62 | 
             
                      raise "unknown attribute '#{attr_name}'"
         | 
| 93 63 | 
             
                    end
         | 
| 94 64 |  | 
| 95 | 
            -
                     | 
| 65 | 
            +
                    send("#{attr_name}=", value)
         | 
| 96 66 | 
             
                  end
         | 
| 97 67 | 
             
                end
         | 
| 98 68 |  | 
| @@ -102,7 +72,7 @@ module Puffs | |
| 102 72 |  | 
| 103 73 | 
             
                def attribute_values
         | 
| 104 74 | 
             
                  self.class.columns.map do |column|
         | 
| 105 | 
            -
                     | 
| 75 | 
            +
                    send(column)
         | 
| 106 76 | 
             
                  end
         | 
| 107 77 | 
             
                end
         | 
| 108 78 |  | 
| @@ -121,9 +91,9 @@ module Puffs | |
| 121 91 |  | 
| 122 92 | 
             
                def insert
         | 
| 123 93 | 
             
                  columns = self.class.columns.reject { |col| col == :id }
         | 
| 124 | 
            -
                  column_values = columns.map {|attr_name| send(attr_name)}
         | 
| 125 | 
            -
                  column_names = columns.join( | 
| 126 | 
            -
                  bind_params = (1..columns.length).map {|n| "$#{n}"}.join( | 
| 94 | 
            +
                  column_values = columns.map { |attr_name| send(attr_name) }
         | 
| 95 | 
            +
                  column_names = columns.join(', ')
         | 
| 96 | 
            +
                  bind_params = (1..columns.length).map { |n| "$#{n}" }.join(', ')
         | 
| 127 97 | 
             
                  result = Puffs::DBConnection.execute(<<-SQL, column_values)
         | 
| 128 98 | 
             
                    INSERT INTO
         | 
| 129 99 | 
             
                      #{self.class.table_name} (#{column_names})
         | 
| @@ -141,8 +111,8 @@ module Puffs | |
| 141 111 |  | 
| 142 112 | 
             
                def update
         | 
| 143 113 | 
             
                  set_line = self.class.columns.map do |column|
         | 
| 144 | 
            -
                    "#{column} = \'#{ | 
| 145 | 
            -
                  end.join( | 
| 114 | 
            +
                    "#{column} = \'#{send(column)}\'"
         | 
| 115 | 
            +
                  end.join(', ')
         | 
| 146 116 |  | 
| 147 117 | 
             
                  Puffs::DBConnection.execute(<<-SQL)
         | 
| 148 118 | 
             
                    UPDATE
         | 
    
        data/puffs.gemspec
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: puffs
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.2. | 
| 4 | 
            +
              version: 0.2.06
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Zachary Moroni
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2016-03- | 
| 11 | 
            +
            date: 2016-03-28 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: thor
         | 
| @@ -186,6 +186,7 @@ files: | |
| 186 186 | 
             
            - lib/server_connection.rb
         | 
| 187 187 | 
             
            - lib/session.rb
         | 
| 188 188 | 
             
            - lib/sql_object/associatable.rb
         | 
| 189 | 
            +
            - lib/sql_object/searchable.rb
         | 
| 189 190 | 
             
            - lib/sql_object/sql_object.rb
         | 
| 190 191 | 
             
            - puffs.gemspec
         | 
| 191 192 | 
             
            - readme.md
         |