Class: ROM::SQL::Attribute
- Inherits:
-
Attribute
- Object
- Attribute
- ROM::SQL::Attribute
- Extended by:
- Dry::Core::Cache
- Defined in:
- lib/rom/sql/attribute.rb,
lib/rom/sql/extensions/postgres/types/json.rb,
lib/rom/sql/extensions/postgres/types/array.rb
Overview
Extended schema attributes tailored for SQL databases
Constant Summary collapse
- OPERATORS =
%i[>= <= > <].freeze
- NONSTANDARD_EQUALITY_VALUES =
[true, false, nil].freeze
- META_KEYS =
%i(index foreign_key target sql_expr qualified).freeze
- QualifyError =
Error raised when an attribute cannot be qualified
Class.new(StandardError)
Class Method Summary collapse
- .[](*args) ⇒ Object private
Instance Method Summary collapse
-
#! ⇒ Attribute
Negate the attribute’s sql expression.
-
#+(other) ⇒ SQL::Attribute<Types::PG::Array>
Concatenate two arrays.
-
#=~(other) ⇒ Attribute
Return a new attribute with an equality expression.
-
#aliased(name) ⇒ SQL::Attribute
(also: #as)
Return a new attribute with an alias.
-
#any(value) ⇒ SQL::Attribute<Types::Bool>
Check whether the array includes a value Translates to the ANY operator.
-
#canonical ⇒ Object
Return a new attribute in its canonical form.
-
#concat(other, sep = ' ') ⇒ SQL::Function
Create a CONCAT function from the attribute.
-
#contain(other) ⇒ SQL::Attribute<Types::Bool>
Check whether the array includes another array Translates to the @> operator.
-
#contained_by(other) ⇒ SQL::Attribute<Types::Bool>
Check whether the array is contained by another array Translates to the <@ operator.
-
#delete(*path) ⇒ SQL::Attribute<Types::PG::JSONB>
Deletes the specified value by key, index, or path Translates to - or #- depending on the number of arguments.
-
#foreign_key ⇒ SQL::Attribute
Return a new attribute marked as a FK.
-
#func(&block) ⇒ SQL::Function
Create a function DSL from the attribute.
-
#get(idx) ⇒ SQL::Attribute
Get element by index (PG uses 1-based indexing).
-
#get_text(*path) ⇒ SQL::Attribute<Types::String>
Extract the JSON value as text using at the specified path Translates to ->> or #>> depending on the number of arguments.
-
#has_all_keys(*keys) ⇒ SQL::Attribute<Types::Bool>
Does the JSON value have all the specified top-level keys Translates to ?&.
-
#has_any_key(*keys) ⇒ SQL::Attribute<Types::Bool>
Does the JSON value have any of the specified top-level keys Translates to ?|.
-
#has_key(key) ⇒ SQL::Attribute<Types::Bool>
Does the JSON value have the specified top-level key Translates to ?.
-
#in(*args) ⇒ Object
Return a boolean expression with an inclusion test.
-
#indexed ⇒ Object
Returns a new attribute marked as indexed.
- #indexed? ⇒ Boolean
-
#is(other) ⇒ Object
Return a boolean expression with an equality operator.
-
#join(delimiter, null_repr) ⇒ SQL::Attribute<Types::String>
Convert the array to a string by joining values with a delimiter (empty stirng by default) and optional filler for NULL values Translates to an ‘array_to_string` call.
-
#joined ⇒ SQL::Attribute
Return a new attribute marked as joined.
-
#joined? ⇒ Boolean
Return if an attribute was used in a join.
-
#length ⇒ SQL::Attribute<Types::Int>
Return array size.
-
#merge(value) ⇒ SQL::Attribute<Types::PG::JSONB>
Concatenate two JSON values Translates to ||.
- #meta_ast ⇒ Object private
-
#not(other) ⇒ Object
Return a boolean expression with a negated equality operator.
-
#overlaps(other) ⇒ SQL::Attribute<Types::Bool>
Check whether the arrays have common values Translates to &&.
-
#qualified(table_alias = nil) ⇒ SQL::Attribute
Return a new attribute marked as qualified.
-
#qualified? ⇒ Boolean
Return if an attribute type is qualified.
-
#remove_value(value) ⇒ SQL::Attribute<Types::PG::Array>
Remove elements by value.
-
#sql_literal(ds) ⇒ Object
private
Sequel calls this method to coerce an attribute into SQL string.
-
#to_sql_name ⇒ Sequel::SQL::AliasedExpression, Sequel::SQL::Identifier
private
Sequel column representation.
-
#to_sym ⇒ Symbol
Return symbol representation of an attribute.
-
#unwrap ⇒ Object
private
Removes metadata from the type.
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(meth, *args, &block) ⇒ Object (private)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Delegate to sql expression if it responds to a given method
336 337 338 339 340 341 342 343 344 345 346 |
# File 'lib/rom/sql/attribute.rb', line 336 def method_missing(meth, *args, &block) if OPERATORS.include?(meth) __cmp__(meth, args[0]) elsif extensions.key?(meth) extensions[meth].(type, sql_expr, *args, &block) elsif sql_expr.respond_to?(meth) (sql_expr: sql_expr.__send__(meth, *args, &block)) else super end end |
Class Method Details
.[](*args) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
25 26 27 |
# File 'lib/rom/sql/attribute.rb', line 25 def self.[](*args) fetch_or_store(args) { new(*args) } end |
Instance Method Details
#! ⇒ Attribute
Negate the attribute’s sql expression
205 206 207 |
# File 'lib/rom/sql/attribute.rb', line 205 def ! ~self end |
#+(other) ⇒ SQL::Attribute<Types::PG::Array>
Concatenate two arrays
|
# File 'lib/rom/sql/extensions/postgres/types/json.rb', line 113
|
#=~(other) ⇒ Attribute
Return a new attribute with an equality expression
179 180 181 |
# File 'lib/rom/sql/attribute.rb', line 179 def =~(other) (sql_expr: sql_expr =~ binary_operation_arg(other)) end |
#aliased(name) ⇒ SQL::Attribute Also known as: as
Return a new attribute with an alias
39 40 41 |
# File 'lib/rom/sql/attribute.rb', line 39 def aliased(name) super.(name: .fetch(:name, name), sql_expr: sql_expr.as(name)) end |
#any(value) ⇒ SQL::Attribute<Types::Bool>
Check whether the array includes a value Translates to the ANY operator
|
# File 'lib/rom/sql/extensions/postgres/types/array.rb', line 21
|
#canonical ⇒ Object
Return a new attribute in its canonical form
47 48 49 50 51 52 53 |
# File 'lib/rom/sql/attribute.rb', line 47 def canonical if aliased? (alias: nil, sql_expr: nil) else self end end |
#concat(other, sep = ' ') ⇒ SQL::Function
Create a CONCAT function from the attribute
264 265 266 |
# File 'lib/rom/sql/attribute.rb', line 264 def concat(other, sep = ' ') Function.new(type).concat(self, sep, other) end |
#contain(other) ⇒ SQL::Attribute<Types::Bool>
Check whether the array includes another array Translates to the @> operator
|
# File 'lib/rom/sql/extensions/postgres/types/json.rb', line 2
|
#contained_by(other) ⇒ SQL::Attribute<Types::Bool>
Check whether the array is contained by another array Translates to the <@ operator
|
# File 'lib/rom/sql/extensions/postgres/types/json.rb', line 17
|
#delete(*path) ⇒ SQL::Attribute<Types::PG::JSONB>
Deletes the specified value by key, index, or path Translates to - or #- depending on the number of arguments
|
# File 'lib/rom/sql/extensions/postgres/types/json.rb', line 118
|
#foreign_key ⇒ SQL::Attribute
Return a new attribute marked as a FK
122 123 124 |
# File 'lib/rom/sql/attribute.rb', line 122 def foreign_key (foreign_key: true) end |
#func(&block) ⇒ SQL::Function
Create a function DSL from the attribute
247 248 249 |
# File 'lib/rom/sql/attribute.rb', line 247 def func(&block) ProjectionDSL.new(name => self).call(&block).first end |
#get(idx) ⇒ SQL::Attribute
Get element by index (PG uses 1-based indexing)
|
# File 'lib/rom/sql/extensions/postgres/types/json.rb', line 30
|
#get_text(*path) ⇒ SQL::Attribute<Types::String>
Extract the JSON value as text using at the specified path Translates to ->> or #>> depending on the number of arguments
|
# File 'lib/rom/sql/extensions/postgres/types/json.rb', line 45
|
#has_all_keys(*keys) ⇒ SQL::Attribute<Types::Bool>
Does the JSON value have all the specified top-level keys Translates to ?&
|
# File 'lib/rom/sql/extensions/postgres/types/json.rb', line 86
|
#has_any_key(*keys) ⇒ SQL::Attribute<Types::Bool>
Does the JSON value have any of the specified top-level keys Translates to ?|
|
# File 'lib/rom/sql/extensions/postgres/types/json.rb', line 73
|
#has_key(key) ⇒ SQL::Attribute<Types::Bool>
Does the JSON value have the specified top-level key Translates to ?
|
# File 'lib/rom/sql/extensions/postgres/types/json.rb', line 60
|
#in(*args) ⇒ Object
Return a boolean expression with an inclusion test
If the single argument passed to the method is a Range object then the resulting expression will restrict the attribute value with range’s bounds. Upper bound condition will be inclusive/non-inclusive depending on the range type.
If more than one argument is passed to the method or the first argument is not Range then the result will be a simple IN check.
227 228 229 230 231 232 233 234 235 236 237 |
# File 'lib/rom/sql/attribute.rb', line 227 def in(*args) if args.first.is_a?(Range) range = args.first lower_cond = __cmp__(:>=, range.begin) upper_cond = __cmp__(range.exclude_end? ? :< : :<=, range.end) Sequel::SQL::BooleanExpression.new(:AND, lower_cond, upper_cond) else __cmp__(:IN, args) end end |
#indexed ⇒ Object
Returns a new attribute marked as indexed
303 304 305 |
# File 'lib/rom/sql/attribute.rb', line 303 def indexed (index: true) end |
#indexed? ⇒ Boolean
296 297 298 |
# File 'lib/rom/sql/attribute.rb', line 296 def indexed? [:index].equal?(true) end |
#is(other) ⇒ Object
Return a boolean expression with an equality operator
167 168 169 |
# File 'lib/rom/sql/attribute.rb', line 167 def is(other) self =~ other end |
#join(delimiter, null_repr) ⇒ SQL::Attribute<Types::String>
Convert the array to a string by joining values with a delimiter (empty stirng by default) and optional filler for NULL values Translates to an ‘array_to_string` call
|
# File 'lib/rom/sql/extensions/postgres/types/array.rb', line 67
|
#joined ⇒ SQL::Attribute
Return a new attribute marked as joined
Whenever you join two schemas, the right schema’s attribute will be marked as joined using this method
83 84 85 |
# File 'lib/rom/sql/attribute.rb', line 83 def joined (joined: true) end |
#joined? ⇒ Boolean
Return if an attribute was used in a join
98 99 100 |
# File 'lib/rom/sql/attribute.rb', line 98 def joined? [:joined].equal?(true) end |
#length ⇒ SQL::Attribute<Types::Int>
Return array size
|
# File 'lib/rom/sql/extensions/postgres/types/array.rb', line 41
|
#merge(value) ⇒ SQL::Attribute<Types::PG::JSONB>
Concatenate two JSON values Translates to ||
|
# File 'lib/rom/sql/extensions/postgres/types/json.rb', line 99
|
#meta_ast ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
308 309 310 311 312 |
# File 'lib/rom/sql/attribute.rb', line 308 def = super [:index] = true if indexed? end |
#not(other) ⇒ Object
Return a boolean expression with a negated equality operator
193 194 195 |
# File 'lib/rom/sql/attribute.rb', line 193 def not(other) !is(other) end |
#overlaps(other) ⇒ SQL::Attribute<Types::Bool>
Check whether the arrays have common values Translates to &&
|
# File 'lib/rom/sql/extensions/postgres/types/array.rb', line 48
|
#qualified(table_alias = nil) ⇒ SQL::Attribute
Return a new attribute marked as qualified
63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/rom/sql/attribute.rb', line 63 def qualified(table_alias = nil) return self if qualified? && table_alias.nil? case sql_expr when Sequel::SQL::AliasedExpression, Sequel::SQL::Identifier, Sequel::SQL::QualifiedIdentifier type = (qualified: table_alias || true) type.(sql_expr: type.to_sql_name) else raise QualifyError, "can't qualify #{name.inspect} (#{sql_expr.inspect})" end end |
#qualified? ⇒ Boolean
Return if an attribute type is qualified
113 114 115 |
# File 'lib/rom/sql/attribute.rb', line 113 def qualified? [:qualified].equal?(true) || [:qualified].is_a?(Symbol) end |
#remove_value(value) ⇒ SQL::Attribute<Types::PG::Array>
Remove elements by value
|
# File 'lib/rom/sql/extensions/postgres/types/array.rb', line 58
|
#sql_literal(ds) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Sequel calls this method to coerce an attribute into SQL string
273 274 275 |
# File 'lib/rom/sql/attribute.rb', line 273 def sql_literal(ds) ds.literal(sql_expr) end |
#to_sql_name ⇒ Sequel::SQL::AliasedExpression, Sequel::SQL::Identifier
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Sequel column representation
282 283 284 285 286 287 288 289 290 291 292 293 |
# File 'lib/rom/sql/attribute.rb', line 282 def to_sql_name @_to_sql_name ||= if qualified? && aliased? Sequel.qualify(table_name, name).as([:alias]) elsif qualified? Sequel.qualify(table_name, name) elsif aliased? Sequel.as(name, [:alias]) else Sequel[name] end end |
#to_sym ⇒ Symbol
Return symbol representation of an attribute
This uses convention from sequel where double underscore in the name is used for qualifying, and triple underscore means aliasing
144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/rom/sql/attribute.rb', line 144 def to_sym @_to_sym ||= if qualified? && aliased? :"#{table_name}__#{name}___#{[:alias]}" elsif qualified? :"#{table_name}__#{name}" elsif aliased? :"#{name}___#{[:alias]}" else name end end |
#unwrap ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Removes metadata from the type
317 318 319 320 321 322 |
# File 'lib/rom/sql/attribute.rb', line 317 def unwrap = .reject { |k, _| META_KEYS.include?(k) } type = optional? ? right : self.type self.class.new(type.with(meta: ), ) end |