All Versions
20
Latest Version
Avg Release Cycle
79 days
Latest Release
56 days ago

Changelog History
Page 1

  • v0.11.1 Changes

    August 24, 2021

    General

    • switch to the crimson-knight/i18n.cr ~> 0.4.1

    Migration

    • 🛠 fix TableBuilder::ChangeTable#drop_reference dropping column before reference
    • ➕ add TableBuilder::DropReference
  • v0.11.0 Changes

    July 20, 2021

    General

    • ➕ add crystal >= 1.0.0 support
    • 🛠 fix inconsistent method signatures in multiple places
    • ➕ add #to_json to the following structs: PG::Numeric, PG::Geo::Point, PG::Geo::Line, PG::Geo::Circle, PG::Geo::LineSegment, PG::Geo::Box, PG::Geo::Path, PG::Geo::Polygon, Char, Time::Span, Slice, UUID
    • ➕ add crystal-mysql: 0.13.0 support
    • ➕ add crystal-pg: 0.23.2 support

    QueryBuilder

    • ➕ add custom #to_json to serialize retrieved collection
    • ➕ add #where accepting Hash(Symbol, _)
    • ➕ add Criteria#equal and Criteria#not_equal as original implementation of Criteria#== and Criteria#!=
    • ➕ add ExpressionBuilder #and, #or and #xor methods that accepts array of conditions

    Model

    • Authentication#password returns given unecrypted value
    • ➕ add Coercer module with static methods to localize all coercing logic for different types
    • ➕ add .coercer method to return object responding to all coercing methods described in Coercer
    • mapping generates .coerce_{{attribute}(value : String) methods for every field to coerce string value to attribute's type
    • mapping generates for every non-string attribute with a setter additional #{{attribute}}=(value : String) setter
    • 👍 allow all build methods (.new, .create and .update) to receive Hash(String, String) and coerce values to expected types
    • ➕ add .column_name to return all field names
    • 🛠 fix .field_names from returning child's properties for parent class
    • ➕ add custom #to_json
    • change converter interface to .from_db(DB::ResultSet, NamedTuple), .from_db(DB::ResultSet, NamedTuple) and .from_hash(Hash, String | Symbol, NamedTuple)
    • 🔄 change all existing converters to support new required interface
    • ➕ add BigDecimalConverter(T) converter
    • ➕ add Coercer.coerce(String, (BigDecimal?).class)
    • add time_zone_aware option for TimeZoneConverter to specify whether field should respect time zone converting logic
    • ➕ add support of date only and time only string formats for TimeZoneConverter
    • add time_format, date_time_format and date_format to customize time, date time and date formats respectively
    • 🛠 fix a bug where updated_at is not set in the generated sql query from model.save
    • NumericToFloat64Converter, BigDecimalConverter, TimeZoneConverter #from_hash accepts string as field value
    • BigDecimalConverter#from_hash accepts integer and float values as field value
    • 🛠 fix Errors#inspect bug using old UInt64#to_s signature
    • introduce Timestamp module that now includes with_timestamps macro
    • reworked how updated_at and created_at fields are set before save - now they are set explicitly without utilizing callbacks
    • ➕ add Resource.where accepting Hash(Symbol, _)

    Validation

    • 🔄 change Validator#validate abstract interface to #validate(record, **opts)
    • ⚡️ update all built-in validators to reflect new Validator interface
    • make Validator.with_blank_validation macro to accept arguments to reference record, field name, value and blank value acceptance

    Relation

    • remove abstract #condition_clause & #condition_clause(a) declarations from IRelation

    View

    • ➕ add custom #to_json

    Adapter

    • ✂ remove abstract #update declaration from Base
    • BaseSQLGenerator#parse_query converts Time arguments to UTC only if Config.time_zone_aware_attributes set to true
    • Mysql#read_column calls super if column isn't a tiny int
    • ResultParser#read_column convert time to Config.local_time_zone if Config.time_zone_aware_attributes set to true or just change time zone to it otherwise

    Config

    • .reset_config creates new instance instead of executing #initialize on existing object
    • add Config.time_zone_aware_attributes to specify whether time zone converting logic should be globally disabled

    Migration

    • ➕ add precision and scale options support for decimal data type

    Record

    • ➕ add custom #to_json
    • ➕ add custom #inspect
  • v0.10.0 Changes

    December 11, 2020

    🔄 Changes

    General

    • ➕ add crystal 0.35.0 support and drop 0.34.0 support

    QueryBuilder

    • 👍 allow arbitrary Query instances as nested queries for CTEs
    • 🛠 fix failed nil assertion when eager load relations sequence with missing intermediate relation records
    • ➕ add IModelQuery#find(id) to retrieve record by primary key
    • ➕ add IModelQuery#find!(id) to retrieve record by primary key or raise Jennifer::RecordNotFound exception
    • ModelQuery(T)#to_a and ModelQuery(T)#find_by_sql ensure T has loaded actual table field count before making a request

    Model

    • 🔄 change model constructor hash argument type from Hash(String, Jennifer::DBany) to Hash(String, AttrType) (same for Symbol keys)
    • CommonMapping#attribute uses attribute getter
    • 👻 CommonMapping#attribute raises Jennifer::UnknownAttribute exception if model has no requested attribute and raise_exception = true
    • add CommonMapping#attribute_before_typecast which returns given attribute in database format using attribute converter
    • add Mapping#{{attribute}}_will_change! to mark {{attribute}} as changed one
    • #primary uses getter
    • any Mapping.mapping invocation creates AttrType alias to represent union of Jennifer::DBAny and any arbitrary type from fields definition
    • ⚡️ change Mapping#update_columns argument type to Hash(String | Symbol, AttrType)
    • ⚡️ Mapping#update_columns raises Jennifer::UnknownAttribute if key-value pairs include unknown attribute
    • Mapping#set_attribute to accept AttrType
    • 👻 Mapping#set_attribute raises Jennifer::UnknownAttribute exception if model has no requested attribute
    • ⚡️ Mapping#update_columns raises Jennifer::UnknownAttribute if key-value pairs include unknown field
    • Mapping#arguments_to_insert and Mapping#arguments_to_save use #attribute_before_typecast to collect attributes to store in a database
    • #add_{{relation}} accepts AttrType as a hash value type
    • 📇 rename EnumConverter to PgEnumConverter
    • ➕ add EnumConverter(T) to convert string to crystal enum
    • add JSONSerializableConverter(T) to convert JSON field to objects of T that support .from_json and #to_json methods
    • add TimeZoneConverter to convert time attributes from UTC to Jennife::Config.local_time_zone

    Adapter

    • ➕ add DBFormater as a proposed default logger formatter
    • 📇 change logging - emit Log::Metadata with query, args and time keys (as new crystal-db does)
    • 🛠 fix missing reconnect to database on connection lost

    SqlGenerator

    • 🛠 fix a potential compilation issue that appears in certain edge cases for postgres adapter (#329)
      Adapter::BaseSQLGenerator now produces valid SQL when using multiple recursive CTEs (.with(..., true)) in a single query

    Migration

    • 📇 rename TableBuilder::DB_OPTIONS to TableBuilder::DbOptions

    Exceptions

    • ➕ add Jennifer::UnknownAttribute to represent case when unknown attribute is tried to be read/written
  • v0.9.0 Changes

    May 24, 2020

    🔄 Changelog

    General

    • ➕ add Crystal 0.34.0 support
    • add Jennifer::Presentable with abstract methods declarations (#attribute, #errors, #human_attribute_name, #attribute_metadata, #class_name)

    QueryBuilder

    • Query#initialize now accept Adapter::Base as a second (optional) argument
    • OrderItem is renamed to OrderExpression to avoid possible name collisions

    Model

    • fix an issue with rendering new_record and destroyed system variables by #to_json
    • 0️⃣ Resource.table_prefix now returns underscored namespace name (if any) by default
    • Base includes Jennifer::Presentable
    • ➕ add Translation#class_name method to return underscored class name
    • ➕ add Mapping#attribute_metadata to return attribute metadata by it's name
    • remove Base::primary_field_type
    • Prevent compile time error with models named Model or Record

    View

    • fix an issue with rendering new_record and destroyed system variables by #to_json
    • remove Base::primary_field_type

    Adapter

    • db connection is established on the first request no on adapter initialization
    • 👀 Adapter.adapter_class raises BaseException if no valid Config.adapter is specified
    • .command_interface, .create_database, .drop_database, .generate_schema, .load_schema, .db_connection, .connection_string, .database_exists? now are instance methods
    • Base#initialize now excepts Config instance
    • respect host in Jennifer::Postgres::CommandInterface#database_exists?
    • escape connection URI segments
    • 🌲 Config#logger now is Log instead of Logger
    • ➕ add read/write adapter segregation
    • 🗄 deprecate .adapter & .adapter_class
    • ✂ remove .query, .exec & .scalar

    Config

    • .reset_config invokes #initialize instead of creating new instance

    Migration

    • Base#schema_processor is no more public api
    • Runner.create and Runner.drop now accept option Adapter::Base instance
    • pass to_table in TableBuilder::DropForeignKey#process
    • 🛠 fix TableBuilder::CreateTable#reference - now it takes into account given SQL type for the foreign key column
    • add #add_reference, #drop_reference, #add_timestamps to TableBuilder::CHangeTable
    • TableBuilder::CHangeTable#drop_index also accepts single column name
    • ✂ remove deprecated TableBuilder::CreateTable#index overrides

    Record

    • 🚚 #initialize(DB::ResultSet) is removed
  • v0.8.4 Changes

    November 15, 2019

    🔄 Changes

    QueryBuilder

    • 👉 use adapter's #read_column in NestedRelationTree
    • ➕ add RelationTree#adapter
    • 🛠 fix Ordering#order(Hash(String | Symbol, String | Symbol))

    Adapter

    • 🛠 fix issue with treating tinyint mysql field as boolean
    • remove ResultParser#result_to_array
    • ➕ add Mysql#read_column
    • add Base.default_max_bind_vars_count which returns default maximum count of bind variables that can be used in Base#bulk_insert (default is 32766)
    • Mysql.default_max_bind_vars_count and Postgres.default_max_bind_vars_count returns 32766
    • 🔒 Base#bulk_insert doesn't do table lock no more
    • if variables that should be inserted by Base#bulk_insert exceed Base.max_bind_vars all of them are quoted and put into a query
    • ✂ remove BaseSQLGenerator::ARRAY_ESCAPE
    • move BaseSQLGenerator::ARGUMENT_ESCAPE_STRING to Quoting
    • move BaseSQLGenerator .quote, .escape_string, .filter_out to Quoting
    • ➕ add correct values quoting for postgres adapter
    • ➕ add correct values quoting for mysql adapter
    • ⏪ now logger writes BEGIN instead of TRANSACTION START, COMMIT instead of TRANSACTION COMMIT and ROLLBACK instead of TRANSACTION ROLLBACK on corresponding transaction commands
    • ✂ add SchemaProcessor::FkEventActions enum to validate on_delete and on_update action values; String | Symbol still should be used as an argument type everywhere

    Config

    • add max_bind_vars_count property to present maximum allowed count of bind variables to be used in bulk insert operation
    • add MigrationFailureHandler enum to validate migration_failure_handler_method value; Symbol | MigrationFailureHandler should be used as an argument for it
    • fix migration_failure_handler_method config - make it instance property
  • v0.8.3 Changes

    October 19, 2019

    🔄 Changes

    General

    • ➕ add crystal 0.31.1 compatibility
    • ➕ add [email protected] support
    • ✂ remove sam from mandatory dependencies

    Model

    • 🛠 fix bug with primary field presence assertion

    View

    • 🛠 fix bug with primary field presence assertion

    Adapter

    • ➕ add date SQL data type
    • date_time field type maps to timestamp SQL data type (postgres only)

    Migration

    • ➕ add Runner.pending_migration? to return whether there is pending (not invoked) migration
    • ➕ add Base.with_transaction method to disable automatic transaction wrapping around migration methods
    • ➕ add Base.with_transaction? to check whether migration is run under a transaction
    • ✂ remove var_string field type
    • ✂ remove blob field type for postgres
    • 🛠 fix wrong explanation message for TableBuilder::CreateIndex
    • ➕ add new TableBuilder::CreateTable#index signatures (old ones are deprecated):
      • #index(fields : Array(Symbol), type : Symbol | ::Nil = nil, name : String | ::Nil = nil, lengths : Hash(Symbol, Int32) = {} of Symbol => Int32, orders : Hash(Symbol, Symbol) = {} of Symbol => Symbol)
      • #index(field : Symbol, type : Symbol | ::Nil = nil, name : String | ::Nil = nil, length : Int32 | ::Nil = nil, order : Symbol | ::Nil = nil)
    • 0️⃣ make default varchar length 254 (mysql only)
    • ➕ add foreign key ON UPDATE and ON DELETE support
    • Base#add_foreign_key accepts on_delete and on_update keyword arguments to specify corresponding actions
    • TableBuilder::ChangeTable#add_foreign_key accepts on_delete and on_update keyword arguments to specify corresponding actions
    • TableBuilder::CreateTable#reference accepts on_delete and on_update options to specify corresponding actions
    • TableBuilder::CreateTable#foreign_key accepts on_delete and on_update keyword arguments to specify corresponding actions
  • v0.8.2 Changes

    September 11, 2019

    General

    • ⬆️ upgrade TechMagister/i18n.cr dependency to 0.3.1
  • v0.8.1 Changes

    September 04, 2019

    General

    • ➕ add crystal-pg 0.18.0 support
    • ➕ add ameba check to CI
    • 🛠 fix bug with not defined JSON

    Model

    • ➕ Add EnumConverter converter for Postgre ENUM field convert
    • (pg only) field presenting ENUM field should explicitly specify converter: Jennifer::Model::EnumConverter

    Adapter

    • Postgre adapter now doesn't register decoders for each ENUM type in #prepare

    Config

    • add allow_outdated_pending_migration configuration to specify whether outdated pending migration should be silently processed or error should be raised

    Migration

    • extend Jennifer::Migration::TableBuilder::Base::AllowedTypes alias with Int64 type.
  • v0.8.0 Changes

    June 11, 2019

    It has been a long time since previous release but expectation is worth it. 0.8.0 release brings a lot of new features such as:

    • extended model mapping
      • new properties to configure sql column name and autoincrementability of primary key
      • opportunity to define mapping in modules and abstract super classes
    • Model.new now respects after_initialize callbacks
    • unify mapping for model and view
    • extended querying functionality
      • make SQL API more natural
      • support of upsert operation
      • add CTE

    🐎 Also a lot of bugs were fixed and performance enhancements were made.

    📚 API documentation is hugely increased so now almost all places are covered.

    🔄 Changelog

    General

    • 0️⃣ by default db:migrate task outputs information about executed migrations
    • db:create command doesn't fail if database already exists

    QueryBuilder

    • ✂ remove redundant Criteria#similar which is loaded with postgres adapter
    • ➕ add Query#insert and Query#upsert
    • ➕ add ExpressionBuilder#values and Values to reference to VALUES statement in upsert
    • .find_by_sql and .to_a of ModelQuery(T) use T.new instead of T.build
    • ➕ add CommonTableExpression to present SQL CTE
    • 📇 rename EagerLoading#with to #with_relation
    • #last! and #last assigns old limit value back after request instead of additional #reverse_order call
    • speed up Query allocation by making all query part containers nilable
    • ➕ add 2nd argument to Query#union setting union to be UNION ALL
    • now Query#with presents API for registering common table expression
    • ➕ add Query#merge
    • 🏗 Query#where yields expression builder
    • Query's #join, #right_join, #left_join and #lateral_join yield expression builders of a main query and joined context
    • ➕ add next SQL functions: count, sum, avg, min, max, coalesce and concat_ws sql functions
    • round function now accepts second optional argument specifying precision
    • Function's #operands_to_sql and #operand_sql now are public
    • 📚 Function.define macro accepts comment key to specify function class documentation comment
    • 0️⃣ Function.define macro arity argument by default is 0 (instead of -1)
    • ➕ add ExpressionBuilder#cast
    • 🖐 handle an empty array passed to Criteria#in
    • 🛠 fix missing LIMIT in query generated by #first!
    • 🛠 fix result type of Executables#exists? query method to Bool (thanks @skloibi)
    • ➕ add Executables#explain

    Model

    • 👍 Base.new now calls after_initialize hooks and supports STI
    • 🏗 Base.build now is alias for Base.new
    • 📜 properties passed to Mapping.mapping now is parsed before main mapping macro is executed
    • #append_{{relation_name}} methods of RelationDefinition now use .new to build a related object
    • 🚚 Resource::Supportable alias is removed
    • Resource.search_by_sql is removed in favour of Resource.all.find_by_sql
    • 🛠 fix bug with ignoring of field converter by a STI child
    • 🛠 fix default constructor for STI child - now it is generated if parent model has only type field without default value
    • 👍 allow mapping option column that defines a custom column name that is mapped to this field (thank @skloibi)
    • 🚚 Base#table_name is moved to Resource
    • Mapping module now can be included by another module with mapping definition
    • STIMapping now doesn't convert result set to hash and use same logic as Mapping
    • ➕ add :auto mapping option to specify whether primary key is autoincrementable

    Validation

    • 🔄 change Validations::Uniqueness to consider field mappings when validating properties (thank @skloibi)
    • 👍 allow passing multiple fields to .validates_uniqueness to validate combination uniqueness (thank @skloibi)

    View

    • introduce Mapping instead of ExperimentalMapping; new mapping heavily reuse Model::Mapping
    • 👍 allow specification of property aliases via column option (cf. Model) (thank @skloibi)
    • mapping shares same functionality as Model's

    Adapter

    • ✂ remove Base::ArgType alias
    • ➕ add Base#upsert
    • Postgres::Adapter#data_type_exists? is renamed to #enum_exists?
    • 🛠 fix bug for dropping foreign key for postgres adapter
    • ✂ remove TableBuilderBuilders - now Migration::Base creates commands by its own
    • speed-up tables column count fetch at application start-up
    • 🛠 Fix result type of #exists? query method to Bool for Base and Postgres adapters (thanks @skloibi)
    • ➕ add Base#explain abstract method and implementations for Mysql and Postgres

    Config

    • ➕ add verbose_migrations to hide or show migration details during db:migrate command invocation

    SqlGenerator

    • add .insert_on_duplicate and .values_expression to BaseSQLGenerator as abstract methods and implementations to Postgres and Mysql
    • now BaseSQLGenerator.from_clause accepts 2 arguments (instead of 2..3) accepting table name as 2nd argument
    • ➕ add BaseSQLGenerator.with_clause which generates CTE
    • ➕ add BaseSQLGenerator.explain

    Migration

    • ➕ add Base#tinyint (not all adapter support it)
    • 🔄 change next Base instance method signature:
      • #foreign_key_exists?(from_table, to_table = nil, column = nil, name : String? = nil)
      • #add_index(table_name : String | Symbol, field : Symbol, type : Symbol? = nil, name : String? = nil, length : Int32? = nil, order : Symbol? = nil) (same for TableBuilder::CreateTable#index and TableBuilder::ChangeTable#add_index)
      • #drop_index(table : String | Symbol, fields : Array(Symbol) = [] of Symbol, name : String? = nil) (same for TableBuilder::ChangeTable#drop_index)
      • #drop_foreign_key(to_table : String | Symbol, column = nil, name = nil) (same for TableBuilder::ChangeTable#drop_foreign_key)
    • ➕ add TableBuilder::CreateTable#column as alias to TableBuilder::CreateTable#field
    • 🆕 new signature of TableBuilder::CreateTable#reference - #reference(name, type : Symbol = :integer, options : Hash(Symbol, AAllowedTypes) = DB_OPTIONS.new)

    Record

    • 👀 for missing fields BaseException exception is raised instead of KeyError
  • v0.7.1 Changes

    February 09, 2019

    🔄 Changelog

    QueryBuilder

    • #pluck, #update, #db_results, #results. #each_result_set and #find_in_batchesof Query respects #none (returns empty result if it has being called)
    • ✂ remove deprecated QueryObject constructor accepting array of options and #params

    Model

    • 🛠 fix mapping issue when all Generics are assumed as unions (#208)

    Validation

    • 👍 allow passing multiple fields to .validates_uniqueness to validate combination uniqueness

    Adapter

    • 0️⃣ Mysql::SchemaProcessor now respects false as column default value
    • 0️⃣ Postgres::SchemaProcessor now respects false as column default value

    Config

    • introduce new configuration pool_size which sets max_idle_pool_size = max_pool_size = initial_pool_size to the given value; getter #pool_size returns #max_pool_size
    • 0️⃣ postgres is no more default adapter

    Migration

    • TableBuilder::Base::AllowedTypes alias includes Float64 and JSON::Any