All Versions
21
Latest Version
Avg Release Cycle
81 days
Latest Release
834 days ago

Changelog History
Page 1

  • v0.12.0 Changes

    December 15, 2021

    General

    • โž• add crystal 1.2.0 support

    QueryBuilder

    • #pluck accepts splatted named tuple of desired attribute-type pairs and returns array of such tuples as a records
    • ๐Ÿ— #upsert passes expression builder as a block argument

    Model

    • add Optimistic locking support via macro with_optimistic_lock(column_name = lock_version)
    • updated_at and created_at fields aren't override on save if have been set manually
    • โž• add upsert class method to insert multiple models while ignoring conflicts on specified unique fields

    Adapter

    • ๐Ÿ›  fix database connection query arguments building
    • each adapter includes RequestMethods instead of including it by base adapter class
    • โž• add a new upsert overload that allows passing a collection of Jennifer::Model::Base
    • fix insert_on_duplicates sql generation for postgres adapter if no unique fields given

    SqlGenerator

    • โšก๏ธ any INSERT, UPDATE, SELECT and DELETE requests uses quoted tables/columns if they are created by QueryBuilder::ExpressionBuilder (raw SQL is placed as-is)
    • .select_clause uses specified query attributes to select and fall back to custom fields only if there is no custom attribute to select

    Migration

    • TableBuilder::ChangeTable now performs DropForeignKey, DropIndex & DropReference before any column manipulation
    • ๐Ÿ›  fix TableBuilder::ChangeEnum to use specified adapter to query effected tables
  • 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