From 87b7578127b6d61d61f197763c2dcaa05455f723 Mon Sep 17 00:00:00 2001 From: jinn999 Date: Fri, 2 Dec 2022 23:28:27 +0100 Subject: [PATCH] Implement function criteria (#912) * Add updated? and created? methods on SaveOperations Implements #888. Adds two new boolean methods to SaveOperation. They work similarly to new_record? but always return false if the record was not persisted (e.g: failed save or not-yet-performed operation) * Implement date function * Move upper and lower to new criterias * generalize the application of functions to columns * Put in standby the extra-param function creation * Final clean up --- spec/avram/string_criteria_spec.cr | 6 +++++ spec/avram/time_criteria_spec.cr | 5 ++++ src/avram/charms/string_extensions.cr | 24 +++---------------- src/avram/charms/time_extensions.cr | 2 ++ src/avram/criteria.cr | 7 ++++++ .../criteria_extensions/between_criteria.cr | 2 +- src/avram/define_attribute.cr | 1 - src/avram/model.cr | 2 +- 8 files changed, 25 insertions(+), 24 deletions(-) diff --git a/spec/avram/string_criteria_spec.cr b/spec/avram/string_criteria_spec.cr index 3833c54cc..25621e696 100644 --- a/spec/avram/string_criteria_spec.cr +++ b/spec/avram/string_criteria_spec.cr @@ -33,6 +33,12 @@ describe String::Lucky::Criteria do end end + describe "trim" do + it "uses TRIM" do + name.trim.eq("elon").to_sql.should eq ["SELECT #{QueryMe::COLUMN_SQL} FROM users WHERE TRIM(users.name) = $1", "elon"] + end + end + describe "not" do describe "with chained criteria" do it "negates the following criteria" do diff --git a/spec/avram/time_criteria_spec.cr b/spec/avram/time_criteria_spec.cr index 10d113802..13074e1e0 100644 --- a/spec/avram/time_criteria_spec.cr +++ b/spec/avram/time_criteria_spec.cr @@ -14,6 +14,11 @@ describe Time::Lucky::Criteria do end end + it "as_date" do + input_date = "2012-01-31" + activated_at.as_date.eq(input_date).to_sql.should eq ["SELECT users.id, users.created_at, users.updated_at, users.activated_at FROM users WHERE DATE(users.activated_at) = $1", input_date] + end + describe "extract" do it "fails with non supported symbol" do expect_raises(ArgumentError) { activated_at.extract(:dayz).eq(5).to_sql } diff --git a/src/avram/charms/string_extensions.cr b/src/avram/charms/string_extensions.cr index 1aa0076c6..2acf9f8df 100644 --- a/src/avram/charms/string_extensions.cr +++ b/src/avram/charms/string_extensions.cr @@ -29,8 +29,6 @@ class String class Criteria(T, V) < Avram::Criteria(T, V) include Avram::IncludesCriteria(T, V) - @upper = false - @lower = false def like(value : String) : T add_clause(Avram::Where::Like.new(column, value)) @@ -40,25 +38,9 @@ class String add_clause(Avram::Where::Ilike.new(column, value)) end - def upper - @upper = true - self - end - - def lower - @lower = true - self - end - - def column - if @upper - "UPPER(#{@column})" - elsif @lower - "LOWER(#{@column})" - else - @column - end - end + define_function_criteria(upper, V) + define_function_criteria(lower, V) + define_function_criteria(trim, String) end end end diff --git a/src/avram/charms/time_extensions.cr b/src/avram/charms/time_extensions.cr index 1bfc508cd..11a9fec00 100644 --- a/src/avram/charms/time_extensions.cr +++ b/src/avram/charms/time_extensions.cr @@ -78,6 +78,8 @@ struct Time class Criteria(T, V) < Avram::Criteria(T, V) include Avram::BetweenCriteria(T, V) include Avram::ExtractCriteria + + define_function_criteria(as_date, String, "DATE") end end end diff --git a/src/avram/criteria.cr b/src/avram/criteria.cr index 40b4fda7a..e452ab903 100644 --- a/src/avram/criteria.cr +++ b/src/avram/criteria.cr @@ -185,4 +185,11 @@ class Avram::Criteria(T, V) sql_clause end end + + macro define_function_criteria(name, output_type = V, sql_name = nil) + {% sql_name = sql_name ? sql_name.id : name.id.upcase %} + def {{name}} + Criteria(T,{{output_type}}).new(rows, "{{sql_name}}(#{column})") + end + end end diff --git a/src/avram/criteria_extensions/between_criteria.cr b/src/avram/criteria_extensions/between_criteria.cr index 673a332bc..13ff9b743 100644 --- a/src/avram/criteria_extensions/between_criteria.cr +++ b/src/avram/criteria_extensions/between_criteria.cr @@ -4,7 +4,7 @@ module Avram::BetweenCriteria(T, V) def between(low_value : V, high_value : V) add_clauses([ Avram::Where::GreaterThanOrEqualTo.new(@column, V.adapter.to_db!(low_value)), - Avram::Where::LessThanOrEqualTo.new(@column, V.adapter.to_db!(high_value)) + Avram::Where::LessThanOrEqualTo.new(@column, V.adapter.to_db!(high_value)), ]) end end diff --git a/src/avram/define_attribute.cr b/src/avram/define_attribute.cr index 9ed6e3e5d..5cfd4fcc4 100644 --- a/src/avram/define_attribute.cr +++ b/src/avram/define_attribute.cr @@ -20,7 +20,6 @@ module Avram::DefineAttribute ATTRIBUTES = [] of Nil \{% end %} - \{% if !@type.ancestors.first.abstract? %} \{% for attribute in @type.ancestors.first.constant :ATTRIBUTES %} \{% ATTRIBUTES << attribute %} diff --git a/src/avram/model.cr b/src/avram/model.cr index 7feb2abaf..900d28136 100644 --- a/src/avram/model.cr +++ b/src/avram/model.cr @@ -16,7 +16,7 @@ abstract class Avram::Model end macro inherited - COLUMNS = [] of Nil # types are not checked in macros + COLUMNS = [] of Nil # types are not checked in macros ASSOCIATIONS = [] of Nil # types are not checked in macros include LuckyCache::Cachable end