General
- address "positional parameter of the overridden method, which has a different name and may affect named argument passing" crystal
1.5.0warning (for full list see MR) - upgrade supported mysql driver version to
0.14.0 - upgrade supported pg driver version to
0.26.0 - add
jsonbtype support for model and migration generators - replace
phoffer/inflector.crinflector library withluckyframework/wordsmith
QueryBuilder
Query.countreturnsInt64instead ofInt32Query.offsetacceptsInt32orInt64as input instead of onlyInt32#group,#selectraise anArgumentErrorif block returns anything except array#having,#reorder,#orderraisesExpressionBuilderas a block argument#whereaccepts hash with string keys as well- added
#find_or_create_by,#find_or_create_by!,#find_or_initialize_byto create/instantiate a record if nothing was found in the DB - added
#find_byand#find_by!as a shortcut for.where().firstand.where().first!
Model
- change default
idattribute type fromInt32toInt64 - generate a setter method for a
Int64attribute that calls#to_i64onInt32value - in mapping automatically assign
null: trueifnullproperty is missing and field is primary - enhance type coercion on initializing instance from hash
- change return type of
.idstoArray(Int64) Model.countreturnsInt64instead ofInt32- add support for
JSON::PullParserattribute class - model class responds to:
#here,#select,#from,#union,#distinct,#order,#group,#with,#merge,#limit,#offset,#lock,#reorder,#count,#max,#min,#sum,#avg,#group_count,#group_max,#group_min,#group_sum,#group_avg,#with_relation,#includes,#preload,#eager_load,#last,#last!,#first,#first!,#find_by,#find_by!,#pluck,#exists?,#increment,#decrement,#ids,#find_records_by_sql,#find_in_batches,#find_each,#join,#right_join,#left_join,#lateral_join - adds
.createand.create!that accepts block - fix a bug when password digest wasn't generated when password was set by passing it to a constructor
- add missing STI initialization to constructors accepting a hash or named tuple
- use
Adapter::Base.coerce_database_valuein constructors accepting a hash or named tuple to coerce values for columns that don't have specified converter - Fix the issue of
Jennifer::Model::OptimisticLocking#reset_lock_versiondecreasing lock version column when it's not changed
Validation
- add
jennifer.errors.messages.requiredmessage in locale yaml file Jennifer::Model::Errors#addacceptsString | Symbol | Proc(Translation, String, String)formessageargumentvalidates_inclusion,validates_exclusion,validates_format,validates_length,validates_uniqueness,validates_presence,validates_absence,validates_numericality,validates_acceptance&validates_confirmationvalidation macros acceptsmessageoption that allows to specify validation message
Relation
belongs_torelation macro acceptsrequiredoption to validate existence of relation on save
View
- model class responds to:
#here,#select,#from,#union,#distinct,#order,#group,#with,#merge,#limit,#offset,#lock,#reorder,#count,#max,#min,#sum,#avg,#group_count,#group_max,#group_min,#group_sum,#group_avg,#with_relation,#includes,#preload,#eager_load,#last,#last!,#first,#first!,#find_by,#find_by!,#pluck,#exists?,#increment,#decrement,#ids,#find_records_by_sql,#find_in_batches,#find_each,#join,#right_join,#left_join,#lateral_join
Adapter
- remove
idcolumn from theversionstable schema - change default
idcolumn type frominttobigint - add
Base.coerce_database_valuemethod to provide interface to perform coercing from default database type used to read column to hash to a desired model attribute type
SqlGenerator
- fix invalid SQL generating for
FROMclause when string value is given for#from
Record
- now calling a
#foo_barmethod on a record that is missing raisesArgumentErrorinstead ofKeyError
General
- add crystal 1.2.0 support
QueryBuilder
#pluckaccepts splatted named tuple of desired attribute-type pairs and returns array of such tuples as a records#upsertpasses expression builder as a block argument
Model
- add Optimistic locking support via macro
with_optimistic_lock(column_name = lock_version) updated_atandcreated_atfields aren't override on save if have been set manually- add
upsertclass method to insert multiple models while ignoring conflicts on specified unique fields
Adapter
- fix database connection query arguments building
- each adapter includes
RequestMethodsinstead of including it by base adapter class - add a new
upsertoverload that allows passing a collection ofJennifer::Model::Base - fix
insert_on_duplicatessql generation for postgres adapter if no unique fields given
SqlGenerator
- any
INSERT,UPDATE,SELECTandDELETErequests uses quoted tables/columns if they are created byQueryBuilder::ExpressionBuilder(raw SQL is placed as-is) .select_clauseuses specified query attributes to select and fall back to custom fields only if there is no custom attribute to select
Migration
TableBuilder::ChangeTablenow performsDropForeignKey,DropIndex&DropReferencebefore any column manipulation- fix
TableBuilder::ChangeEnumto use specified adapter to query effected tables
General
- switch to the
crimson-knight/i18n.cr~> 0.4.1
Migration
- fix
TableBuilder::ChangeTable#drop_referencedropping column before reference - add
TableBuilder::DropReference
General
- add crystal
>= 1.0.0support - fix inconsistent method signatures in multiple places
- add
#to_jsonto 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.0support - add
crystal-pg: 0.23.2support
QueryBuilder
- add custom
#to_jsonto serialize retrieved collection - add
#whereacceptingHash(Symbol, _) - add
Criteria#equalandCriteria#not_equalas original implementation ofCriteria#==andCriteria#!= - add
ExpressionBuilder#and,#orand#xormethods that accepts array of conditions
Model
Authentication#passwordreturns given unecrypted value- add
Coercermodule with static methods to localize all coercing logic for different types - add
.coercermethod to return object responding to all coercing methods described inCoercer mappinggenerates.coerce_{{attribute}(value : String)methods for every field to coerce string value toattribute's typemappinggenerates for every non-string attribute with a setter additional#{{attribute}}=(value : String)setter- allow all build methods (
.new,.createand.update) to receiveHash(String, String)and coerce values to expected types - add
.column_nameto return all field names - fix
.field_namesfrom 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_awareoption forTimeZoneConverterto 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_formatanddate_formatto 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_hashaccepts string as field valueBigDecimalConverter#from_hashaccepts integer and float values as field value- fix
Errors#inspectbug using oldUInt64#to_ssignature - introduce
Timestampmodule that now includeswith_timestampsmacro - reworked how
updated_atandcreated_atfields are set before save - now they are set explicitly without utilizing callbacks - add
Resource.whereacceptingHash(Symbol, _)
Validation
- change
Validator#validateabstract interface to#validate(record, **opts) - update all built-in validators to reflect new
Validatorinterface - make
Validator.with_blank_validationmacro to accept arguments to reference record, field name, value and blank value acceptance
Relation
- remove abstract
#condition_clause&#condition_clause(a)declarations fromIRelation
View
- add custom
#to_json
Adapter
- remove abstract
#updatedeclaration fromBase BaseSQLGenerator#parse_queryconvertsTimearguments to UTC only ifConfig.time_zone_aware_attributesset totrueMysql#read_columncallssuperif column isn't a tiny intResultParser#read_columnconvert time toConfig.local_time_zoneifConfig.time_zone_aware_attributesset totrueor just change time zone to it otherwise
Config
.reset_configcreates new instance instead of executing#initializeon existing object- add
Config.time_zone_aware_attributesto specify whether time zone converting logic should be globally disabled
Migration
- add
precisionandscaleoptions support fordecimaldata type
Record
- add custom
#to_json - add custom
#inspect
General
- add crystal 0.35.0 support and drop 0.34.0 support
QueryBuilder
- allow arbitrary
Queryinstances as nested queries for CTEs - fix failed
nilassertion 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 raiseJennifer::RecordNotFoundexception ModelQuery(T)#to_aandModelQuery(T)#find_by_sqlensureThas loaded actual table field count before making a request
Model
- change model constructor hash argument type from
Hash(String, Jennifer::DBany)toHash(String, AttrType)(same forSymbolkeys) CommonMapping#attributeuses attribute getterCommonMapping#attributeraisesJennifer::UnknownAttributeexception if model has no requested attribute andraise_exception = true- add
CommonMapping#attribute_before_typecastwhich returns given attribute in database format using attribute converter - add
Mapping#{{attribute}}_will_change!to mark{{attribute}}as changed one #primaryuses getter- any
Mapping.mappinginvocation createsAttrTypealias to represent union ofJennifer::DBAnyand any arbitrary type from fields definition - change
Mapping#update_columnsargument type toHash(String | Symbol, AttrType) Mapping#update_columnsraisesJennifer::UnknownAttributeif key-value pairs include unknown attributeMapping#set_attributeto acceptAttrTypeMapping#set_attributeraisesJennifer::UnknownAttributeexception if model has no requested attributeMapping#update_columnsraisesJennifer::UnknownAttributeif key-value pairs include unknown fieldMapping#arguments_to_insertandMapping#arguments_to_saveuse#attribute_before_typecastto collect attributes to store in a database#add_{{relation}}acceptsAttrTypeas a hash value type- rename
EnumConvertertoPgEnumConverter - add
EnumConverter(T)to convert string to crystal enum - add
JSONSerializableConverter(T)to convert JSON field to objects ofTthat support.from_jsonand#to_jsonmethods - add
TimeZoneConverterto convert time attributes from UTC toJennife::Config.local_time_zone
Adapter
- add
DBFormateras a proposed default logger formatter - change logging - emit
Log::Metadatawithquery,argsandtimekeys (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::BaseSQLGeneratornow produces valid SQL when using multiple recursive CTEs (.with(..., true)) in a single query
Migration
- rename
TableBuilder::DB_OPTIONStoTableBuilder::DbOptions
Exceptions
- add
Jennifer::UnknownAttributeto represent case when unknown attribute is tried to be read/written
General
- add Crystal
0.34.0support - add
Jennifer::Presentablewith abstract methods declarations (#attribute,#errors,#human_attribute_name,#attribute_metadata,#class_name)
QueryBuilder
Query#initializenow acceptAdapter::Baseas a second (optional) argumentOrderItemis renamed toOrderExpressionto avoid possible name collisions
Model
- fix an issue with rendering
new_recordanddestroyedsystem variables by#to_json Resource.table_prefixnow returns underscored namespace name (if any) by defaultBaseincludesJennifer::Presentable- add
Translation#class_namemethod to return underscored class name - add
Mapping#attribute_metadatato return attribute metadata by it's name - remove
Base::primary_field_type - Prevent compile time error with models named
ModelorRecord
View
- fix an issue with rendering
new_recordanddestroyedsystem variables by#to_json - remove
Base::primary_field_type
Adapter
- db connection is established on the first request no on adapter initialization
Adapter.adapter_classraisesBaseExceptionif no validConfig.adapteris specified.command_interface,.create_database,.drop_database,.generate_schema,.load_schema,.db_connection,.connection_string,.database_exists?now are instance methodsBase#initializenow exceptsConfiginstance- respect host in
Jennifer::Postgres::CommandInterface#database_exists? - escape connection URI segments
Config#loggernow isLoginstead ofLogger- add read/write adapter segregation
- deprecate
.adapter&.adapter_class - remove
.query,.exec&.scalar
Config
.reset_configinvokes#initializeinstead of creating new instance
Migration
Base#schema_processoris no more public apiRunner.createandRunner.dropnow accept optionAdapter::Baseinstance- pass
to_tableinTableBuilder::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_timestampstoTableBuilder::CHangeTable TableBuilder::CHangeTable#drop_indexalso accepts single column name- remove deprecated
TableBuilder::CreateTable#indexoverrides
Record
#initialize(DB::ResultSet)is removed
QueryBuilder
- use adapter's
#read_columninNestedRelationTree - add
RelationTree#adapter - fix
Ordering#order(Hash(String | Symbol, String | Symbol))
Adapter
- fix issue with treating
tinyintmysql field asboolean - remove
ResultParser#result_to_array - add
Mysql#read_column - add
Base.default_max_bind_vars_countwhich returns default maximum count of bind variables that can be used inBase#bulk_insert(default is 32766) Mysql.default_max_bind_vars_countandPostgres.default_max_bind_vars_countreturns32766Base#bulk_insertdoesn't do table lock no more- if variables that should be inserted by
Base#bulk_insertexceedBase.max_bind_varsall of them are quoted and put into a query - remove
BaseSQLGenerator::ARRAY_ESCAPE - move
BaseSQLGenerator::ARGUMENT_ESCAPE_STRINGtoQuoting - move
BaseSQLGenerator.quote,.escape_string,.filter_outtoQuoting - add correct values quoting for
postgresadapter - add correct values quoting for
mysqladapter - now logger writes
BEGINinstead ofTRANSACTION START,COMMITinstead ofTRANSACTION COMMITandROLLBACKinstead ofTRANSACTION ROLLBACKon corresponding transaction commands - add
SchemaProcessor::FkEventActionsenum to validateon_deleteandon_updateaction values;String | Symbolstill should be used as an argument type everywhere
Config
- add
max_bind_vars_countproperty to present maximum allowed count of bind variables to be used in bulk insert operation - add
MigrationFailureHandlerenum to validatemigration_failure_handler_methodvalue;Symbol | MigrationFailureHandlershould be used as an argument for it - fix
migration_failure_handler_methodconfig - make it instance property
General
- add crystal
0.31.1compatibility - add
crystal-db@0.7.0support - remove
samfrom mandatory dependencies
Model
- fix bug with primary field presence assertion
View
- fix bug with primary field presence assertion
Adapter
- add
dateSQL data type date_timefield type maps totimestampSQL data type (postgres only)
Migration
- add
Runner.pending_migration?to return whether there is pending (not invoked) migration - add
Base.with_transactionmethod to disable automatic transaction wrapping around migration methods - add
Base.with_transaction?to check whether migration is run under a transaction - remove
var_stringfield type - remove
blobfield type for postgres - fix wrong explanation message for
TableBuilder::CreateIndex - add new
TableBuilder::CreateTable#indexsignatures (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)
- make default
varcharlength254(mysql only) - add foreign key ON UPDATE and ON DELETE support
Base#add_foreign_keyacceptson_deleteandon_updatekeyword arguments to specify corresponding actionsTableBuilder::ChangeTable#add_foreign_keyacceptson_deleteandon_updatekeyword arguments to specify corresponding actionsTableBuilder::CreateTable#referenceacceptson_deleteandon_updateoptions to specify corresponding actionsTableBuilder::CreateTable#foreign_keyacceptson_deleteandon_updatekeyword arguments to specify corresponding actions
General
- upgrade
TechMagister/i18n.crdependency to0.3.1
General
- add
crystal-pg0.18.0 support - add ameba check to CI
- fix bug with not defined
JSON
Model
- Add
EnumConverterconverter for PostgreENUMfield convert - (pg only) field presenting
ENUMfield should explicitly specifyconverter: Jennifer::Model::EnumConverter
Adapter
Postgreadapter now doesn't register decoders for each ENUM type in#prepare
Config
- add
allow_outdated_pending_migrationconfiguration to specify whether outdated pending migration should be silently processed or error should be raised
Migration
- extend
Jennifer::Migration::TableBuilder::Base::AllowedTypesalias withInt64type.
General
- by default
db:migratetask outputs information about executed migrations db:createcommand doesn't fail if database already exists
QueryBuilder
- remove redundant
Criteria#similarwhich is loaded withpostgresadapter - add
Query#insertandQuery#upsert - add
ExpressionBuilder#valuesandValuesto reference toVALUESstatement in upsert .find_by_sqland.to_aofModelQuery(T)useT.newinstead ofT.build- add
CommonTableExpressionto present SQL CTE - rename
EagerLoading#withto#with_relation #last!and#lastassigns old limit value back after request instead of additional#reverse_ordercall- speed up
Queryallocation by making all query part containers nilable - add 2nd argument to
Query#unionsetting union to beUNION ALL - now
Query#withpresents API for registering common table expression - add
Query#merge Query#whereyields expression builderQuery's#join,#right_join,#left_joinand#lateral_joinyield expression builders of a main query and joined context- add next SQL functions:
count,sum,avg,min,max,coalesceandconcat_wsSQL functions roundfunction now accepts second optional argument specifying precisionFunction's#operands_to_sqland#operand_sqlnow are publicFunction.definemacro acceptscommentkey to specify function class documentation commentFunction.definemacroarityargument by default is0(instead of-1)- add
ExpressionBuilder#cast - handle an empty array passed to
Criteria#in - fix missing
LIMITin query generated by#first! - fix result type of
Executables#exists?query method toBool(thanks @skloibi) - add
Executables#explain
Model
Base.newnow callsafter_initializehooks and supports STIBase.buildnow is alias forBase.new- properties passed to
Mapping.mappingnow is parsed before main mapping macro is executed #append_{{relation_name}}methods ofRelationDefinitionnow use.newto build a related objectResource::Supportablealias is removedResource.search_by_sqlis removed in favour ofResource.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
typefield without default value - allow mapping option
columnthat defines a custom column name that is mapped to this field (thank @skloibi) Base#table_nameis moved toResourceMappingmodule now can be included by another module with mapping definitionSTIMappingnow doesn't convert result set to hash and use same logic asMapping- add
:automapping option to specify whether primary key is autoincrementable
Validation
- change
Validations::Uniquenessto consider field mappings when validating properties (thank @skloibi) - allow passing multiple fields to
.validates_uniquenessto validate combination uniqueness (thank @skloibi)
View
- introduce
Mappinginstead ofExperimentalMapping; new mapping heavily reuseModel::Mapping - allow specification of property aliases via
columnoption (cf. Model) (thank @skloibi) - mapping shares same functionality as
Model's
Adapter
- remove
Base::ArgTypealias - add
Base#upsert Postgres::Adapter#data_type_exists?is renamed to#enum_exists?- fix bug for dropping foreign key for
postgresadapter - remove
TableBuilderBuilders- nowMigration::Basecreates commands by its own - speed-up tables column count fetch at application start-up
- Fix result type of
#exists?query method toBoolforBaseandPostgresadapters (thanks @skloibi) - add
Base#explainabstract method and implementations forMysqlandPostgres
Config
- add
verbose_migrationsto hide or show migration details duringdb:migratecommand invocation
SqlGenerator
- add
.insert_on_duplicateand.values_expressiontoBaseSQLGeneratoras abstract methods and implementations toPostgresandMysql - now
BaseSQLGenerator.from_clauseaccepts 2 arguments (instead of 2..3) accepting table name as 2nd argument - add
BaseSQLGenerator.with_clausewhich generates CTE - add
BaseSQLGenerator.explain
Migration
- add
Base#tinyint(not all adapter support it) - change next
Baseinstance 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 forTableBuilder::CreateTable#indexandTableBuilder::ChangeTable#add_index)#drop_index(table : String | Symbol, fields : Array(Symbol) = [] of Symbol, name : String? = nil)(same forTableBuilder::ChangeTable#drop_index)#drop_foreign_key(to_table : String | Symbol, column = nil, name = nil)(same forTableBuilder::ChangeTable#drop_foreign_key)
- add
TableBuilder::CreateTable#columnas alias toTableBuilder::CreateTable#field - new signature of
TableBuilder::CreateTable#reference-#reference(name, type : Symbol = :integer, options : Hash(Symbol, AAllowedTypes) = DB_OPTIONS.new)
Record
- for missing fields
BaseExceptionexception is raised instead ofKeyError
QueryBuilder
#pluck,#update,#db_results,#results.#each_result_setand#find_in_batchesofQueryrespects#none(returns empty result if it has being called)- remove deprecated
QueryObjectconstructor 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_uniquenessto validate combination uniqueness
Adapter
Mysql::SchemaProcessornow respectsfalseas column default valuePostgres::SchemaProcessornow respectsfalseas column default value
Config
- introduce new configuration
pool_sizewhich setsmax_idle_pool_size = max_pool_size = initial_pool_sizeto the given value; getter#pool_sizereturns#max_pool_size postgresis no more default adapter
Migration
TableBuilder::Base::AllowedTypesalias includesFloat64andJSON::Any
General
- bump
samto"~> 0.3.0" - add sam command
generate:modelto generate model and related migration - move all logic regarding file generating to
Jennifer::Generatorsspace - add
db:seedtask as a placeholder seeding task db:setupnow invokesdb:seedafterdb:migrate
QueryBuilder
- add
#and,#orand#xorshortcut methods toExpressionBuilder Criteria#innow acceptsSQLNodeas well- add
Statementmodule with base abstract functionality needed for query string generating ExpressionBuilder#gand#groupnow has no argument type restrictionGrouping#conditionnow can be ofStatementtypeQueryincludesStatementQuery#to_sqlnow is#as_sql,#select_args-#sql_argsConditionincludesStatementExecutables#updateaccepts block expectingHash(Symbol, Statement)to be returnedExecutables#modifyis removed in favor of new#updatemethod accepting block- now
LogicOperatoris inherited fromSQLNode #deleteandexists?ofExecutablesdo nothing when#do_nothing?istrue- add
Query#do_nothing? - add
Query.nullwhich returnsQuery.new.none JoinacceptsGroupingforONcondition
Model
- remove
Base.build_params,Base.parameter_convertermethods - remove
ParameterConverterclass - fix skipping generating default constructor by
Mapping.mappingwhen at least one field has default value and all others are nilable stringified_typeoption is removed from theCOLUMNS_METADATASTIMapping#arguments_to_save&STIMapping#arguments_to_insertnow respect field converterTranslationmodel now is includeable module- all class methods of
Translationare moved toTranslation::ClassMethodswhich is automatically extended by target class usingincludedmacro #lookup_ancestorsand#human_attribute_namemethods ofTranslationare addedErrors#basenow is type ofTranslationinstead ofBase- add
Base#persisted? - now attribute-specific rendering for
Resource#inspectis generated by.mapping - add polymorphic relation support for
has_one,has_manyandbelongs_torelations - add
:nodoc:for almost all generated relation methods (except#association) - add missing relation names for criterion in
Relation::Basemethods - add
Relation::IPolymorphicBelongsTo,Relation::PolymorphicHasManyandRelation::PolymorphicHasOne @new_record,@destroyed,@errors, changeset and relation attributes now is ignored byJSON::Serializable- add
skip_validationargument toAuthentication.with_authenticationmacro to specify whether validation should be added - add generating predicate method
#{{attribute}}?for boolean attribute - allow
Jennifer::Model::Base#attribute=to accept not only defined type but alsoJennifer::DBAny - rename
Base#update_attributestoBase#set_attributes
Validation
- all validation macros now accept
:ifkey; the value may be bothSymbolname of a method to be called or expression - replace validation logic generated during a macro call with new validators usage:
Validations::Absence,Validations::Acceptance,Validations::Confirmation,Validations::Exclusion,Validations::Format,Validations::Inclusion,Validations::Length,Validations::Numericality,Validations::Presence,Validations::Uniqueness - remove
Jennifer::Validatorin favour ofJennifer::Valdiations::Validator - all validators by default implement singleton pattern
- all validation macros are moved to
Jennifer::Validations::Macros
View
- now attribute-specific rendering for
Resource#inspectis generated by.mapping - add generating predicate method
#{{attribute}}?for boolean attribute
Adapter
- fix output stream for postgres schema dump
- remove legacy postgres insert
- add
Adapter#foreign_key_exists? - add
Mysql::SchameProcessor - now
Base#schema_processoris abstract - add
Postgres::SchemaProcessor#rename_table SchemaProcessornow is abstract class- all builder methods are moved from
SchemaProcessorclass toTableBuilderBuildersmodule - fix syntax in
SchemaProcessor#drop_foreign_key - all
_queryarguments inBasemethods are renamed toquery Base.extract_argumentsis removed.delete,.existsand.countofBaseSQLGeneratornow returns stringPostgres.bulk_insertis removedTransaction#with_connectionensure to release connection- all sqlite3 related code are removed
Config
- fix
migration_failure_handler_methodproperty from being global - add new property
model_files_pathpresenting model directory (is used in a scope of model generating) - fix ignoring
skip_dumping_schema_sqlconfig
SqlGenerator
.select_clausenow doesn't invoke.from_clauseunder the hood.lock_clauseadds whitespaces around lock statement automatically
Migration
- remove
Runner.generateandRunner::MIGRATION_DATE_FORMAT TableBuilder::CreateTable#referencetriggers#foreign_keyand acceptspolymorphicbool argument presenting whether additional type column should be added; for polymorphic reference foreign key isn't added
Exceptions
- 'RecordNotFound' from
QueryBuilder::Query#first!andQueryBuilder::Query#last!includes detailed parsed query
General
- add
:nodoc:to all internal constants and generated methods (implementing standard ORM methods) from the macros
QueryBuilder
Queryisn't extended byIfrit- add
OrderItemto describe order direction - add
Criteria#order,Criteria#ascandCriteria#descto createOrderItem - add
Condition#eql?to compare with other condition orSQLNode(returnsfalse) - add
Criteria#eql?,Grouping#eql?,LogicOperator#eql? - add
Query#orderandQuery#reorderwith acceptingOrderItem - now
Query#orderwith block to expect aOrderItem - remove
CriteriaContainer QueryObjectnow is an abstract class- changed wording for the
ArgumentErrorin#max,#min,#sum,#avgmethods ofAggregationto "Cannot be used with grouping" - change
Query#from(_from : String | Query)signature toQuery#from(from : String | Query)
Model
#saveand#updatewill returntruewhen is called on an object with no changed fields (all before callbacks are invoked)- next
Basemethods become abstract:.primary_auto_incrementable?,.build_params,#destroy,#arguments_to_save,#arguments_to_insert Base#_extract_attributesandBase#_sti_extract_attributesbecome private- all callback invocation methods become protected
- next
Resourcemethods become abstract:.primary,.field_count,.field_names,.columns_tuple,#to_h,#to_str_h Resourceisn't extended byIfrit- regenerate
.build_paramsfor STI models Scoping.scope(Symbol,QueryObject)now checks in runtime whetherTofJennifer::QueryBuilder::ModelQuery(T)responds to method named after the scope
View
Base#_after_initialize_callbackbecomes protectedBase#_extract_attributesbecomes private
Adapter
- fix custom port not used when accessing the Postgres database
Migration
TableBuilder::Baseisn't extended byIfrit- rename
TableBuilder::ChangeTable#new_table_renamegetter to#new_table_name - fix misuse of local variable in
TableBuilder::ChangeTable#rename_table TableBuilder::ChangeTable#change_columnhas next changes:old_nameargument renamed tonamenew_nameargument is replaced with option inoptionsarguemnt hash- raise
ArgumentErrorif bothtypeandoptions[:sql_type]arenil
TableBuilder::ChangeTable#change_columnraisesArgumentErrorif bothtypeandoptions[:sql_type]arenilTableBuilder::CreateTable#fielddata_typeargument renamed totypeTableBuilder::CreateTable#timestampscreates fields withnull: falseby defaultTableBuilder::CreateTable#add_indexis removed in favour of#index.pending_versions,.assert_outdated_pending_migrationsand.default_adaptermethods ofRunnerbecome privateRunner.configis removed
General
- adds
Time::Spanto supported types
QueryBuilder
- allows listing any
SQLNodeinstance in SELECT clause (like raw SQL or functions) - removes redundant
SQLNode#sql_args_count - adds
SQLNode#filterable?function which presents if node has filterable SQL parameter - refactors
Condition#sql_arg - adds
Functionbase abstract class for defining custom SQL functions - adds
lower,upper,current_timestamp,current_date,current_time,now,concat,abs,ceil,floor,round - adds
Join#filterable?andQuery#filterable? - raise
AmbiguousSQLwhen%symbol is found in the raw SQL (except%s)
Model
- replaces mapping option
numeric_converterwith newconverter - adds
NumericToFloat64ConverterandJSONConverter - now
#to_hand#to_str_huse field getter methods - remove
putsfromJSONConverter#from_db
Adapter
- propagate native
DB::Errorinstead of wrapping it intoBadQuery - manually release a connection when an exception occurs under the transaction
Config
- set default
max_pool_sizeto 1 and warn about danger of setting differentmax_pool_size,max_idle_pool_sizeandinitial_pool_size
Migration
- adds
Migration::TableBuilder::CreateForeignKey&Migration::TableBuilder::DropForeignKey - adds
Migration::Base#add_foreign_key&Migration::Base#drop_foreign_key - adds
Migration::TableBuilder::ChangeTable#add_foreign_key&Migration::TableBuilder::ChangeTable#drop_foreign_key
Exceptions
- add
AmbiguousSQL- is raised when forbidden%symbol is used in the raw SQL
General
- adds support of crystal
0.25.0 - removes
time_zonedependency - removes requiring
"inflector/string" - adds cloning to
Time::Location&Time::Location::Zone - removes
Ifrit.typed_hashandIfrit.typed_arrayusage - presents "mapping types" which allows reusing common type definition
- now
Primary32andPrimary64are mapping types (not aliases ofInt32andInt64) - removes
accorddependency
QueryBuilder
- allows nested eager loading in
ModelQuery(T)#eager_loadandModelQuery(T)#include - all query eager loading methods are extracted to separate module
QueryBuilder::EagerLoadingwhich is included inQueryBuilder::IModelQuery
Model
- introduces model virtual attributes
- adds
Mapping.build_paramsandParameterConverterclass for convertingHash(String, String)parameters to acceptable by model - allows to specify table prefix
- all relations are stored in
Base::RELATIONS - fixes building of sti objects using parent class
- adds
Jennifer::Model::Authenticationmodule with authentication logic - fixes compile time issue with
IRelationwhen app has no belongs-to relation defined - fixes bug with reading
Int64primary key - adds
#inspect - adds
numeric_convertermapping option for numeric postgres field - introduces new
Jennifer::Model::Errorsclass replacingAccord::ErrorListwhich mimics analogic rails one a lot; - moves
Translation::human_errormethod functionality to introducedErrorsinstance level - now next
Resourcestatic methods are abstract:actual_table_field_count,primary_field_name,build,all,superclass Resource#inspectreturns simplified version (only class name and object id)Resource.allnow is a macro method- fixes
Model::Translation.lookup_ancestorsfrom breaking at compilation time - now all built-in validations use attribute getter methods instead of variables
View
- removes
ExperimentalMapping#attributes_hash,ExperimentalMapping.strict_mapping?
Config
local_time_zonenow is aTime::Location- local time zone is loaded using
Time::Location.localas default value
SqlGenerator
- replaces
\nwith whitespace character as query part separator
Migration
- now migration version is taken from file name timestamp
Jennifer::Migration::Base.migrationsreturns a hash of version number => migration class instead of array of classes
QueryBuilder
- fixes bug with compiling application without defined any model (as a result no
ModelQueryclass is defined as well) - allows to pass SQL arguments to left hand condition statement
- fixes bug with invalid order direction type interpretation (#124)
Adapter
- adds command interface layer for invoking console tool utilities (e.g. for dumping database schema)
- adds docker command interface
Config
- makes
Configto realize singleton pattern instead of holding all data as class variables - adds flag to skip dumping database schema after running migrations
- fixes connection port definition (#121)
ifrit/corepact is required- adds
i18nlib support - adds
time_zonelib support
QueryBuilder
- now
#destroyuses#find_each - adds
#patchand#patch!which invokes#updateon each object - introduced
CriteriaContainerto resolve issue with usingCriteriaobject as a key for@orderhash - all
#as_sqlmethods now acceptSQLGeneratorclass
Model
- added methods
#update&#update!which allows to massassign attributes and store object to the db - added support of localization lib (i18n)
- added methods
::human_attribute_name,::human_errorand::humanto translate model attribute name, error message and model name - added own
#valid?and#validate!methods - they performs validation and trigger callbacks each call - added
#invalid?- doesn't trigger validation and callbacks - moved all validation error messages to yaml file
- now
%validates_withaccepts oly one class and allows to pass extra arguments to validator class %validate_presence_ofis renamed to%validate_presence- adds new validation macros:
%validate_absence,%validates_numericality,%validates_acceptanceand%validates_confirmation - introduced own validator class
- adds
after_update/before_updatecallbacks - adds
after_commit/after_rollbackcallbacks - reorganizes the way how callback method names are stored
- now
%mappingautomatically guess is it should be sti or common mapping (should be used in places of%sti_mapping) - removed
#attributes_hash - any time object is converted to UTC when is stored and to local when is retrieved from db
View
- any time object is converted to local when is retrieved from db
Config
- adds
::local_time_zone_namemethod to set application time zone - adds
::local_time_zone- returns local time zone object
Adapter
- any time object passed as argument is converted from local time to UTC
postgresadapter now useINSERTwithRETURNING- now several adapters could be required at the same time
- all schema manipulation methods now in located in the
SchemaProcessor
- All macro methods were rewritten to new 0.24.1 crystal syntax
Adapter
- removed
Jennifer::Adapter::TICKS_PER_MICROSECOND - fixes
Jennifer::Adapter::Mysql#table_column_countbug
Model
- add
Primary32andPrimary64shortcuts for primary key mapping (view mapping respects this as well) - add
::create!&::createwith splatted named tuple arguments - now relation retrieveness is updated for any superclass relations as well
- a relation will be retrieved from db for only persisted record
- move
Jennifer::Mode::buildmethod to%mappingmacro - allow retrieving and building sti records using base class
- fix
#reloadmethod for sti record - optimize building sti record from hash
QueryBuilder
- fix
Criteria#not - add
Criteria#ilike
View
- introduce
View::Materializedsuperclass for materialized views - add
COLUMNS_METADATAconstant - add
::columns_tuplewhich returnsCOLUMNS_METADATA - remove
::children_classes - make
after_initializecallback respect inheritance - add
::adapter
Exceptions
- add
AbstractMethodexception which presents expectation of overriding current method by parents (is useful when method can't be real abstract one) - add
UnknownSTIType
SqlGenerator
- rename
#trancateto#truncate
Migration
- rename
TableBuilder::DropIndextoTableBuilder::DropIndex - remove printing out redundant execution information during db drop and create
- remove
Migration::Base::TABLE_NAMEconstant - allow to pass
QueryBuilder::Queryas source to theCreateMaterializedView(postgres only)
Model
- move
Base#buildmethod without arguments toMappingmodule under the%mapping - added
validates_presence_ofvalidation macros - fixed callback invocation from parent classes
- add
allow_blankkey tovalidates_inclusion,validates_exclusion,validates_format - add
ValidationMessagesmodule which includes methods generating validation error messages - add
Primary32andPrimary64shortcuts forInt32andInt64primary field declarations for model and view - allow use nil usions instead of
null: truenamed tuple option
QueryBuilder
#countmethod is moved fromExecutablesmodule to theAggregationsone- changed method signature of
#find_in_batches - add
#find_each- works same way as#find_in_batchesbut yields each record instead of array - add
#ordered?method toOrderingmodule - switch
Criteria#hashto useobject_idas seed - add
Query#eql? - add
Query#cloneand all related methods - add
Query#except- creates clone except given clauses - make
IModelQueryclass as new superclass ofModelQuery(T); move all methods no depending onTto the new class
Config
- added
portconfiguration ::reset_configresets to default configurations- added validation for adapter and db
::from_uriallows to load configuration from uri
Adapter
- added
#query_arraymethod to request array of arrays of given type - added
#with_table_lockwhich allows to lock table (mysql and postgres have different behaviors)
Query
- added
allandanystatements - refactored logical operators - now they don't group themselves with "()"
- added
ExpressionBuilder#g(ExpressionBuilder#grouping) to group some condition - added
XOR - moved all executable methods to
Executablesmodule - change behavior of
#distinct- now it accepts no arguments and just prependDISTINCTto common select query - added
#find_in_batches- allows to search over requested collection required only determined amount of records per iteration #find_records_by_sql- returns array ofRecordby given SQL string- added
:full_outerjoin type - added
#lateral_jointo makeLATERAL JOIN(for now is supported only by PostgreSQL) - extracted all join methods to
Joiningmodule - extracted all ordering methods to
Orderingmodule - added
#reordermethod allowing to reorder existing query
ModelQuery
- added
#find_by_sqlsimilar toQuery#find_records_by_sql
Model
- added
::with_table_lock - added
::adapter - added
::importto perform one query import - fixed bug with reloading empty relations
Mapping
- added
inverse_ofoption tohas_manyandhas_onerelations to sets owner during relation loading
Exception
BadQuerynow allows to append query body to the main error text
Adapter
- added
#view_exists?(name)
QueryBuilder
-
now
#eager_loadbehaves as old variant of#includes- via joining relations and adding them to theSELECTstatement (breaking changes) -
added
#preloadmethod which allows to load all listed relations after execution of main request -
new behavior of
#includesis same as#preload(breaking changes) -
added
Jennifer::QueryBuilder::QueryObjectwhich designed to be as a abstract class for query objects forModel::Basescopes (will be renamed in futher releases) -
all query related objects are clonable
-
now
GROUPclause is placed right after theWHEREclause -
aggregation methods is moved to
Jennifer::QueryBuilder::Aggregationsmodule which is included in theQueryclass -
Query#selectnow acceptsCriteriaobject,Symbol(which now will be transformed to correspondingCriteria), 'String' (which will be transformed toRawSql), string and symbol tuples, array of criterion and could raise a block withExpressionBuilderas a current context (Array(Criteria)is expected to be returned) -
Query#groupgot same behavior asQuery#select -
Query#orderrealize same idea as withQuery#selectbut with hashes -
added
Criteria#aliasmethod which allows to alias field in theSELECTclause -
ExpressionBuilder#starcreates "all" attribute; allows optional argument specifying table name -
RawSqlnow has@use_braketsattribute presenting whether SQL statement should be surrounded by brackets -
Criteria#sqlmethod now acceptsuse_bracketsargument which is passed toRawSql
Migration
- mysql got
#varcharmethod for column definition - added invoking of
TableBuilder::CreateMaterializedViewin#create_materialized_viewmethod - now
Jennifer::TableBuilder::CreateMaterializedViewaccepts onlyStringquery - added
#drop_materialized_view - added
CreateIndex,DropIndex,CreateView,DropViewclasses and corresponding methods
Record
- added
attribute(name : String, type : T.class)method
Model
- added
::contextmethod which return expression builder for current model - added
::starmethod which returns "all" criteria - moved scope definition to
Scopingmodule - now scopes accepts
QueryBuilder::QueryObjectclass name as a 2nd argument - now object inserting into db use old variant with inserting and grepping last inserted id (because of bug with pg crystal driver)
View
- added view support for both mysql and postgres - name of abstract class for inheritance
Jennifer::View::Base