module Safrano
needed for ruby < 2.5
picked from activsupport; needed for ruby < 2.5 Destructively converts all keys using the block
operations. Same as transform_keys
but modifies self
.
require 'bigdecimal/util'
filter base class and subclass in our OData
namespace
all ordering related classes in our OData
module
Error handling
all dataset expanding related classes in our OData
module ie do eager loading
top level Safrano
namespace
OData
relation related classes/module
all dataset selecting related classes in our OData
module ie do eager loading
our main namespace
url parameters processing . Mostly delegates to specialised classes (filter, order…) to convert into Sequel
exprs.
our main namespace
shamelessly copied from Sequel
…
monkey patch deactivate Rack/multipart because it does not work on simple OData
$batch requests when the content-length is not passed
Link to Model
Note: Safrano
has hardcoded mapping rules for most of types. But
it might not be 100% complete it might not always do what is expected
The type mapping functionality here allows Safrano
users to design type mapping themselves and fill or fix the two above issues
Constants
- APPATOMXML_UTF8
- APPJSON
- APPJSON_UTF8
- APPXML
- APPXML_UTF8
- ARY_204_EMPTY_HASH_ARY
- COMMA
- CONTENT_TYPE
some prominent constants… probably already defined elsewhere eg in
Rack
but lets KISS- CTT_TYPE_LC
- CT_APPXML
- CT_ATOMXML
- CT_JSON
- CT_TEXT
- CV_MAX_DATASERVICE_VERSION
- CV_MIN_DATASERVICE_VERSION
- DB_TYPE_FLOATP_RGX
thank you rubular Test String: DECIMAL (55,2 ) Match groups 1 DECIMAL 2 (55,2 ) 3 55,2 4 55 5 ,2 6 2
- DB_TYPE_INTLIKE_RGX
Note: “char” (quoted!) is postgresql's byte type
- DB_TYPE_NUMDEC_RGX
- DB_TYPE_STRING_RGX
TODO: use
Sequel
GENERIC_TYPES: –> Constants GENERIC_TYPES = %w'String Integer Float Numeric BigDecimal Date DateTime Time File TrueClass FalseClass'.freeze Classes specifying generic types thatSequel
will convert to database-specific types.- EMPTY_ARRAY
frozen empty Array/Hash to reduce unncecessary object creation
- EMPTY_HASH
- EMPTY_HASH_IN_ARY
- EMPTY_STRING
- MAX_DATASERVICE_VERSION
- MIN_DATASERVICE_VERSION
- MP_MIXED
- SPACE
- TEXTPLAIN_UTF8
- TransitionBatch
- TransitionContentId
- TransitionCount
- TransitionEnd
- TransitionExecuteFunc
- TransitionLinks
- TransitionMetadata
- TransitionValue
- VERSION
Attributes
Public Class Methods
# File lib/odata/complex_type.rb, line 275 def Safrano.ComplexType(**props) Class.new(Safrano::ComplexType) do @props = props props.each { |a, klassmod| asym = a.to_sym define_method(asym) do @values[asym] end define_method("#{a}=") do |val| @values[asym] = val end } define_method :initialize do |*p, **kwvals| super() p.zip(props.keys).each { |val, a| @values[a] = val } if p kwvals.each { |a, val| @values[a] = val if props.key?(a) } if kwvals end end end
# File lib/odata/function_import.rb, line 8 def self.FunctionImport(name) FunctionImport::Function.new(name) end
type mappings are hard, especially between “Standards” like SQL and OData
V2 (might be a bit better in V4 ?) this is all best effort/try to make it work logic
# File lib/odata/edm/primitive_types.rb, line 40 def self.add_edm_types(metadata, props) # try num/dec with db_type: metadata[:edm_type] = if (md = DB_TYPE_NUMDEC_RGX.match(props[:db_type])) prec = md[4] scale = md[6] if (scale && prec) if (scale == '0') # dont force default scale to 0 like SQL standard metadata[:edm_precision] = prec "Edm.Decimal(#{prec})" else # we have precision and scale metadata[:edm_scale] = scale metadata[:edm_precision] = prec "Edm.Decimal(#{prec},#{scale})" end elsif prec # we have precision only metadata[:edm_precision] = prec "Edm.Decimal(#{prec})" else 'Edm.Decimal' end end return if metadata[:edm_type] # try float(prec) with db_type: metadata[:edm_type] = if (md = DB_TYPE_FLOATP_RGX.match(props[:db_type])) # FLOAT( 22) match groups # 1 FLOAT # 2 (22 ) # 3 22 if (prec = md[3]) # we have precision only metadata[:edm_precision] = prec 'Edm.Double' end end return if metadata[:edm_type] # try int-like with db_type: # smallint|int|integer|bigint|serial|bigserial metadata[:edm_type] = if (md = DB_TYPE_INTLIKE_RGX.match(props[:db_type])) if (itype = md[1]) case itype.downcase when 'smallint', 'int2', 'smallserial' 'Edm.Int16' when 'int', 'integer', 'serial', 'mediumint', 'int4' 'Edm.Int32' when 'bigint', 'bigserial', 'int8' 'Edm.Int64' when 'tinyint' 'Edm.Byte' end end end return if metadata[:edm_type] # try with Sequel(ruby) type metadata[:edm_type] = case props[:type] when :integer 'Edm.Int32' when :string 'Edm.String' when :date 'Edm.DateTime' when :datetime 'Edm.DateTime' when :time 'Edm.Time' when :boolean 'Edm.Boolean' when :float 'Edm.Double' when :decimal 'Edm.Decimal' when :blob 'Edm.Binary' else end end