require "uuid" module Clear::Model::HasSerialPkey PKEY_TYPE = {} of Nil => Nil # Macro used to define serializable primary keys. # Currently support `bigserial`, `serial` and `uuid`. # # For `bigserial` and `serial`, let to PostgreSQL the handling of sequence numbers. # For `uuid`, will generate a new `UUID` number on creation. macro primary_key(name = "id", type = :bigserial) {% # Transform symbols to string name = "#{name.id}" type = "#{type.id}" %} {% cb = PKEY_TYPE[type] %} {% if cb %} {{cb.gsub(/__name__/, name).id}} {% else %} {% raise "Cannot define primary key of type #{type}. Candidates are: #{PKEY_TYPE.keys.join(", ")}" %} {% end %} end # Add a hook for the `primary_key` # In the hook, __name__ will be replaced by the column name required by calling primary_key # # ## Example # # ``` # Clear::Model::HasSerialPkey.add_pkey_type("awesomepkey") do # column __name__ : AwesomePkey, primary: true, presence: false # # before_validate do # # ... # end # end # ``` # # Your new primary key system can then be called using `primary_key` method: # # ``` # primary_key :id, :awesomepkey # ``` # macro add_pkey_type(type, &block) {% PKEY_TYPE[type] = "#{block.body}" %} end add_pkey_type "bigserial" do column __name__ : Int64, primary: true, presence: false end add_pkey_type "serial" do column __name__ : Int32, primary: true, presence: false end add_pkey_type "text" do column __name__ : String, primary: true, presence: true end add_pkey_type "int" do column __name__ : Int32, primary: true, presence: true end add_pkey_type "bigint" do column __name__ : Int64, primary: true, presence: true end end