aliyun-log 0.2.6 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/aliyun/log/config.rb +2 -1
- data/lib/aliyun/log/record.rb +3 -37
- data/lib/aliyun/log/record/exception.rb +1 -0
- data/lib/aliyun/log/record/field.rb +10 -6
- data/lib/aliyun/log/record/persistence.rb +36 -19
- data/lib/aliyun/log/record/relation.rb +70 -13
- data/lib/aliyun/log/record/scoping.rb +55 -0
- data/lib/aliyun/log/record/type_casting.rb +191 -0
- data/lib/aliyun/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b389451492d70d3427b9a940de87c2166d862ac543f882b97a3924e31b51e92c
|
4
|
+
data.tar.gz: 6f8d17bad66ed46c0a8da7e514c10cfaa1198418e48e7d2f03be8f8de499d16d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1c68ba2d18b987e36c96187a7007ede440af4f0beb36748e49ce213872f57dd5db78dfb82ed63c4f9ee5f87b558daa4fc0686b13e71533ba4d3dc6fdaa3333ae
|
7
|
+
data.tar.gz: 3ce13d9720545a7394a0b64b2b6adb78f196dd83a554f7b872a57460e29dac5dd2876a5a528c7c728c537ece778bc4913900b0487856dd65c7d563ff5f0045ee
|
data/lib/aliyun/log/config.rb
CHANGED
@@ -7,7 +7,8 @@ module Aliyun
|
|
7
7
|
@endpoint = 'https://cn-beijing.log.aliyuncs.com'
|
8
8
|
@open_timeout = 10
|
9
9
|
@read_timeout = 120
|
10
|
-
@log_level = Logger::
|
10
|
+
@log_level = Logger::WARN
|
11
|
+
@log_file = STDOUT
|
11
12
|
@timestamps = true
|
12
13
|
class << self
|
13
14
|
attr_accessor :endpoint, :access_key_id, :access_key_secret,
|
data/lib/aliyun/log/record.rb
CHANGED
@@ -9,8 +9,7 @@ require 'forwardable'
|
|
9
9
|
require_relative 'record/exception'
|
10
10
|
require_relative 'record/field'
|
11
11
|
require_relative 'record/persistence'
|
12
|
-
require_relative 'record/
|
13
|
-
require_relative 'record/scope_registry'
|
12
|
+
require_relative 'record/scoping'
|
14
13
|
|
15
14
|
module Aliyun
|
16
15
|
module Log
|
@@ -28,7 +27,7 @@ module Aliyun
|
|
28
27
|
|
29
28
|
Log.included_models << self unless Log.included_models.include? self
|
30
29
|
|
31
|
-
field :created_at, :text if Config.timestamps
|
30
|
+
field :created_at, type: :text, cast_type: :datetime if Config.timestamps
|
32
31
|
|
33
32
|
define_model_callbacks :save, :create, :initialize
|
34
33
|
|
@@ -37,6 +36,7 @@ module Aliyun
|
|
37
36
|
|
38
37
|
include Field
|
39
38
|
include Persistence
|
39
|
+
include Scoping
|
40
40
|
|
41
41
|
include ActiveModel::AttributeMethods
|
42
42
|
|
@@ -52,40 +52,6 @@ module Aliyun
|
|
52
52
|
opt[:field_doc_value] = opt[:field_doc_value] != false
|
53
53
|
self.options = opt
|
54
54
|
end
|
55
|
-
|
56
|
-
delegate :load, :result, :count, to: :all
|
57
|
-
delegate :where, :query, :search, :sql, :from, :to, :page, :line, :limit, :offset, to: :all
|
58
|
-
delegate :first, :last, :second, :third, :fourth, :fifth, :find_offset, to: :all
|
59
|
-
|
60
|
-
def current_scope
|
61
|
-
ScopeRegistry.value_for(:current_scope, self)
|
62
|
-
end
|
63
|
-
|
64
|
-
def current_scope=(scope)
|
65
|
-
ScopeRegistry.set_value_for(:current_scope, self, scope)
|
66
|
-
end
|
67
|
-
|
68
|
-
def scope(name, body)
|
69
|
-
raise ArgumentError, 'The scope body needs to be callable.' unless body.respond_to?(:call)
|
70
|
-
|
71
|
-
singleton_class.send(:define_method, name) do |*args|
|
72
|
-
scope = all
|
73
|
-
scope = scope.scoping { body.call(*args) }
|
74
|
-
scope
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def all
|
79
|
-
scope = current_scope
|
80
|
-
scope ||= relation.from(0).to(Time.now.to_i)
|
81
|
-
scope
|
82
|
-
end
|
83
|
-
|
84
|
-
private
|
85
|
-
|
86
|
-
def relation
|
87
|
-
Relation.new(self)
|
88
|
-
end
|
89
55
|
end
|
90
56
|
|
91
57
|
def initialize(attrs = {})
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'type_casting'
|
4
|
+
|
3
5
|
module Aliyun
|
4
6
|
module Log
|
5
7
|
module Record
|
@@ -18,10 +20,12 @@ module Aliyun
|
|
18
20
|
|
19
21
|
included do
|
20
22
|
class_attribute :attributes, instance_accessor: false, default: {}
|
23
|
+
extend Common::Logging
|
21
24
|
end
|
22
25
|
|
23
26
|
module ClassMethods
|
24
|
-
def field(name,
|
27
|
+
def field(name, options = {})
|
28
|
+
type = options[:type] || :text
|
25
29
|
unless PERMITTED_KEY_TYPES.include?(type)
|
26
30
|
raise ArgumentError, "Field #{name} type(#{type}) error, key type only support text/long/double/json"
|
27
31
|
end
|
@@ -33,7 +37,7 @@ module Aliyun
|
|
33
37
|
warn_about_method_overriding("#{named}=", name)
|
34
38
|
warn_about_method_overriding("#{named}?", name)
|
35
39
|
|
36
|
-
define_attribute_method(name)
|
40
|
+
define_attribute_method(name)
|
37
41
|
|
38
42
|
generated_methods.module_eval do
|
39
43
|
define_method(named) { read_attribute(named) }
|
@@ -61,7 +65,6 @@ module Aliyun
|
|
61
65
|
remove_method field
|
62
66
|
remove_method :"#{field}="
|
63
67
|
remove_method :"#{field}?"
|
64
|
-
remove_method :"#{field}_before_type_cast"
|
65
68
|
end
|
66
69
|
end
|
67
70
|
|
@@ -77,7 +80,8 @@ module Aliyun
|
|
77
80
|
|
78
81
|
def warn_about_method_overriding(method_name, field_name)
|
79
82
|
if instance_methods.include?(method_name.to_sym)
|
80
|
-
|
83
|
+
logger.warn("Method #{method_name} generated for the field #{field_name} " \
|
84
|
+
'overrides already existing method')
|
81
85
|
end
|
82
86
|
end
|
83
87
|
end
|
@@ -103,7 +107,7 @@ module Aliyun
|
|
103
107
|
attr_accessor :attributes
|
104
108
|
|
105
109
|
def write_attribute(name, value)
|
106
|
-
attributes[name.to_sym] = value
|
110
|
+
attributes[name.to_sym] = TypeCasting.cast_field(value, self.class.attributes[name.to_sym])
|
107
111
|
end
|
108
112
|
|
109
113
|
alias []= write_attribute
|
@@ -114,7 +118,7 @@ module Aliyun
|
|
114
118
|
alias [] read_attribute
|
115
119
|
|
116
120
|
def set_created_at
|
117
|
-
self.created_at ||= DateTime.now.in_time_zone(Time.zone).
|
121
|
+
self.created_at ||= DateTime.now.in_time_zone(Time.zone).iso8601 if timestamps_enabled?
|
118
122
|
end
|
119
123
|
|
120
124
|
def timestamps_enabled?
|
@@ -56,9 +56,8 @@ module Aliyun
|
|
56
56
|
def create(data, opts = {})
|
57
57
|
auto_load_schema
|
58
58
|
if data.is_a?(Array)
|
59
|
-
logs =
|
60
|
-
|
61
|
-
logs << new(log_attr).save_array
|
59
|
+
logs = data.map do |log_attr|
|
60
|
+
new(log_attr).save_array
|
62
61
|
end
|
63
62
|
res = Log.record_connection.put_log(project_name, logstore_name, logs, opts)
|
64
63
|
res.code == 200
|
@@ -80,17 +79,11 @@ module Aliyun
|
|
80
79
|
end
|
81
80
|
|
82
81
|
def field_indices
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
end
|
88
|
-
indices.each do |_, v|
|
89
|
-
next unless v[:doc_value].nil?
|
90
|
-
|
91
|
-
v[:doc_value] = options[:field_doc_value] != false
|
82
|
+
if options[:field_index] == false
|
83
|
+
attributes.select { |_, value| value[:index] == true }
|
84
|
+
else
|
85
|
+
attributes.reject { |_, value| value[:index] == false }
|
92
86
|
end
|
93
|
-
indices
|
94
87
|
end
|
95
88
|
|
96
89
|
def create_index
|
@@ -104,18 +97,38 @@ module Aliyun
|
|
104
97
|
def update_index
|
105
98
|
conf_res = Log.record_connection.get_index(project_name, logstore_name)
|
106
99
|
raw_conf = JSON.parse(conf_res)
|
107
|
-
index_conf = raw_conf.
|
108
|
-
|
109
|
-
index_conf['keys'][k.to_s] ||=
|
100
|
+
index_conf = raw_conf.deep_dup
|
101
|
+
field_index_types.each do |k, v|
|
102
|
+
index_conf['keys'][k.to_s] ||= {}
|
103
|
+
index_conf['keys'][k.to_s].merge!(v.as_json)
|
110
104
|
end
|
111
105
|
return if index_conf['keys'] == raw_conf['keys']
|
112
106
|
|
113
107
|
Log.record_connection.update_index(
|
114
108
|
project_name,
|
115
109
|
logstore_name,
|
116
|
-
index_conf['keys']
|
110
|
+
index_conf['keys'].with_indifferent_access
|
117
111
|
)
|
118
112
|
end
|
113
|
+
|
114
|
+
def field_index_types
|
115
|
+
field_indices.tap do |tap|
|
116
|
+
tap.each do |_, v|
|
117
|
+
v[:alias] ||= ''
|
118
|
+
v[:caseSensitive] ||= false
|
119
|
+
v[:chn] ||= false
|
120
|
+
v[:doc_value] = options[:field_doc_value] != false if v[:doc_value].nil?
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def dump_attributes
|
127
|
+
attributes.dup.tap do |tap|
|
128
|
+
tap.each do |k, v|
|
129
|
+
tap[k] = TypeCasting.dump_field(v, self.class.attributes[k])
|
130
|
+
end
|
131
|
+
end
|
119
132
|
end
|
120
133
|
|
121
134
|
def save
|
@@ -123,7 +136,11 @@ module Aliyun
|
|
123
136
|
run_callbacks(:create) do
|
124
137
|
run_callbacks(:save) do
|
125
138
|
if valid?
|
126
|
-
res = Log.record_connection.put_log(
|
139
|
+
res = Log.record_connection.put_log(
|
140
|
+
self.class.project_name,
|
141
|
+
self.class.logstore_name,
|
142
|
+
dump_attributes
|
143
|
+
)
|
127
144
|
res.code == 200
|
128
145
|
else
|
129
146
|
false
|
@@ -135,7 +152,7 @@ module Aliyun
|
|
135
152
|
def save_array
|
136
153
|
run_callbacks(:create) do
|
137
154
|
run_callbacks(:save) do
|
138
|
-
validate! &&
|
155
|
+
validate! && dump_attributes
|
139
156
|
end
|
140
157
|
end
|
141
158
|
end
|
@@ -8,12 +8,11 @@ module Aliyun
|
|
8
8
|
@klass = klass
|
9
9
|
@opts = opts
|
10
10
|
@klass.auto_load_schema
|
11
|
-
@opts[:search] ||= '*'
|
12
11
|
end
|
13
12
|
|
14
|
-
def inspect
|
15
|
-
|
16
|
-
end
|
13
|
+
# def inspect
|
14
|
+
# "#<#{self.class}>"
|
15
|
+
# end
|
17
16
|
|
18
17
|
def first(line = 1)
|
19
18
|
find_offset(0, line, false)
|
@@ -87,13 +86,15 @@ module Aliyun
|
|
87
86
|
self
|
88
87
|
end
|
89
88
|
|
90
|
-
def search(
|
91
|
-
|
89
|
+
def search(*statement)
|
90
|
+
ql = statement_ql(*statement)
|
91
|
+
@opts[:search] = ql if ql.present?
|
92
92
|
self
|
93
93
|
end
|
94
94
|
|
95
|
-
def sql(
|
96
|
-
|
95
|
+
def sql(*statement)
|
96
|
+
ql = statement_ql(*statement)
|
97
|
+
@opts[:sql] = ql if ql.present?
|
97
98
|
self
|
98
99
|
end
|
99
100
|
|
@@ -120,7 +121,7 @@ module Aliyun
|
|
120
121
|
query[:line] ||= 100
|
121
122
|
query[:offset] = query[:page] * query[:line]
|
122
123
|
end
|
123
|
-
query[:query] = query[:search]
|
124
|
+
query[:query] = query[:search] || '*'
|
124
125
|
query[:query] = "#{query[:query]}|#{query[:sql]}" if query[:sql].present?
|
125
126
|
res = Log.record_connection.get_logs(@klass.project_name, @klass.logstore_name, query)
|
126
127
|
JSON.parse(res)
|
@@ -128,16 +129,72 @@ module Aliyun
|
|
128
129
|
|
129
130
|
def load
|
130
131
|
result.map do |json_attr|
|
131
|
-
|
132
|
-
|
133
|
-
|
132
|
+
record = @klass.new
|
133
|
+
json_attr.each do |key, value|
|
134
|
+
record.send("#{key}=", value) if record.respond_to?("#{key}=")
|
134
135
|
end
|
135
|
-
|
136
|
+
record
|
136
137
|
end
|
137
138
|
end
|
138
139
|
|
139
140
|
private
|
140
141
|
|
142
|
+
def statement_ql(*statement)
|
143
|
+
if statement.size == 1
|
144
|
+
sanitize_hash(statement.first)
|
145
|
+
elsif statement.size > 1
|
146
|
+
sanitize_array(*statement)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def sanitize_hash(search_content)
|
151
|
+
return search_content unless search_content.is_a?(Hash)
|
152
|
+
|
153
|
+
search_content.select { |_, v| v.present? }.map do |key, value|
|
154
|
+
unless @klass.attributes[:"#{key}"]
|
155
|
+
raise UnknownAttributeError, "unknown field '#{key}' for #{@klass.name}."
|
156
|
+
end
|
157
|
+
|
158
|
+
"#{key}: #{value}"
|
159
|
+
end.join(' AND ')
|
160
|
+
end
|
161
|
+
|
162
|
+
def sanitize_array(*ary)
|
163
|
+
statement, *values = ary
|
164
|
+
if values.first.is_a?(Hash) && /:\w+/.match?(statement)
|
165
|
+
replace_named_bind_variables(statement, values.first)
|
166
|
+
elsif statement.include?('?')
|
167
|
+
replace_bind_variables(statement, values)
|
168
|
+
elsif statement.blank?
|
169
|
+
statement
|
170
|
+
else
|
171
|
+
statement % values.collect(&:to_s)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def replace_named_bind_variables(statement, bind_vars)
|
176
|
+
statement.gsub(/(:?):([a-zA-Z]\w*)/) do |match|
|
177
|
+
if bind_vars.include?(match = Regexp.last_match(2).to_sym)
|
178
|
+
"'#{bind_vars[match]}'"
|
179
|
+
else
|
180
|
+
raise ParseStatementInvalid, "missing value for :#{match} in #{statement}"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def replace_bind_variables(statement, values)
|
186
|
+
expected = statement.count('?')
|
187
|
+
provided = values.size
|
188
|
+
if expected != provided
|
189
|
+
raise ParseStatementInvalid, "wrong number of bind variables (#{provided} " \
|
190
|
+
"for #{expected}) in: #{statement}"
|
191
|
+
end
|
192
|
+
bound = values.dup
|
193
|
+
statement.gsub(/\?/) do
|
194
|
+
"'#{bound.shift}'"
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
141
198
|
def method_missing(method, *args, &block)
|
142
199
|
if @klass.respond_to?(method)
|
143
200
|
scoping { @klass.public_send(method, *args, &block) }
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'scope_registry'
|
4
|
+
require_relative 'relation'
|
5
|
+
|
6
|
+
module Aliyun
|
7
|
+
module Log
|
8
|
+
module Record
|
9
|
+
module Scoping
|
10
|
+
extend ActiveSupport::Concern
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
delegate :load, :result, :count, to: :all
|
14
|
+
delegate :where, :query, :search, :sql, :from, :to,
|
15
|
+
:page, :line, :limit, :offset, to: :all
|
16
|
+
delegate :first, :last, :second, :third, :fourth, :fifth, :find_offset, to: :all
|
17
|
+
|
18
|
+
def current_scope
|
19
|
+
ScopeRegistry.value_for(:current_scope, self)
|
20
|
+
end
|
21
|
+
|
22
|
+
def current_scope=(scope)
|
23
|
+
ScopeRegistry.set_value_for(:current_scope, self, scope)
|
24
|
+
end
|
25
|
+
|
26
|
+
def scope(name, body)
|
27
|
+
raise ArgumentError, 'The scope body needs to be callable.' unless body.respond_to?(:call)
|
28
|
+
|
29
|
+
singleton_class.send(:define_method, name) do |*args|
|
30
|
+
scope = all
|
31
|
+
scope = scope.scoping { body.call(*args) }
|
32
|
+
scope
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def unscoped
|
37
|
+
block_given? ? relation.scoping { yield } : relation
|
38
|
+
end
|
39
|
+
|
40
|
+
def all
|
41
|
+
scope = current_scope
|
42
|
+
scope ||= relation.from(0).to(Time.now.to_i)
|
43
|
+
scope
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def relation
|
49
|
+
Relation.new(self)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Aliyun
|
6
|
+
module Log
|
7
|
+
module Record
|
8
|
+
module TypeCasting
|
9
|
+
TYPE_MAPPING = {
|
10
|
+
text: :string,
|
11
|
+
long: :integer,
|
12
|
+
double: :bigdecimal,
|
13
|
+
json: :json
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
def self.cast_field(value, options)
|
17
|
+
options ||= {}
|
18
|
+
type = options[:cast_type]
|
19
|
+
type ||= TYPE_MAPPING[options[:type]]
|
20
|
+
|
21
|
+
return value if options.nil?
|
22
|
+
return nil if value.nil?
|
23
|
+
|
24
|
+
caster = Registry.lookup(type)
|
25
|
+
raise ArgumentError, "Unknown type #{options[:type]}" if caster.nil?
|
26
|
+
|
27
|
+
caster.new(options).cast(value)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.dump_field(value, options)
|
31
|
+
options ||= {}
|
32
|
+
type = options[:cast_type]
|
33
|
+
type ||= TYPE_MAPPING[options[:type]]
|
34
|
+
|
35
|
+
return value if options.nil?
|
36
|
+
return nil if value.nil?
|
37
|
+
|
38
|
+
dumper = Registry.lookup(type)
|
39
|
+
raise ArgumentError, "Unknown type #{options[:type]}" if dumper.nil?
|
40
|
+
|
41
|
+
dumper.new(options).dump(value)
|
42
|
+
end
|
43
|
+
|
44
|
+
class Value
|
45
|
+
def initialize(options)
|
46
|
+
@options = options
|
47
|
+
end
|
48
|
+
|
49
|
+
def cast(value)
|
50
|
+
value
|
51
|
+
end
|
52
|
+
|
53
|
+
def dump(value)
|
54
|
+
value
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class StringType < Value; end
|
59
|
+
|
60
|
+
class DateType < Value
|
61
|
+
def cast(value)
|
62
|
+
return nil unless value.respond_to?(:to_date)
|
63
|
+
|
64
|
+
value.to_date
|
65
|
+
end
|
66
|
+
|
67
|
+
def dump(value)
|
68
|
+
if value.respond_to?(:to_date)
|
69
|
+
value.to_datetime.iso8601
|
70
|
+
else
|
71
|
+
value.to_s
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class DateTimeType < Value
|
77
|
+
def cast(value)
|
78
|
+
return nil unless value.respond_to?(:to_datetime)
|
79
|
+
|
80
|
+
dt = begin
|
81
|
+
::DateTime.parse(value)
|
82
|
+
rescue StandardError
|
83
|
+
nil
|
84
|
+
end
|
85
|
+
if dt
|
86
|
+
seconds = string_utc_offset(value) || 0
|
87
|
+
offset = seconds_to_offset(seconds)
|
88
|
+
::DateTime.new(dt.year, dt.mon, dt.mday, dt.hour, dt.min, dt.sec, offset)
|
89
|
+
else
|
90
|
+
value.to_datetime
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def dump(value)
|
95
|
+
if value.respond_to?(:to_datetime)
|
96
|
+
value.to_datetime.iso8601
|
97
|
+
else
|
98
|
+
value.to_s
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
def string_utc_offset(string)
|
105
|
+
Date._parse(string)[:offset]
|
106
|
+
end
|
107
|
+
|
108
|
+
def seconds_to_offset(seconds)
|
109
|
+
ActiveSupport::TimeZone.seconds_to_utc_offset(seconds)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
class IntegerType < Value
|
114
|
+
def cast(value)
|
115
|
+
if value == true
|
116
|
+
1
|
117
|
+
elsif value == false
|
118
|
+
0
|
119
|
+
elsif value.is_a?(String) && value.blank?
|
120
|
+
nil
|
121
|
+
elsif value.is_a?(Float) && !value.finite?
|
122
|
+
nil
|
123
|
+
elsif !value.respond_to?(:to_i)
|
124
|
+
nil
|
125
|
+
else
|
126
|
+
value.to_i
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
class BigDecimalType < Value
|
132
|
+
def cast(value)
|
133
|
+
if value == true
|
134
|
+
1
|
135
|
+
elsif value == false
|
136
|
+
0
|
137
|
+
elsif value.is_a?(Symbol)
|
138
|
+
value.to_s.to_d
|
139
|
+
elsif value.is_a?(String) && value.blank?
|
140
|
+
nil
|
141
|
+
elsif value.is_a?(Float) && !value.finite?
|
142
|
+
nil
|
143
|
+
elsif !value.respond_to?(:to_d)
|
144
|
+
nil
|
145
|
+
else
|
146
|
+
value.to_d
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
class JsonType < Value
|
152
|
+
def cast(value)
|
153
|
+
return value unless value.is_a?(String)
|
154
|
+
|
155
|
+
begin
|
156
|
+
ActiveSupport::JSON.decode(value)
|
157
|
+
rescue StandardError
|
158
|
+
nil
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def dump(value)
|
163
|
+
ActiveSupport::JSON.encode(value) unless value.nil?
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
module Registry
|
168
|
+
module_function
|
169
|
+
|
170
|
+
@registrations = {}
|
171
|
+
|
172
|
+
def register(name, klass = nil)
|
173
|
+
@registrations[name.to_sym] = klass
|
174
|
+
end
|
175
|
+
|
176
|
+
def lookup(name)
|
177
|
+
name ||= :string
|
178
|
+
@registrations[name.to_sym]
|
179
|
+
end
|
180
|
+
|
181
|
+
register(:string, StringType)
|
182
|
+
register(:date, DateType)
|
183
|
+
register(:datetime, DateTimeType)
|
184
|
+
register(:bigdecimal, BigDecimalType)
|
185
|
+
register(:integer, IntegerType)
|
186
|
+
register(:json, JsonType)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
data/lib/aliyun/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aliyun-log
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yingce Liu
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-06-
|
11
|
+
date: 2020-06-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -137,6 +137,8 @@ files:
|
|
137
137
|
- lib/aliyun/log/record/persistence.rb
|
138
138
|
- lib/aliyun/log/record/relation.rb
|
139
139
|
- lib/aliyun/log/record/scope_registry.rb
|
140
|
+
- lib/aliyun/log/record/scoping.rb
|
141
|
+
- lib/aliyun/log/record/type_casting.rb
|
140
142
|
- lib/aliyun/log/request.rb
|
141
143
|
- lib/aliyun/log/server_error.rb
|
142
144
|
- lib/aliyun/version.rb
|