anykeyh / clear

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

Error with column_name database #123

Open remydev opened 5 years ago

remydev commented 5 years ago

Thank you for the reactivity. https://github.com/anykeyh/clear/issues/121 According to my tests, it doesn't work yet.

But the mistake must be different. In the example I'm testing

class Brand
        include Clear::Model
        primary_key  
        column name : String, column_name: "brand_name"
end

I have a correct table "name" in the database, but the return error is

You're trying to access to the column name but it is not initialized.

I was expecting a mistake with "brand_name" I have the same error with the right column name "brand_name" in the database

This code work for me (with "name" in the database):

class Brand
        include Clear::Model
        primary_key  
        column name : String #, column_name: "brand_name"
end

I hope this will help you

anykeyh commented 5 years ago

Hello,

I didn't went all the way with the fix as I had a though planning the last days. I'll make a proper test case and fix it during the week,

Thank you again for the feedback,

anykeyh commented 5 years ago

Hello,

I just made a spec and it passes without problem. Here is my test case based on your database schema:

require "../spec_helper"

module ModelDifferentColumnNameSpec
  class Brand
    include Clear::Model

    primary_key
    column name : String, column_name: "brand_name"
    self.table = "brands"
  end

  class ModelDifferentColumnNameSpecMigration8273
    include Clear::Migration

    def change(dir)
      create_table "brands" do |t|
        t.column "brand_name", "string"

        t.timestamps
      end
    end
  end

  def self.reinit
    reinit_migration_manager
    ModelDifferentColumnNameSpecMigration8273.new.apply(Clear::Migration::Direction::UP)
  end

  describe "Clear::Model" do
    context "Column definition" do
      it "can define properties in the model with a name different of the column name in PG" do
        # Here the column "name" is linked to "brand_name" in postgreSQL
        temporary do
          reinit

          Brand.create! name: "Nike"
          Brand.query.first!.name.should eq "Nike"
          Brand.query.where(brand_name: "Nike").count.should eq 1
        end
      end
    end
  end

end

I'm confused since this work properly.

remydev commented 5 years ago

I found something

This code works without <""> with brand_name

class Brand
    include Clear::Model
    primary_key
    column name : String, column_name: brand_name
    brand= Brand.query
end

pp Brand.create! name: "Nike"
pp Brand.query.first!.name
pp Brand.query.where(brand_name: "Nike")

p = Brand.query.find({id: 1}).try &.name # Return Product?

pp p
#<Brand:0x55790e67f540
 @attributes={},
 @cache=nil,
 @errors=[],
 @id_column=3,
 @name_column="Nike",
 @persisted=true>
"Décathlon"
#<Brand::Collection:0x55790e670c00
 @add_operation=nil,
 @before_query_triggers=[],
 @cache=
  #<Clear::Model::QueryCache:0x55790e669000
   @cache={},
   @cache_activation=Set{}>,
 @cached_result=nil,
 @columns=[],
 @connection_name="default",
 @cte={},
 @distinct_value=nil,
 @froms=[Clear::SQL::From(@value="\"brands\"", @var=nil)],
 @group_bys=[],
 @havings=[],
 @joins=[],
 @limit=nil,
 @lock=nil,
 @offset=nil,
 @order_bys=[],
 @polymorphic=false,
 @polymorphic_key=nil,
 @polymorphic_scope=nil,
 @tags={},
 @total_entries=nil,
 @unlink_operation=nil,
 @wheres=
  [#<Clear::Expression::Node::DoubleOperator:0x55790e6b5a50
    @a=
     #<Clear::Expression::Node::Variable:0x55790e669380
      @name="brand_name",
      @parent=nil>,
    @b=#<Clear::Expression::Node::Literal:0x55790e6b5a80 @value="Nike">,
    @op="=">],
 @windows=[]>
"Décathlon"

Also this fail

class Brand
    include Clear::Model
    primary_key  
    column name : String, column_name: "brand_name"
    brand= Brand.query
end

pp Brand.create! name: "Nike"
pp Brand.query.first!.name
pp Brand.query.where(brand_name: "Nike")

p = Brand.query.find({id: 1}).try &.name # Return Product?

pp p
remy-pc/remy ~/dev_env/remyaltideal/test > ./bin/altideal
Unhandled exception: the column « "brand_name" » of the relationship « brands » does not exist
Error caught, last query was:
INSERT INTO "brands" ("""brand_name""") VALUES ('Nike') RETURNING * (Clear::SQL::Error)
  from lib/clear/src/clear/sql/insert_query.cr:62:5 in 'execute'
  from lib/clear/src/clear/model/modules/has_saving.cr:112:20 in 'save'
  from lib/clear/src/clear/model/modules/has_saving.cr:137:55 in 'save!'
  from src/orm/Brand.cr:2:2 in 'create!:name'
  from src/orm/Brand.cr:11:1 in '__crystal_main'
  from /usr/lib/crystal/crystal/main.cr:97:5 in 'main_user_code'
  from /usr/lib/crystal/crystal/main.cr:86:7 in 'main'
  from /usr/lib/crystal/crystal/main.cr:106:3 in 'main'
  from __libc_start_main
  from _start
  from ???
Caused by: la colonne « "brand_name" » de la relation « brands » n'existe pas (PQ::PQError)
  from lib/pg/src/pq/connection.cr:204:7 in 'handle_error'
  from lib/pg/src/pq/connection.cr:0:9 in 'handle_async_frames'
  from lib/pg/src/pq/connection.cr:163:7 in 'read'
  from lib/pg/src/pq/connection.cr:158:7 in 'read'
  from lib/pg/src/pq/connection.cr:314:31 in 'expect_frame'
  from lib/pg/src/pq/connection.cr:313:5 in 'expect_frame'
  from lib/pg/src/pg/statement.cr:18:5 in 'perform_query'
  from lib/db/src/db/statement.cr:103:14 in 'perform_query_with_rescue'
  from lib/db/src/db/statement.cr:83:7 in 'query'
  from lib/db/src/db/pool_statement.cr:29:30 in 'query'
  from lib/db/src/db/query_methods.cr:38:7 in 'query'
  from lib/clear/src/clear/sql/insert_query.cr:53:12 in 'execute'
  from lib/clear/src/clear/model/modules/has_saving.cr:112:20 in 'save'
  from lib/clear/src/clear/model/modules/has_saving.cr:137:55 in 'save!'
  from src/orm/Brand.cr:2:2 in 'create!:name'
  from src/orm/Brand.cr:11:1 in '__crystal_main'
  from /usr/lib/crystal/crystal/main.cr:97:5 in 'main_user_code'
  from /usr/lib/crystal/crystal/main.cr:86:7 in 'main'
  from /usr/lib/crystal/crystal/main.cr:106:3 in 'main'
  from __libc_start_main
  from _start

This <"> are very strange INSERT INTO "brands" ("""brand_name""") VALUES ('Nike') RETURNING * (Clear::SQL::Error)

anykeyh commented 4 years ago

This is a problem with the macro system. I should cast string literal it to id type when building the code. I'll fix it asap.