anykeyh / clear

Advanced ORM between postgreSQL and Crystal
https://github.com/anykeyh/clear
MIT License
269 stars 34 forks source link

Incompatible with pg v.0.24.0 #221

Open dukeraphaelng opened 3 years ago

dukeraphaelng commented 3 years ago

Clear fails with pg v.0.24.0, probably due to the changes introduced in https://github.com/will/crystal-pg/commit/387ec63030b91b95257dd52f166ac00f623d7d54

Please note that pg version 0.23.2 runs fine.

This is log for crystal spec --error-trace

error in line 1
Error: while requiring "./spec/cli/cli_spec.cr"

In spec/cli/cli_spec.cr:1:1

 1 | require "../spec_helper"
     ^
Error: while requiring "../spec_helper"

In spec/spec_helper.cr:3:1

 3 | require "../src/clear"
     ^
Error: while requiring "../src/clear"

In src/clear.cr:19:1

 19 | require "./clear/core"
      ^
Error: while requiring "./clear/core"

In src/clear/core.cr:12:1

 12 | require "./model/**"
      ^
Error: while requiring "./model/**"

In src/clear/model/model.cr:94:1

 94 | require "./reflection/**"
      ^
Error: while requiring "./reflection/**"

In src/clear/model/reflection/column.cr:4:3

 4 | include Clear::Model
     ^
Error: expanding macro

There was a problem expanding macro 'included'

Called macro defined in macro 'included'

 1 | macro included

Which expanded to:

 >  1 |       @@initialized = false
 >  2 | 
 >  3 |       # :nodoc:
 >  4 |       macro __on_init__
 >  5 |         class ::{{@type}}
 >  6 |           def self.__main_init__
 >  7 |             previous_def
 >  8 |             {{yield}}
 >  9 |           end
 > 10 | 
 > 11 |         end
 > 12 |       end
 > 13 | 
 > 14 |       # :nodoc:
 > 15 |       def self.__initialize_once__
 > 16 |         unless @@initialized
 > 17 |           __main_init__
 > 18 |           @@initialized = true
 > 19 |         end
 > 20 |       end
 > 21 | 
 > 22 |       __initialize_once__
 > 23 |     
Error: instantiating '__initialize_once__()'

In src/clear/model/reflection/column.cr:4:3

 4 | include Clear::Model
     ^
Error: expanding macro

There was a problem expanding macro 'included'

Called macro defined in macro 'included'

 1 | macro included

Which expanded to:

 >  1 |       @@initialized = false
 >  2 | 
 >  3 |       # :nodoc:
 >  4 |       macro __on_init__
 >  5 |         class ::{{@type}}
 >  6 |           def self.__main_init__
 >  7 |             previous_def
 >  8 |             {{yield}}
 >  9 |           end
 > 10 | 
 > 11 |         end
 > 12 |       end
 > 13 | 
 > 14 |       # :nodoc:
 > 15 |       def self.__initialize_once__
 > 16 |         unless @@initialized
 > 17 |           __main_init__
 > 18 |           @@initialized = true
 > 19 |         end
 > 20 |       end
 > 21 | 
 > 22 |       __initialize_once__
 > 23 |     
Error: instantiating '__main_init__()'

There was a problem expanding macro 'generate'

Called macro defined in src/clear/model/modules/relations/belongs_to_macro.cr:3:3

 3 | macro generate(self_type, relation)

Which expanded to:

 >   1 |     
 >   2 |       
 >   3 | 
 >   4 |       __define_association_cache__(table, Clear::Reflection::Table)
 >   5 | 
 >   6 |       column table_name : String?, primary: false, presence: false, mass_assign: true
 >   7 | 
 >   8 |       # :nodoc:
 >   9 |       def self.__relation_filter_table__(query)
 >  10 |         query.inner_join(Clear::Reflection::Column.table){ var( Clear::Reflection::Column.table, "table_name" ) == var( Clear::Reflection::Table.table, Clear::Reflection::Table.__pkey__ ) }
 >  11 |       end
 >  12 | 
 >  13 |       # :nodoc:
 >  14 |       def self.__relation_key_table_table__ : Tuple(String, String)
 >  15 |         {
 >  16 |           Clear::Reflection::Table.table.to_s,
 >  17 |           Clear::Reflection::Table.__pkey__.to_s
 >  18 |         }
 >  19 |       end
 >  20 | 
 >  21 |       __on_init__ do
 >  22 |         Clear::Reflection::Column::RELATION_FILTERS["table"] = -> (x : Clear::SQL::SelectBuilder) { __relation_filter_table__(x) }
 >  23 |       end
 >  24 | 
 >  25 |       # The method table is a `belongs_to` relation
 >  26 |       #   to Clear::Reflection::Table
 >  27 |       def table : Clear::Reflection::Table?
 >  28 |         if cached = @_cached_table
 >  29 |           cached
 >  30 |         elsif @cache.try &.active? "table"
 >  31 |           cache = @cache.not_nil!
 >  32 | 
 >  33 |           model = @_cached_table = cache.hit("table",
 >  34 |             self.table_name_column.to_sql_value,
 >  35 |             Clear::Reflection::Table
 >  36 |           ).first?
 >  37 | 
 >  38 |           
 >  39 | 
 >  40 |           model
 >  41 |         else
 >  42 |           fkey = self.table_name_column.value(nil)
 >  43 | 
 >  44 |           
 >  45 |             return nil if fkey.nil?
 >  46 |           
 >  47 | 
 >  48 |           @_cached_table =
 >  49 |             Clear::Reflection::Table.query
 >  50 |               .where{ var(Clear::Reflection::Table.table, Clear::Reflection::Table.__pkey__) == fkey }
 >  51 |               .first
 >  52 |         end
 >  53 |       end
 >  54 | 
 >  55 |       
 >  56 |         def table! : Clear::Reflection::Table
 >  57 |           model = self.table
 >  58 |           raise Clear::SQL::RecordNotFoundError.new if model.nil?
 >  59 |           model.not_nil!
 >  60 |         end # /  *!
 >  61 |       
 >  62 | 
 >  63 |       def table=(model : Clear::Reflection::Table?)
 >  64 |         if model && model.try &.persisted?
 >  65 |           raise "`#{model.__pkey_column__.name}` must be fetchable when assigning to a `belongs_to` relation." unless model.__pkey_column__.defined?
 >  66 |           @table_name_column.value = model.__pkey__
 >  67 |         else
 >  68 |           
 >  69 |             @_cached_table = nil
 >  70 |             @table_name_column.value = nil
 >  71 |           
 >  72 |         end
 >  73 | 
 >  74 |         @_cached_table = model
 >  75 |       end
 >  76 | 
 >  77 |       # :nodoc:
 >  78 |       # save the belongs_to model first if needed
 >  79 |       def _bt_save_table
 >  80 |         c = @_cached_table
 >  81 | 
 >  82 |         
 >  83 | 
 >  84 |         return if c.nil?
 >  85 | 
 >  86 |         unless c.persisted?
 >  87 |           if c.save
 >  88 |             @table_name_column.reset_convert(c.__pkey__)
 >  89 |           else
 >  90 |             add_error("table", c.print_errors)
 >  91 |           end
 >  92 |         else # relation model has been persisted after assigned to current model
 >  93 |           self.table_name = c.__pkey__
 >  94 |         end
 >  95 | 
 >  96 |       end # / _bt_save_*
 >  97 | 
 >  98 |       __on_init__ do
 >  99 |         Clear::Reflection::Column.before(:validate) do |mdl|
 > 100 |           mdl.as(self)._bt_save_table
 > 101 |         end
 > 102 |       end
 > 103 | 
 > 104 |       class Collection
 > 105 |         def with_table(fetch_columns = false, &block : Clear::Reflection::Table::Collection -> ) : self
 > 106 |           before_query do
 > 107 |             sub_query = self.dup.clear_select.select("#{ item_class.table }.table_name")
 > 108 | 
 > 109 |             cached_qry = Clear::Reflection::Table.query.where{ var(Clear::Reflection::Table.table, Clear::Reflection::Table.__pkey__ ).in?(sub_query) }
 > 110 | 
 > 111 |             block.call(cached_qry)
 > 112 | 
 > 113 |             cache_name = "table"
 > 114 |             @cache.active cache_name
 > 115 | 
 > 116 |             cached_qry.each(fetch_columns: fetch_columns) do |mdl|
 > 117 |               @cache.set(cache_name, mdl.__pkey__, [mdl])
 > 118 |             end
 > 119 |           end
 > 120 | 
 > 121 |           self
 > 122 |         end # / with_*
 > 123 | 
 > 124 |         def with_table(fetch_columns = false) : self
 > 125 |           with_table(fetch_columns){}
 > 126 |           self
 > 127 |         end # / with_*
 > 128 | 
 > 129 |       end # / Collection
 > 130 |      # / begin block
 > 131 |   
Error: expanding macro

There was a problem expanding macro '__on_init__'

Called macro defined in macro 'included'

 4 | macro __on_init__

Which expanded to:

 >  1 |         class ::Clear::Reflection::Column
 >  2 |           def self.__main_init__
 >  3 |             previous_def
 >  4 |             begin Clear::Reflection::Column.before(:validate) do |mdl|
 >  5 |   (mdl.as(self))._bt_save_table
 >  6 | end end
 >  7 |           end
 >  8 | 
 >  9 |         end
 > 10 |       
Error: instantiating 'Clear::Reflection::Column#_bt_save_table()'

There was a problem expanding macro '__generate_relations__'

Called macro defined in src/clear/model/modules/has_relations.cr:224:3

 224 | macro __generate_relations__

Which expanded to:

 > 1 |     
 > 2 |       
 > 3 |         
 > 4 |           Relations::BelongsToMacro.generate(Clear::Reflection::Column, {name: "table", type: Clear::Reflection::Table, relation_type: :belongs_to, nilable: true, foreign_key: "table_name", foreign_key_type: "String", polymorphic: false, polymorphic_type_column: nil, primary: false, presence: true, through: nil, cache: true, mass_assign: true})
 > 5 |         
 > 6 |       
 > 7 |     
 > 8 |   
Error: expanding macro

There was a problem expanding macro 'generate'

Called macro defined in src/clear/model/modules/relations/belongs_to_macro.cr:3:3

 3 | macro generate(self_type, relation)

Which expanded to:

 >   1 |     
 >   2 |       
 >   3 | 
 >   4 |       __define_association_cache__(table, Clear::Reflection::Table)
 >   5 | 
 >   6 |       column table_name : String?, primary: false, presence: false, mass_assign: true
 >   7 | 
 >   8 |       # :nodoc:
 >   9 |       def self.__relation_filter_table__(query)
 >  10 |         query.inner_join(Clear::Reflection::Column.table){ var( Clear::Reflection::Column.table, "table_name" ) == var( Clear::Reflection::Table.table, Clear::Reflection::Table.__pkey__ ) }
 >  11 |       end
 >  12 | 
 >  13 |       # :nodoc:
 >  14 |       def self.__relation_key_table_table__ : Tuple(String, String)
 >  15 |         {
 >  16 |           Clear::Reflection::Table.table.to_s,
 >  17 |           Clear::Reflection::Table.__pkey__.to_s
 >  18 |         }
 >  19 |       end
 >  20 | 
 >  21 |       __on_init__ do
 >  22 |         Clear::Reflection::Column::RELATION_FILTERS["table"] = -> (x : Clear::SQL::SelectBuilder) { __relation_filter_table__(x) }
 >  23 |       end
 >  24 | 
 >  25 |       # The method table is a `belongs_to` relation
 >  26 |       #   to Clear::Reflection::Table
 >  27 |       def table : Clear::Reflection::Table?
 >  28 |         if cached = @_cached_table
 >  29 |           cached
 >  30 |         elsif @cache.try &.active? "table"
 >  31 |           cache = @cache.not_nil!
 >  32 | 
 >  33 |           model = @_cached_table = cache.hit("table",
 >  34 |             self.table_name_column.to_sql_value,
 >  35 |             Clear::Reflection::Table
 >  36 |           ).first?
 >  37 | 
 >  38 |           
 >  39 | 
 >  40 |           model
 >  41 |         else
 >  42 |           fkey = self.table_name_column.value(nil)
 >  43 | 
 >  44 |           
 >  45 |             return nil if fkey.nil?
 >  46 |           
 >  47 | 
 >  48 |           @_cached_table =
 >  49 |             Clear::Reflection::Table.query
 >  50 |               .where{ var(Clear::Reflection::Table.table, Clear::Reflection::Table.__pkey__) == fkey }
 >  51 |               .first
 >  52 |         end
 >  53 |       end
 >  54 | 
 >  55 |       
 >  56 |         def table! : Clear::Reflection::Table
 >  57 |           model = self.table
 >  58 |           raise Clear::SQL::RecordNotFoundError.new if model.nil?
 >  59 |           model.not_nil!
 >  60 |         end # /  *!
 >  61 |       
 >  62 | 
 >  63 |       def table=(model : Clear::Reflection::Table?)
 >  64 |         if model && model.try &.persisted?
 >  65 |           raise "`#{model.__pkey_column__.name}` must be fetchable when assigning to a `belongs_to` relation." unless model.__pkey_column__.defined?
 >  66 |           @table_name_column.value = model.__pkey__
 >  67 |         else
 >  68 |           
 >  69 |             @_cached_table = nil
 >  70 |             @table_name_column.value = nil
 >  71 |           
 >  72 |         end
 >  73 | 
 >  74 |         @_cached_table = model
 >  75 |       end
 >  76 | 
 >  77 |       # :nodoc:
 >  78 |       # save the belongs_to model first if needed
 >  79 |       def _bt_save_table
 >  80 |         c = @_cached_table
 >  81 | 
 >  82 |         
 >  83 | 
 >  84 |         return if c.nil?
 >  85 | 
 >  86 |         unless c.persisted?
 >  87 |           if c.save
 >  88 |             @table_name_column.reset_convert(c.__pkey__)
 >  89 |           else
 >  90 |             add_error("table", c.print_errors)
 >  91 |           end
 >  92 |         else # relation model has been persisted after assigned to current model
 >  93 |           self.table_name = c.__pkey__
 >  94 |         end
 >  95 | 
 >  96 |       end # / _bt_save_*
 >  97 | 
 >  98 |       __on_init__ do
 >  99 |         Clear::Reflection::Column.before(:validate) do |mdl|
 > 100 |           mdl.as(self)._bt_save_table
 > 101 |         end
 > 102 |       end
 > 103 | 
 > 104 |       class Collection
 > 105 |         def with_table(fetch_columns = false, &block : Clear::Reflection::Table::Collection -> ) : self
 > 106 |           before_query do
 > 107 |             sub_query = self.dup.clear_select.select("#{ item_class.table }.table_name")
 > 108 | 
 > 109 |             cached_qry = Clear::Reflection::Table.query.where{ var(Clear::Reflection::Table.table, Clear::Reflection::Table.__pkey__ ).in?(sub_query) }
 > 110 | 
 > 111 |             block.call(cached_qry)
 > 112 | 
 > 113 |             cache_name = "table"
 > 114 |             @cache.active cache_name
 > 115 | 
 > 116 |             cached_qry.each(fetch_columns: fetch_columns) do |mdl|
 > 117 |               @cache.set(cache_name, mdl.__pkey__, [mdl])
 > 118 |             end
 > 119 |           end
 > 120 | 
 > 121 |           self
 > 122 |         end # / with_*
 > 123 | 
 > 124 |         def with_table(fetch_columns = false) : self
 > 125 |           with_table(fetch_columns){}
 > 126 |           self
 > 127 |         end # / with_*
 > 128 | 
 > 129 |       end # / Collection
 > 130 |      # / begin block
 > 131 |   
Error: instantiating 'Clear::Reflection::Table#save()'

In src/clear/model/modules/has_saving.cr:96:5

 96 | with_triggers(:save) do
      ^------------
Error: instantiating 'with_triggers(Symbol)'

In src/clear/model/modules/has_hooks.cr:16:16

 16 | Clear::SQL.transaction do |cnx|
                 ^----------
Error: instantiating 'Clear::SQL:Module#transaction()'

In src/clear/sql/transaction.cr:47:32

 47 | Clear::SQL::ConnectionPool.with_connection(connection) do |cnx|
                                 ^--------------
Error: instantiating 'Clear::SQL::ConnectionPool.class#with_connection(String)'

In src/clear/sql/transaction.cr:47:32

 47 | Clear::SQL::ConnectionPool.with_connection(connection) do |cnx|
                                 ^--------------
Error: instantiating 'Clear::SQL::ConnectionPool.class#with_connection(String)'

In src/clear/model/modules/has_hooks.cr:16:16

 16 | Clear::SQL.transaction do |cnx|
                 ^----------
Error: instantiating 'Clear::SQL:Module#transaction()'

In src/clear/model/modules/has_saving.cr:96:5

 96 | with_triggers(:save) do
      ^------------
Error: instantiating 'with_triggers(Symbol)'

In src/clear/model/modules/has_saving.cr:107:11

 107 | with_triggers(:create) do
       ^------------
Error: instantiating 'with_triggers(Symbol)'

In src/clear/model/modules/has_hooks.cr:16:16

 16 | Clear::SQL.transaction do |cnx|
                 ^----------
Error: instantiating 'Clear::SQL:Module#transaction()'

In src/clear/sql/transaction.cr:47:32

 47 | Clear::SQL::ConnectionPool.with_connection(connection) do |cnx|
                                 ^--------------
Error: instantiating 'Clear::SQL::ConnectionPool.class#with_connection(String)'

In src/clear/sql/transaction.cr:47:32

 47 | Clear::SQL::ConnectionPool.with_connection(connection) do |cnx|
                                 ^--------------
Error: instantiating 'Clear::SQL::ConnectionPool.class#with_connection(String)'

In src/clear/model/modules/has_hooks.cr:16:16

 16 | Clear::SQL.transaction do |cnx|
                 ^----------
Error: instantiating 'Clear::SQL:Module#transaction()'

In src/clear/model/modules/has_saving.cr:107:11

 107 | with_triggers(:create) do
       ^------------
Error: instantiating 'with_triggers(Symbol)'

In src/clear/model/modules/has_saving.cr:111:28

 111 | hash = query.execute(@@connection)
                    ^------
Error: instantiating 'Clear::SQL::InsertQuery#execute(String)'

In src/clear/sql/insert_query.cr:82:7

 82 | fetch(connection_name) { |x| o = x }
      ^----
Error: instantiating 'fetch(String)'

In src/clear/sql/insert_query.cr:46:32

 46 | Clear::SQL::ConnectionPool.with_connection(connection_name) do |cnx|
                                 ^--------------
Error: instantiating 'Clear::SQL::ConnectionPool.class#with_connection(String)'

In src/clear/sql/insert_query.cr:46:32

 46 | Clear::SQL::ConnectionPool.with_connection(connection_name) do |cnx|
                                 ^--------------
Error: instantiating 'Clear::SQL::ConnectionPool.class#with_connection(String)'

In src/clear/sql/insert_query.cr:50:7

 50 | fetch_result_set(h, rs) { |x| yield(x) }
      ^---------------
Error: instantiating 'fetch_result_set(Hash(String, Array(JSON::Any) | Array(PG::BoolArray) | Array(PG::CharArray) | Array(PG::Float32Array) | Array(PG::Float64Array) | Array(PG::Int16Array) | Array(PG::Int32Array) | Array(PG::Int64Array) | Array(PG::NumericArray) | Array(PG::StringArray) | Array(PG::TimeArray) | BigDecimal | Bool | Char | Clear::Expression::UnsafeSql | Float32 | Float64 | Hash(String, JSON::Any) | Int16 | Int32 | Int64 | Int8 | JSON::Any | PG::Geo::Box | PG::Geo::Circle | PG::Geo::Line | PG::Geo::LineSegment | PG::Geo::Path | PG::Geo::Point | PG::Geo::Polygon | PG::Interval | PG::Numeric | Slice(UInt8) | String | Time | UInt16 | UInt32 | UInt64 | UInt8 | UUID | Nil), PG::ResultSet)'

In src/clear/sql/insert_query.cr:59:5

 59 | loop do
      ^---
Error: instantiating 'loop()'

In src/clear/sql/insert_query.cr:59:5

 59 | loop do
      ^---
Error: instantiating 'loop()'

In src/clear/sql/insert_query.cr:60:10

 60 | rs.each_column do |col|
         ^----------
Error: instantiating 'PG::ResultSet#each_column()'

In src/clear/sql/insert_query.cr:60:10

 60 | rs.each_column do |col|
         ^----------
Error: instantiating 'PG::ResultSet#each_column()'

In src/clear/sql/insert_query.cr:61:10

 61 | h[col] = rs.read
       ^
Error: no overload matches 'Hash(String, Array(JSON::Any) | Array(PG::BoolArray) | Array(PG::CharArray) | Array(PG::Float32Array) | Array(PG::Float64Array) | Array(PG::Int16Array) | Array(PG::Int32Array) | Array(PG::Int64Array) | Array(PG::NumericArray) | Array(PG::StringArray) | Array(PG::TimeArray) | BigDecimal | Bool | Char | Clear::Expression::UnsafeSql | Float32 | Float64 | Hash(String, JSON::Any) | Int16 | Int32 | Int64 | Int8 | JSON::Any | PG::Geo::Box | PG::Geo::Circle | PG::Geo::Line | PG::Geo::LineSegment | PG::Geo::Path | PG::Geo::Point | PG::Geo::Polygon | PG::Interval | PG::Numeric | Slice(UInt8) | String | Time | UInt16 | UInt32 | UInt64 | UInt8 | UUID | Nil)#[]=' with types String, (Array(PG::BoolArray) | Array(PG::CharArray) | Array(PG::Float32Array) | Array(PG::Float64Array) | Array(PG::Int16Array) | Array(PG::Int32Array) | Array(PG::Int64Array) | Array(PG::NumericArray) | Array(PG::StringArray) | Array(PG::TimeArray) | Bool | Char | Float32 | Float64 | Int16 | Int32 | Int64 | JSON::PullParser | PG::Geo::Box | PG::Geo::Circle | PG::Geo::Line | PG::Geo::LineSegment | PG::Geo::Path | PG::Geo::Point | PG::Geo::Polygon | PG::Interval | PG::Numeric | Slice(UInt8) | String | Time | UInt32 | UUID | Nil)

Overloads are:
 - Hash(K, V)#[]=(key : K, value : V)
Couldn't find overloads for these types:
 - Hash(String, Array(JSON::Any) | Array(PG::BoolArray) | Array(PG::CharArray) | Array(PG::Float32Array) | Array(PG::Float64Array) | Array(PG::Int16Array) | Array(PG::Int32Array) | Array(PG::Int64Array) | Array(PG::NumericArray) | Array(PG::StringArray) | Array(PG::TimeArray) | BigDecimal | Bool | Char | Clear::Expression::UnsafeSql | Float32 | Float64 | Hash(String, JSON::Any) | Int16 | Int32 | Int64 | Int8 | JSON::Any | PG::Geo::Box | PG::Geo::Circle | PG::Geo::Line | PG::Geo::LineSegment | PG::Geo::Path | PG::Geo::Point | PG::Geo::Polygon | PG::Interval | PG::Numeric | Slice(UInt8) | String | Time | UInt16 | UInt32 | UInt64 | UInt8 | UUID | Nil)#[]=(key : String, value : JSON::PullParser)
 - 
sa-0001 commented 3 years ago

i don't think it's ideal to implicitly use the latest version of a dependency:

dependencies:
  pg:
    github: will/crystal-pg

@dukeraphaelng - in the latest versions of shards you can fix the issue by adding the following to shard.override.yml:

dependencies:
  pg:
    github: will/crystal-pg
    version: 0.23.2

(in older versions of shards, this won't work unfortunately; you'll need to git clone https://github.com/will/crystal-pg and checkout tag v0.23.2, and then add the local directory to both shard.yml and shard.override.yml - i learned this the hard way)