stairwell 0.1.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +36 -2
- data/README.md +29 -10
- data/lib/stairwell/bind_transformer.rb +11 -8
- data/lib/stairwell/query.rb +20 -3
- data/lib/stairwell/types/base_type.rb +17 -0
- data/lib/stairwell/types/boolean_type.rb +9 -0
- data/lib/stairwell/types/column_name_type.rb +13 -0
- data/lib/stairwell/types/date_time_type.rb +9 -0
- data/lib/stairwell/types/date_type.rb +9 -0
- data/lib/stairwell/types/float_type.rb +9 -0
- data/lib/stairwell/types/in_type.rb +28 -0
- data/lib/stairwell/types/integer_type.rb +9 -0
- data/lib/stairwell/types/null_type.rb +9 -0
- data/lib/stairwell/types/string_type.rb +9 -0
- data/lib/stairwell/types/table_name_type.rb +13 -0
- data/lib/stairwell/version.rb +1 -1
- data/lib/stairwell.rb +21 -4
- data/stairwell.gemspec +7 -0
- data/test.db +0 -0
- metadata +44 -7
- data/lib/stairwell/core_extensions/core.rb +0 -77
- data/lib/stairwell/core_extensions/types.rb +0 -7
- data/lib/stairwell/type_validator.rb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e963ad4c2388946d0baae50090e6f3e9913e49dcdd896cdd18403861d72b9a40
|
4
|
+
data.tar.gz: 29cb2a589732e6e4b0b43115da878d8b4463eb59a1ad46726d01595bc0f56f19
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d21bd2ad1fc8a8b04de7da744dae787a474a33fbb42146a4b77d218d5ee493c25ed930da39b23a4ce45a67448920924e5d2a4006ba62978422caf3c43156395
|
7
|
+
data.tar.gz: 229bc47578fea9e530d10291d79d94bcd042222e767f5627b45e4b7867af09e76958a34b9d4208b6763c1d89fcea5399317ad6c4047c547e2bae11e62361f61c
|
data/Gemfile.lock
CHANGED
@@ -1,18 +1,52 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
stairwell (0.
|
4
|
+
stairwell (0.3.0)
|
5
|
+
activerecord (>= 4.2.11)
|
6
|
+
sqlite3
|
5
7
|
|
6
8
|
GEM
|
7
9
|
remote: https://rubygems.org/
|
8
10
|
specs:
|
11
|
+
activemodel (7.1.1)
|
12
|
+
activesupport (= 7.1.1)
|
13
|
+
activerecord (7.1.1)
|
14
|
+
activemodel (= 7.1.1)
|
15
|
+
activesupport (= 7.1.1)
|
16
|
+
timeout (>= 0.4.0)
|
17
|
+
activesupport (7.1.1)
|
18
|
+
base64
|
19
|
+
bigdecimal
|
20
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
21
|
+
connection_pool (>= 2.2.5)
|
22
|
+
drb
|
23
|
+
i18n (>= 1.6, < 2)
|
24
|
+
minitest (>= 5.1)
|
25
|
+
mutex_m
|
26
|
+
tzinfo (~> 2.0)
|
27
|
+
base64 (0.1.1)
|
28
|
+
bigdecimal (3.1.4)
|
9
29
|
coderay (1.1.3)
|
30
|
+
concurrent-ruby (1.2.2)
|
31
|
+
connection_pool (2.4.1)
|
32
|
+
drb (2.1.1)
|
33
|
+
ruby2_keywords
|
34
|
+
i18n (1.14.1)
|
35
|
+
concurrent-ruby (~> 1.0)
|
10
36
|
method_source (1.0.0)
|
11
|
-
|
37
|
+
mini_portile2 (2.8.5)
|
38
|
+
minitest (5.20.0)
|
39
|
+
mutex_m (0.1.2)
|
12
40
|
pry (0.13.1)
|
13
41
|
coderay (~> 1.1)
|
14
42
|
method_source (~> 1.0)
|
15
43
|
rake (12.3.3)
|
44
|
+
ruby2_keywords (0.0.5)
|
45
|
+
sqlite3 (1.6.7)
|
46
|
+
mini_portile2 (~> 2.8.0)
|
47
|
+
timeout (0.4.0)
|
48
|
+
tzinfo (2.0.6)
|
49
|
+
concurrent-ruby (~> 1.0)
|
16
50
|
|
17
51
|
PLATFORMS
|
18
52
|
ruby
|
data/README.md
CHANGED
@@ -18,9 +18,15 @@ Or install it yourself as:
|
|
18
18
|
|
19
19
|
$ gem install stairwell
|
20
20
|
|
21
|
+
## Why?
|
22
|
+
Although ActiveRecord serves as an excellent tool for the majority of database queries, certain scenarios call for more customized queries.
|
23
|
+
This project was initially conceived to help transition a development team and their project from PHP to Ruby. This PHP project had thousands of complex SQL queries, thus the necessity of making SQL a first-class citizen in the ruby project enabled a smoother transition.
|
24
|
+
So, why not Arel? Arel is a powerful tool, but it's worth noting that it is considered a private API and is likely to remain so for the forseeable future.
|
25
|
+
Does this approach make queries less composable? Yes, if you are used to chaining your arel queries and AR scopes then you're probably not going to use this. However, it provides an interface that enables you to leverage SQL securely in your Ruby projects without the need to reinvent the wheel.
|
26
|
+
|
21
27
|
## Usage
|
22
28
|
|
23
|
-
Define a class in your app that inherits from `Stairwell::Query`. We're going to assume you are in a rails app, but this will work in any ruby app, ActiveRecord is
|
29
|
+
Define a class in your app that inherits from `Stairwell::Query`. We're going to assume you are in a rails app, but this will work in any ruby app, although ActiveRecord is a dependency of this gem.
|
24
30
|
In rails you could create a directory called `app/queries` for instance.
|
25
31
|
|
26
32
|
Define your `validate_type`, which will be the arguments you send in, and their type. For instance, if your query looks like this: `SELECT * FROM users WHERE name = :name`, and name is a `String`, your `validate_type` will look like this `validate_type :name, :string`, and you'll pass in a hash of your binds like this: `{ name: "<name value>" }`
|
@@ -34,6 +40,7 @@ class UsersSql < Stairwell::Query
|
|
34
40
|
validate_type :gpa, :float
|
35
41
|
validate_type :date_joined, :sql_date
|
36
42
|
validate_type :created_at, :sql_date_time
|
43
|
+
validate_type :favorite_numbers, [:integer]
|
37
44
|
|
38
45
|
query <<-SQL
|
39
46
|
SELECT
|
@@ -45,6 +52,7 @@ class UsersSql < Stairwell::Query
|
|
45
52
|
AND gpa = :gpa
|
46
53
|
AND date_joined = :date_joined
|
47
54
|
AND created_at >= :created_at
|
55
|
+
AND favorite_numbers IN (:favorite_numbers)
|
48
56
|
;
|
49
57
|
SQL
|
50
58
|
end
|
@@ -55,9 +63,10 @@ binds = {
|
|
55
63
|
name: "First",
|
56
64
|
age: 99,
|
57
65
|
active: true,
|
58
|
-
gpa: 4.2
|
66
|
+
gpa: 4.2,
|
59
67
|
date_joined: "2008-08-28",
|
60
68
|
created_at: "2008-08-28 23:41:18",
|
69
|
+
favorite_numbers: [4, 7, 100]
|
61
70
|
}
|
62
71
|
|
63
72
|
# and call the following:
|
@@ -66,23 +75,33 @@ UsersSql.sql(binds)
|
|
66
75
|
|
67
76
|
# You will receive the following result:
|
68
77
|
|
69
|
-
"SELECT * FROM users WHERE name = 'First' age = 99 active = TRUE date_joined = '2008-08-28' created_at
|
78
|
+
"SELECT * FROM users WHERE name = 'First' AND age = 99 AND active = TRUE AND date_joined = '2008-08-28' AND created_at >= '2008-08-28 23:41:18' AND gpa = 4.2 AND favorite_numbers IN (4, 7, 100) ;"
|
70
79
|
```
|
71
80
|
|
72
81
|
Binds passed in are validated against the validate_type, so if you have a validate_type you must include that value in your binds hash.
|
73
82
|
They types of the binds are validated too.
|
74
83
|
The names binds in your sql are also validated.
|
75
|
-
|
76
|
-
|
77
|
-
|
84
|
+
All types are quoted using ActiveRecord quoting, which will be different depending on your database type (Mysql, postgres etc.)
|
85
|
+
|
86
|
+
## Supported Types
|
87
|
+
|
88
|
+
| Type | Values Accepted | Info |
|
89
|
+
|--------------|----------------------|------------------------------------------------------------------------------------------------------|
|
90
|
+
| :boolean | TrueClass/FalseClass | Not fully supported since many databases require 'IS TRUE' or 'IS FALSE' |
|
91
|
+
| :column_name | String | for quoting a column name |
|
92
|
+
| :date_time | String | only taking the actual string for now |
|
93
|
+
| :date | String | only taking the actual string for now |
|
94
|
+
| :float | Float | |
|
95
|
+
| [<type>] | Array | will quote any type provided in the array [:integer] |
|
96
|
+
| :integer | Integer | |
|
97
|
+
| :null | NilClass | nil/NULL values are not completely supported since many databases require 'IS NULL' or 'IS NOT NULL' |
|
98
|
+
| :string | String | |
|
99
|
+
| :table_name | String | for quoting a table name |
|
78
100
|
|
79
101
|
## Known issues
|
80
102
|
|
81
|
-
* nil/NULL values are not
|
103
|
+
* nil/NULL values are not completely supported, since many databases require `IS NULL`, or `IS NOT NULL`, you can use the null_type here, but it will only accept `nil`, and it will possibly not support what you're trying to do. YMMV.
|
82
104
|
* Date/Datetime are not validated for their format, it is expected that you will pass the correct format.
|
83
|
-
* Datetime in postgres is not currently working for equality, only for `>` or `<` or `>=` or `<=`
|
84
|
-
* Column/table quoting is not currently available.
|
85
|
-
* `IN` statements with arrays support is forthcoming.
|
86
105
|
|
87
106
|
|
88
107
|
## Development
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Stairwell
|
2
2
|
class BindTransformer
|
3
3
|
|
4
|
-
attr_accessor :sql, :bind_hash, :depleting_bind_hash
|
4
|
+
attr_accessor :sql, :bind_hash, :depleting_bind_hash, :converted_sql
|
5
5
|
|
6
6
|
def initialize(sql, bind_hash)
|
7
7
|
@sql = sql
|
@@ -18,26 +18,29 @@ module Stairwell
|
|
18
18
|
# with quoted values to ensure safety.
|
19
19
|
# Note: $2 is The match for the first, second, etc. parenthesized groups in the last regex
|
20
20
|
def transform
|
21
|
-
|
21
|
+
convert_sql
|
22
|
+
validate_bind_hash
|
23
|
+
converted_sql
|
24
|
+
end
|
25
|
+
|
26
|
+
def convert_sql
|
27
|
+
@converted_sql ||= sql.gsub(/(:?):([a-zA-Z]\w*)/) do |_|
|
22
28
|
replace = $2.to_sym
|
23
29
|
validate_sql(replace)
|
24
|
-
bind_hash[replace].
|
30
|
+
bind_hash[replace].quote
|
25
31
|
end
|
26
|
-
|
27
|
-
validate_bind_hash
|
28
|
-
converted_sql
|
29
32
|
end
|
30
33
|
|
31
34
|
private
|
32
35
|
|
33
36
|
def validate_sql(attr)
|
34
|
-
raise SqlBindMismatch, ":#{attr} in your query is missing from your
|
37
|
+
raise SqlBindMismatch, ":#{attr} in your query is missing from your args" unless bind_hash[attr]
|
35
38
|
|
36
39
|
depleting_bind_hash.delete(attr)
|
37
40
|
end
|
38
41
|
|
39
42
|
def validate_bind_hash
|
40
|
-
raise SqlBindMismatch, "
|
43
|
+
raise SqlBindMismatch, ":#{depleting_bind_hash.keys.join(', ')} in your bind hash is missing from your query: #{sql}" unless depleting_bind_hash.empty?
|
41
44
|
end
|
42
45
|
|
43
46
|
end
|
data/lib/stairwell/query.rb
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
require "stairwell/bind_transformer"
|
2
|
+
require "stairwell/types/boolean_type"
|
3
|
+
require "stairwell/types/column_name_type"
|
4
|
+
require "stairwell/types/date_time_type"
|
5
|
+
require "stairwell/types/date_type"
|
6
|
+
require "stairwell/types/float_type"
|
7
|
+
require "stairwell/types/integer_type"
|
8
|
+
require "stairwell/types/in_type"
|
9
|
+
require "stairwell/types/string_type"
|
10
|
+
require "stairwell/types/null_type"
|
11
|
+
require "stairwell/types/table_name_type"
|
12
|
+
|
1
13
|
module Stairwell
|
2
14
|
class Query
|
3
15
|
|
@@ -26,10 +38,15 @@ module Stairwell
|
|
26
38
|
|
27
39
|
bind_hash.each do |bind_name, bind_value|
|
28
40
|
type = all_validations[bind_name]
|
29
|
-
|
30
|
-
|
41
|
+
if type.is_a?(Array)
|
42
|
+
type = type.first
|
43
|
+
type_object = Types::InType.new(bind_value, type)
|
44
|
+
end
|
45
|
+
type_object ||= Object.const_get(TYPE_CLASSES[type]).new(bind_value)
|
46
|
+
|
47
|
+
raise InvalidBindType.new("#{bind_name} is not #{all_validations[bind_name]}") unless type_object.valid?
|
31
48
|
|
32
|
-
|
49
|
+
bind_hash[bind_name] = type_object
|
33
50
|
end
|
34
51
|
end
|
35
52
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Stairwell::Types
|
2
|
+
class BaseType
|
3
|
+
attr_reader :value
|
4
|
+
|
5
|
+
def initialize(value)
|
6
|
+
@value = value
|
7
|
+
end
|
8
|
+
|
9
|
+
def quote
|
10
|
+
connection.quote(value)
|
11
|
+
end
|
12
|
+
|
13
|
+
def connection
|
14
|
+
@connection ||= ActiveRecord::Base.connection
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "stairwell/types/base_type"
|
2
|
+
|
3
|
+
module Stairwell::Types
|
4
|
+
class InType
|
5
|
+
attr_reader :value, :type
|
6
|
+
|
7
|
+
def initialize(value, type)
|
8
|
+
@value = value
|
9
|
+
@type = type
|
10
|
+
end
|
11
|
+
|
12
|
+
def quote
|
13
|
+
contained_values.map(&:quote).join(", ")
|
14
|
+
end
|
15
|
+
|
16
|
+
def valid?
|
17
|
+
value.is_a?(Array) && contained_values.all?(&:valid?)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def contained_values
|
23
|
+
value.map do |contained|
|
24
|
+
Object.const_get(Stairwell::TYPE_CLASSES[type]).new(contained)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/stairwell/version.rb
CHANGED
data/lib/stairwell.rb
CHANGED
@@ -1,14 +1,31 @@
|
|
1
|
+
require "active_record"
|
1
2
|
require "date"
|
2
|
-
require "stairwell/bind_transformer"
|
3
3
|
require "stairwell/query"
|
4
|
-
require "stairwell/type_validator"
|
5
4
|
require "stairwell/version"
|
6
|
-
require "stairwell/core_extensions/core"
|
7
|
-
require "stairwell/core_extensions/types"
|
8
5
|
|
9
6
|
module Stairwell
|
10
7
|
class Error < StandardError; end
|
11
8
|
class InvalidBindType < StandardError; end
|
12
9
|
class InvalidBindCount < StandardError; end
|
13
10
|
class SqlBindMismatch < StandardError; end
|
11
|
+
|
12
|
+
TYPE_CLASSES = {
|
13
|
+
string: "Stairwell::Types::StringType",
|
14
|
+
integer: "Stairwell::Types::IntegerType",
|
15
|
+
boolean: "Stairwell::Types::BooleanType",
|
16
|
+
float: "Stairwell::Types::FloatType",
|
17
|
+
date: "Stairwell::Types::DateType",
|
18
|
+
date_time: "Stairwell::Types::DateTimeType",
|
19
|
+
null: "Stairwell::Types::NullType",
|
20
|
+
column_name: "Stairwell::Types::ColumnNameType",
|
21
|
+
table_name: "Stairwell::Types::TableNameType"
|
22
|
+
}.freeze
|
23
|
+
|
24
|
+
# for development and testing
|
25
|
+
unless defined?(Rails)
|
26
|
+
ActiveRecord::Base.establish_connection(
|
27
|
+
adapter: 'sqlite3',
|
28
|
+
database: 'test.db'
|
29
|
+
)
|
30
|
+
end
|
14
31
|
end
|
data/stairwell.gemspec
CHANGED
@@ -25,4 +25,11 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.bindir = "exe"
|
26
26
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
27
27
|
spec.require_paths = ["lib"]
|
28
|
+
|
29
|
+
spec.add_dependency 'activerecord', '>= 4.2.11'
|
30
|
+
|
31
|
+
# for development and testing
|
32
|
+
unless defined?(Rails)
|
33
|
+
spec.add_dependency 'sqlite3'
|
34
|
+
end
|
28
35
|
end
|
data/test.db
ADDED
File without changes
|
metadata
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stairwell
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- tobyond
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
11
|
+
date: 2023-10-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activerecord
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.2.11
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 4.2.11
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sqlite3
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
13
41
|
description: Sanitize and quote raw SQL for rails and any project in ruby
|
14
42
|
email:
|
15
43
|
executables: []
|
@@ -27,12 +55,21 @@ files:
|
|
27
55
|
- bin/setup
|
28
56
|
- lib/stairwell.rb
|
29
57
|
- lib/stairwell/bind_transformer.rb
|
30
|
-
- lib/stairwell/core_extensions/core.rb
|
31
|
-
- lib/stairwell/core_extensions/types.rb
|
32
58
|
- lib/stairwell/query.rb
|
33
|
-
- lib/stairwell/
|
59
|
+
- lib/stairwell/types/base_type.rb
|
60
|
+
- lib/stairwell/types/boolean_type.rb
|
61
|
+
- lib/stairwell/types/column_name_type.rb
|
62
|
+
- lib/stairwell/types/date_time_type.rb
|
63
|
+
- lib/stairwell/types/date_type.rb
|
64
|
+
- lib/stairwell/types/float_type.rb
|
65
|
+
- lib/stairwell/types/in_type.rb
|
66
|
+
- lib/stairwell/types/integer_type.rb
|
67
|
+
- lib/stairwell/types/null_type.rb
|
68
|
+
- lib/stairwell/types/string_type.rb
|
69
|
+
- lib/stairwell/types/table_name_type.rb
|
34
70
|
- lib/stairwell/version.rb
|
35
71
|
- stairwell.gemspec
|
72
|
+
- test.db
|
36
73
|
homepage: https://github.com/tobyond/stairwell
|
37
74
|
licenses:
|
38
75
|
- MIT
|
@@ -54,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
54
91
|
- !ruby/object:Gem::Version
|
55
92
|
version: '0'
|
56
93
|
requirements: []
|
57
|
-
rubygems_version: 3.
|
94
|
+
rubygems_version: 3.4.10
|
58
95
|
signing_key:
|
59
96
|
specification_version: 4
|
60
97
|
summary: stairwell for sql
|
@@ -1,77 +0,0 @@
|
|
1
|
-
class String
|
2
|
-
def squish!
|
3
|
-
gsub!(/[[:space:]]+/, " ")
|
4
|
-
strip!
|
5
|
-
self
|
6
|
-
end
|
7
|
-
|
8
|
-
def underscore
|
9
|
-
self.gsub(/::/, '/').
|
10
|
-
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
11
|
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
12
|
-
tr("-", "_").
|
13
|
-
downcase
|
14
|
-
end
|
15
|
-
|
16
|
-
def sql_quote
|
17
|
-
"'#{self.gsub('\\', '\&\&').gsub("'", "''")}'"
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
class TrueClass
|
22
|
-
def sql_quote
|
23
|
-
"TRUE"
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
class FalseClass
|
28
|
-
def sql_quote
|
29
|
-
"FALSE"
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
class NilClass
|
34
|
-
def sql_quote
|
35
|
-
"IS NULL"
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
class Integer
|
40
|
-
def sql_quote
|
41
|
-
self
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
class Float
|
46
|
-
def sql_quote
|
47
|
-
self
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
class Array
|
52
|
-
def sql_quote
|
53
|
-
map(&:sql_quote).join(", ")
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
class Date
|
58
|
-
def self.parsable?(string)
|
59
|
-
begin
|
60
|
-
parse(string)
|
61
|
-
true
|
62
|
-
rescue ArgumentError
|
63
|
-
false
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
class DateTime
|
69
|
-
def self.parsable?(string)
|
70
|
-
begin
|
71
|
-
parse(string)
|
72
|
-
true
|
73
|
-
rescue ArgumentError
|
74
|
-
false
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
require "stairwell/core_extensions/core"
|
2
|
-
require "stairwell/core_extensions/types"
|
3
|
-
|
4
|
-
module Stairwell
|
5
|
-
class TypeValidator
|
6
|
-
|
7
|
-
class << self
|
8
|
-
TYPES = [
|
9
|
-
String,
|
10
|
-
Boolean,
|
11
|
-
Integer,
|
12
|
-
Float,
|
13
|
-
SqlDate,
|
14
|
-
SqlDateTime
|
15
|
-
].freeze
|
16
|
-
|
17
|
-
TYPES.each do |type|
|
18
|
-
define_method(type.to_s.underscore.to_sym) do |arg|
|
19
|
-
return arg.is_a?(type) unless arg.is_a?(Array)
|
20
|
-
arg.all? { |element| element.is_a?(type) }
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|