dwh 0.1.0
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 +7 -0
- data/.rubocop.yml +36 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE +21 -0
- data/README.md +130 -0
- data/Rakefile +42 -0
- data/docs/DWH/Adapters/Adapter.html +3053 -0
- data/docs/DWH/Adapters/Athena.html +1704 -0
- data/docs/DWH/Adapters/Boolean.html +121 -0
- data/docs/DWH/Adapters/Druid.html +1626 -0
- data/docs/DWH/Adapters/DuckDb.html +2012 -0
- data/docs/DWH/Adapters/MySql.html +1704 -0
- data/docs/DWH/Adapters/OpenAuthorizable/ClassMethods.html +265 -0
- data/docs/DWH/Adapters/OpenAuthorizable.html +1102 -0
- data/docs/DWH/Adapters/Postgres.html +2000 -0
- data/docs/DWH/Adapters/Snowflake.html +1662 -0
- data/docs/DWH/Adapters/SqlServer.html +2084 -0
- data/docs/DWH/Adapters/Trino.html +1835 -0
- data/docs/DWH/Adapters.html +129 -0
- data/docs/DWH/AuthenticationError.html +142 -0
- data/docs/DWH/Behaviors.html +767 -0
- data/docs/DWH/Capabilities.html +748 -0
- data/docs/DWH/Column.html +1115 -0
- data/docs/DWH/ConfigError.html +143 -0
- data/docs/DWH/ConnectionError.html +143 -0
- data/docs/DWH/DWHError.html +138 -0
- data/docs/DWH/ExecutionError.html +143 -0
- data/docs/DWH/Factory.html +1133 -0
- data/docs/DWH/Functions/Arrays.html +505 -0
- data/docs/DWH/Functions/Dates.html +1644 -0
- data/docs/DWH/Functions/ExtractDatePart.html +804 -0
- data/docs/DWH/Functions/Nulls.html +377 -0
- data/docs/DWH/Functions.html +846 -0
- data/docs/DWH/Logger.html +258 -0
- data/docs/DWH/OAuthError.html +138 -0
- data/docs/DWH/Settings.html +658 -0
- data/docs/DWH/StreamingStats.html +804 -0
- data/docs/DWH/Table.html +1260 -0
- data/docs/DWH/TableStats.html +583 -0
- data/docs/DWH/TokenExpiredError.html +142 -0
- data/docs/DWH/UnsupportedCapability.html +135 -0
- data/docs/DWH.html +220 -0
- data/docs/_index.html +471 -0
- data/docs/class_list.html +54 -0
- data/docs/css/common.css +1 -0
- data/docs/css/full_list.css +58 -0
- data/docs/css/style.css +503 -0
- data/docs/file.README.html +210 -0
- data/docs/file.adapters.html +514 -0
- data/docs/file.creating-adapters.html +497 -0
- data/docs/file.getting-started.html +288 -0
- data/docs/file.usage.html +446 -0
- data/docs/file_list.html +79 -0
- data/docs/frames.html +22 -0
- data/docs/guides/adapters.md +445 -0
- data/docs/guides/creating-adapters.md +430 -0
- data/docs/guides/getting-started.md +225 -0
- data/docs/guides/usage.md +378 -0
- data/docs/index.html +210 -0
- data/docs/js/app.js +344 -0
- data/docs/js/full_list.js +242 -0
- data/docs/js/jquery.js +4 -0
- data/docs/method_list.html +2038 -0
- data/docs/top-level-namespace.html +110 -0
- data/lib/dwh/adapters/athena.rb +359 -0
- data/lib/dwh/adapters/druid.rb +267 -0
- data/lib/dwh/adapters/duck_db.rb +235 -0
- data/lib/dwh/adapters/my_sql.rb +235 -0
- data/lib/dwh/adapters/open_authorizable.rb +215 -0
- data/lib/dwh/adapters/postgres.rb +250 -0
- data/lib/dwh/adapters/snowflake.rb +489 -0
- data/lib/dwh/adapters/sql_server.rb +257 -0
- data/lib/dwh/adapters/trino.rb +213 -0
- data/lib/dwh/adapters.rb +363 -0
- data/lib/dwh/behaviors.rb +67 -0
- data/lib/dwh/capabilities.rb +39 -0
- data/lib/dwh/column.rb +79 -0
- data/lib/dwh/errors.rb +29 -0
- data/lib/dwh/factory.rb +125 -0
- data/lib/dwh/functions/arrays.rb +42 -0
- data/lib/dwh/functions/dates.rb +162 -0
- data/lib/dwh/functions/extract_date_part.rb +70 -0
- data/lib/dwh/functions/nulls.rb +31 -0
- data/lib/dwh/functions.rb +86 -0
- data/lib/dwh/logger.rb +50 -0
- data/lib/dwh/settings/athena.yml +77 -0
- data/lib/dwh/settings/base.yml +81 -0
- data/lib/dwh/settings/databricks.yml +51 -0
- data/lib/dwh/settings/druid.yml +59 -0
- data/lib/dwh/settings/duckdb.yml +44 -0
- data/lib/dwh/settings/mysql.yml +67 -0
- data/lib/dwh/settings/postgres.yml +30 -0
- data/lib/dwh/settings/redshift.yml +52 -0
- data/lib/dwh/settings/snowflake.yml +45 -0
- data/lib/dwh/settings/sqlserver.yml +80 -0
- data/lib/dwh/settings/trino.yml +77 -0
- data/lib/dwh/settings.rb +79 -0
- data/lib/dwh/streaming_stats.rb +69 -0
- data/lib/dwh/table.rb +105 -0
- data/lib/dwh/table_stats.rb +51 -0
- data/lib/dwh/version.rb +5 -0
- data/lib/dwh.rb +54 -0
- data/sig/dwh.rbs +4 -0
- metadata +231 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
module DWH
|
2
|
+
module Functions
|
3
|
+
# Operations on array columns. Mostly used in where clauses
|
4
|
+
module Arrays
|
5
|
+
# Generates sql test to see if any values from the passed
|
6
|
+
# in list is in the array column/exp.
|
7
|
+
#
|
8
|
+
# @param exp [String] - sql expression
|
9
|
+
# @param list [String] - comma separated list
|
10
|
+
# @raise UnsupportedCapability if the db doesn't support array functions.
|
11
|
+
def array_in_list(exp, list)
|
12
|
+
raise UnsupportedCapability unless supports_array_functions?
|
13
|
+
|
14
|
+
gsk(:array_in_list).gsub(/@exp/i, exp).gsub(/@list/i, list)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Generates sql test to see if any values from the passed
|
18
|
+
# in list is NOT in the array column/exp.
|
19
|
+
#
|
20
|
+
# @param exp [String] - sql expression
|
21
|
+
# @param list [String] - comma separated list
|
22
|
+
# @raise UnsupportedCapability if the db doesn't support array functions.
|
23
|
+
def array_exclude_list(exp, list)
|
24
|
+
raise UnsupportedCapability unless supports_array_functions?
|
25
|
+
|
26
|
+
gsk(:array_exclude_list).gsub(/@exp/i, exp).gsub(/@list/i, list)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Explode an array. This should be used in a join expression.
|
30
|
+
# @param exp [String] the column/expression that will be Explode
|
31
|
+
# @param table_alias [String] the alias of the exploded array
|
32
|
+
# @raise UnsupportedCapability if the db doesn't support array functions.
|
33
|
+
def array_unnest_join(exp, table_alias)
|
34
|
+
raise UnsupportedCapability unless supports_array_functions?
|
35
|
+
|
36
|
+
gsk(:array_unnest_join)
|
37
|
+
.gsub(/@exp/i, exp)
|
38
|
+
.gsub(/@alias/i, table_alias)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
module DWH
|
2
|
+
module Functions
|
3
|
+
# Standard date functions except for those dealing with extracting
|
4
|
+
# a date part.
|
5
|
+
module Dates
|
6
|
+
# Ruby format string that is compatible for the target database.
|
7
|
+
def date_format
|
8
|
+
settings[:date_format]
|
9
|
+
end
|
10
|
+
|
11
|
+
# Ruby format string that is compatible timestamp format
|
12
|
+
# for the target db.
|
13
|
+
def date_time_format
|
14
|
+
settings[:date_time_format]
|
15
|
+
end
|
16
|
+
|
17
|
+
# Ruby format string that is compatible timestamp with timezone
|
18
|
+
# format for the target db.
|
19
|
+
def date_time_tz_format
|
20
|
+
settings[:date_time_tz_format]
|
21
|
+
end
|
22
|
+
|
23
|
+
# The native date storage type of the db.
|
24
|
+
def date_data_type
|
25
|
+
settings[:data_type]
|
26
|
+
end
|
27
|
+
|
28
|
+
# Whether the db uses an int format store dates natively
|
29
|
+
def date_int?
|
30
|
+
date_data_type =~ /int/i
|
31
|
+
end
|
32
|
+
|
33
|
+
# The native function to return current date
|
34
|
+
def current_date
|
35
|
+
settings[:current_date]
|
36
|
+
end
|
37
|
+
|
38
|
+
# The native function to return current time
|
39
|
+
def current_time
|
40
|
+
settings[:current_time]
|
41
|
+
end
|
42
|
+
|
43
|
+
# The native function to return current timestamp
|
44
|
+
def current_timestamp
|
45
|
+
settings[:current_timestamp]
|
46
|
+
end
|
47
|
+
|
48
|
+
TIMESTAMPABLE_UNITS = %w[millisecond second minute hour].freeze
|
49
|
+
|
50
|
+
# Given a date expression, truncate it to a given level.
|
51
|
+
# The SQL output of a truncation is still date or timestamp.
|
52
|
+
#
|
53
|
+
# @param unit [String] the unit to truncate to
|
54
|
+
# @param exp [String] the expression to truncate
|
55
|
+
#
|
56
|
+
# @example Truncate date to the week start day
|
57
|
+
# truncate_date('week', 'my_date_col')
|
58
|
+
# Postgres ==> DATE_TRUNC('week', 'my_date_col')
|
59
|
+
# SQL Server ==> DATETRUNC(week, 'my_date_col')
|
60
|
+
#
|
61
|
+
# @note When truncating a literal date rather than an
|
62
|
+
# expression, the date_literal function should be called on
|
63
|
+
# it first. e.g. truncate_date('week', date_lit('2025-08-06'))
|
64
|
+
# For many dbs it won't matter, but some require date literals
|
65
|
+
# to be specified.
|
66
|
+
def truncate_date(unit, exp)
|
67
|
+
unit = unit.strip.downcase
|
68
|
+
res = if unit == 'week' && adjust_week_start_day?
|
69
|
+
gsk("#{settings[:week_start_day].downcase}_week_start_day")
|
70
|
+
.gsub(/@exp/i, exp)
|
71
|
+
else
|
72
|
+
gsk(:truncate_date)
|
73
|
+
.gsub(/@unit/i, unit)
|
74
|
+
.gsub(/@exp/i, exp)
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
# If we are truncating above the timestamp level ie days, years etc
|
79
|
+
# then we can cast the result to date
|
80
|
+
if TIMESTAMPABLE_UNITS.include?(unit)
|
81
|
+
res
|
82
|
+
else
|
83
|
+
cast(res, 'DATE')
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Add some interval of time to a given date expression.
|
88
|
+
# @param unit [String] the units we are adding i.e day, month, week etc
|
89
|
+
# @param val [Integer] the number of said units
|
90
|
+
# @param exp [String] the target expression being operated on
|
91
|
+
def date_add(unit, val, exp)
|
92
|
+
gsk(:date_add)
|
93
|
+
.gsub(/@unit/i, unit)
|
94
|
+
.gsub(/@val/i, val.to_s)
|
95
|
+
.gsub(/@exp/i, exp)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Differnect between two dates in terms of the given unit.
|
99
|
+
# @param unit [String] i.e day, month, hour etc
|
100
|
+
# @param start_exp [String] starting date expression
|
101
|
+
# @param end_exp [String] ending date expression
|
102
|
+
def date_diff(unit, start_exp, end_exp)
|
103
|
+
gsk(:date_diff)
|
104
|
+
.gsub(/@unit/i, unit)
|
105
|
+
.gsub(/@start_exp/i, start_exp)
|
106
|
+
.gsub(/@end_exp/i, end_exp)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Applies the given format to the target date expression
|
110
|
+
def date_format_sql(exp, format)
|
111
|
+
gsk(:date_format_sql)
|
112
|
+
.gsub(/@exp/i, exp)
|
113
|
+
.gsub(/@format/i, format)
|
114
|
+
end
|
115
|
+
|
116
|
+
DATE_CLASSES = [Date, DateTime, Time].freeze
|
117
|
+
|
118
|
+
# Generates a valid date literal string. Most db's
|
119
|
+
# this is just single quoted value while others require
|
120
|
+
# a date declaration.
|
121
|
+
# @param val [String, Date, DateTime, Time]
|
122
|
+
def date_literal(val)
|
123
|
+
val = DATE_CLASSES.include?(val.class) ? val.strftime(date_format) : val
|
124
|
+
gsk(:date_literal).gsub(/@val/i, val)
|
125
|
+
end
|
126
|
+
|
127
|
+
# @param val [String, Date, DateTime, Time]
|
128
|
+
def date_time_literal(val)
|
129
|
+
val = DATE_CLASSES.include?(val.class) ? val.strftime(date_time_format) : val
|
130
|
+
gsk(:date_time_literal).gsub(/@val/i, val)
|
131
|
+
end
|
132
|
+
|
133
|
+
# The current default week start day. This is how
|
134
|
+
# the db is currently setup. Should be either monday or sunday
|
135
|
+
def default_week_start_day
|
136
|
+
gsk(:default_week_start_day)
|
137
|
+
end
|
138
|
+
|
139
|
+
# The desired week start day. Could be diff from the db setting.
|
140
|
+
def week_start_day
|
141
|
+
gsk(:week_start_day)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Whether we need to adjust the week start day. If its different
|
145
|
+
# from the default, we need to adjust
|
146
|
+
def adjust_week_start_day?
|
147
|
+
week_start_day.strip != default_week_start_day.strip
|
148
|
+
end
|
149
|
+
|
150
|
+
# Apply translation to desired week start day
|
151
|
+
def adjust_week_start_day(exp)
|
152
|
+
gsk("#{settings[:week_start_day].downcase}_week_start_day")
|
153
|
+
.gsub(/@exp/i, exp)
|
154
|
+
end
|
155
|
+
|
156
|
+
# Does the week start on sunday?
|
157
|
+
def week_starts_on_sunday?
|
158
|
+
gsk(:week_start_day) == 'SUNDAY'
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module DWH
|
2
|
+
module Functions
|
3
|
+
# All date functions related to extracting part of date
|
4
|
+
# from a date or timestamp.
|
5
|
+
module ExtractDatePart
|
6
|
+
def extract_year(exp)
|
7
|
+
gsk(:extract_year).gsub(/@exp/i, exp)
|
8
|
+
end
|
9
|
+
|
10
|
+
def extract_month(exp)
|
11
|
+
gsk(:extract_month).gsub(/@exp/i, exp)
|
12
|
+
end
|
13
|
+
|
14
|
+
def extract_quarter(exp)
|
15
|
+
gsk(:extract_quarter).gsub(/@exp/i, exp)
|
16
|
+
end
|
17
|
+
|
18
|
+
def extract_day_of_year(exp)
|
19
|
+
gsk(:extract_day_of_year).gsub(/@exp/i, exp)
|
20
|
+
end
|
21
|
+
|
22
|
+
def extract_day_of_month(exp)
|
23
|
+
gsk(:extract_day_of_month).gsub(/@exp/i, exp)
|
24
|
+
end
|
25
|
+
|
26
|
+
def extract_day_of_week(exp)
|
27
|
+
gsk(:extract_day_of_week).gsub(/@exp/i, exp)
|
28
|
+
end
|
29
|
+
|
30
|
+
def extract_week_of_year(exp)
|
31
|
+
gsk(:extract_week_of_year).gsub(/@exp/i, exp)
|
32
|
+
end
|
33
|
+
|
34
|
+
def extract_hour(exp)
|
35
|
+
gsk(:extract_hour).gsub(/@exp/i, exp)
|
36
|
+
end
|
37
|
+
|
38
|
+
def extract_minute(exp)
|
39
|
+
gsk(:extract_minute).gsub(/@exp/i, exp)
|
40
|
+
end
|
41
|
+
|
42
|
+
def extract_year_month(exp)
|
43
|
+
gsk(:extract_year_month).gsub(/@exp/i, exp)
|
44
|
+
end
|
45
|
+
|
46
|
+
def extract_day_name(exp, abbreviate: false)
|
47
|
+
upper_case(
|
48
|
+
if abbreviate
|
49
|
+
date_format_sql(exp,
|
50
|
+
gsk(:abbreviated_day_name_format))
|
51
|
+
else
|
52
|
+
date_format_sql(exp, gsk(:day_name_format))
|
53
|
+
end
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
def extract_month_name(exp, abbreviate: false)
|
58
|
+
upper_case(
|
59
|
+
if abbreviate
|
60
|
+
date_format_sql(exp,
|
61
|
+
gsk(:abbreviated_month_name_format))
|
62
|
+
else
|
63
|
+
date_format_sql(exp,
|
64
|
+
gsk(:month_name_format))
|
65
|
+
end
|
66
|
+
)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module DWH
|
2
|
+
module Functions
|
3
|
+
# Manages translations to Null handling Functions
|
4
|
+
module Nulls
|
5
|
+
# If the provided expression is null
|
6
|
+
# then return the second expression.
|
7
|
+
# @param exp [String] - target expression
|
8
|
+
# @param exp_if_null [String] - exp if target is null
|
9
|
+
def if_null(exp, exp_if_null)
|
10
|
+
gsk(:if_null)
|
11
|
+
.sub(/@exp/i, exp.to_s)
|
12
|
+
.sub(/@when_null/i, exp_if_null.to_s)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns Null if the given expression
|
16
|
+
# equals the target expression.
|
17
|
+
def null_if(exp, target_exp)
|
18
|
+
gsk(:null_if)
|
19
|
+
.sub(/@exp/i, exp.to_s)
|
20
|
+
.sub(/@target/i, target_exp.to_s)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns Null if the given expression
|
24
|
+
# evaluates to zero.
|
25
|
+
def null_if_zero(exp)
|
26
|
+
gsk(:null_if_zero)
|
27
|
+
.sub(/@exp/i, exp.to_s)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require_relative 'functions/dates'
|
2
|
+
require_relative 'functions/extract_date_part'
|
3
|
+
require_relative 'functions/nulls'
|
4
|
+
require_relative 'functions/arrays'
|
5
|
+
|
6
|
+
module DWH
|
7
|
+
# The Functions module adds a translation layer between this library
|
8
|
+
# and native database functions. It relies on the adapters settings
|
9
|
+
# file to map standard function to its native counterpart.
|
10
|
+
#
|
11
|
+
# @example Truncate date to the week start day
|
12
|
+
# truncate_date('week', 'my_date_col')
|
13
|
+
# Postgres ==> DATE_TRUNC('week', 'my_date_col')
|
14
|
+
# SQL Server ==> DATETRUNC(week, 'my_date_col')
|
15
|
+
#
|
16
|
+
# @example Output a date string as a valid date literal
|
17
|
+
# date_literal('2025-08-06')
|
18
|
+
# Postgres ==> '2025-08-06'::DATE
|
19
|
+
# SQL Server ==> '2025-08-06'
|
20
|
+
module Functions
|
21
|
+
include Dates
|
22
|
+
include ExtractDatePart
|
23
|
+
include Nulls
|
24
|
+
include Arrays
|
25
|
+
|
26
|
+
# Casts an expresion/literal to the target datatype.
|
27
|
+
# Datatype should be valid for the target db.
|
28
|
+
#
|
29
|
+
# @param exp [String] sql expression
|
30
|
+
# @param type [String] valid type for target db
|
31
|
+
def cast(exp, type)
|
32
|
+
gsk(:cast).gsub(/@exp/i, exp)
|
33
|
+
.gsub(/@type/i, type)
|
34
|
+
end
|
35
|
+
|
36
|
+
def trim(exp)
|
37
|
+
gsk(:trim).gsub(/@exp/i, exp)
|
38
|
+
end
|
39
|
+
|
40
|
+
def lower_case(exp)
|
41
|
+
gsk(:lower_case).gsub(/@exp/i, exp)
|
42
|
+
end
|
43
|
+
|
44
|
+
def upper_case(exp)
|
45
|
+
gsk(:upper_case).gsub(/@exp/i, exp)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Applies adapter specific quotes around the given
|
49
|
+
# expression. The expression is usually a column name, alias,
|
50
|
+
# or table alias.
|
51
|
+
#
|
52
|
+
# @param exp [String] - column, alias, table name
|
53
|
+
def quote(exp)
|
54
|
+
gsk(:quote).sub(/@exp/i, exp)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Applies adapter specific string literal translation around the given
|
58
|
+
# expression. The expression is usually a string value.
|
59
|
+
#
|
60
|
+
# @param exp [String] some string value
|
61
|
+
def string_lit(exp)
|
62
|
+
gsk(:string_literal).sub(/@exp/i, exp.gsub("'", "''"))
|
63
|
+
end
|
64
|
+
|
65
|
+
# Applies adapter specific cross join expression
|
66
|
+
# This takes the target table. Ie if you are joining
|
67
|
+
# table a with table b.. You will pass in the table b
|
68
|
+
# name expression here.
|
69
|
+
#
|
70
|
+
# @example
|
71
|
+
# adapter.cross_join("schema.table_b")
|
72
|
+
#
|
73
|
+
# @param relation [String] - table name or table exp
|
74
|
+
def cross_join(relation)
|
75
|
+
gsk(:cross_join).sub(/@relation/i, relation)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Shortcut to get settings value
|
79
|
+
# by key.
|
80
|
+
# @param key [Symbol,String]
|
81
|
+
# @return [String] upcased value
|
82
|
+
def gsk(key)
|
83
|
+
settings[key.to_sym]
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/dwh/logger.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module DWH
|
4
|
+
# Access a default logger for the gem.
|
5
|
+
module Logger
|
6
|
+
def logger
|
7
|
+
DWH::Logger.logger
|
8
|
+
end
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def logger
|
12
|
+
@logger ||= create_logger
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def create_logger
|
18
|
+
if rails_logger_available?
|
19
|
+
Rails.logger
|
20
|
+
else
|
21
|
+
standalone_logger
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def rails_logger_available?
|
26
|
+
defined?(Rails) && Rails.respond_to?(:logger) && Rails.logger
|
27
|
+
end
|
28
|
+
|
29
|
+
def standalone_logger
|
30
|
+
logger = ::Logger.new($stdout)
|
31
|
+
logger.level = log_level
|
32
|
+
logger.formatter = proc do |severity, datetime, _progname, msg|
|
33
|
+
"[#{datetime.strftime('%Y-%m-%d %H:%M:%S')}] #{severity} DWH: #{msg}\n"
|
34
|
+
end
|
35
|
+
logger
|
36
|
+
end
|
37
|
+
|
38
|
+
def log_level
|
39
|
+
case ENV['DWH_LOG_LEVEL']&.downcase
|
40
|
+
when 'debug' then ::Logger::DEBUG
|
41
|
+
when 'info' then ::Logger::INFO
|
42
|
+
when 'warn' then ::Logger::WARN
|
43
|
+
when 'error' then ::Logger::ERROR
|
44
|
+
when 'fatal' then ::Logger::FATAL
|
45
|
+
else ::Logger::INFO
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
|
2
|
+
# Date Literal Formats
|
3
|
+
date_format: "%Y-%m-%d"
|
4
|
+
date_time_format: "%Y-%m-%d %H:%M:%S"
|
5
|
+
date_time_tz_format: "%Y-%m-%d %H:%M:%S %Z"
|
6
|
+
date_type: "string" # alternative is int, integer, dateint
|
7
|
+
day_name_format: "%W"
|
8
|
+
abbreviated_day_name_format: "%a"
|
9
|
+
month_name_format: "%M"
|
10
|
+
abbreviated_month_name_format: "%b"
|
11
|
+
|
12
|
+
# Date functions patterns
|
13
|
+
current_date: "CURRENT_DATE"
|
14
|
+
current_time: "CURRENT_TIME"
|
15
|
+
current_timestamp: "CURRENT_TIMESTAMP"
|
16
|
+
truncate_date: "DATE_TRUNC('@unit', @exp)"
|
17
|
+
date_add: "DATE_ADD('@unit', @val, @exp)"
|
18
|
+
date_diff: "DATE_DIFF('@unit', @start_exp, @end_exp)"
|
19
|
+
date_format_sql: "DATE_FORMAT(@exp, '@format')"
|
20
|
+
date_literal: "DATE '@val'"
|
21
|
+
date_time_literal: "TIMESTAMP '@val'"
|
22
|
+
extract_year: 'YEAR(@exp)'
|
23
|
+
extract_month: 'MONTH(@exp)'
|
24
|
+
extract_quarter: 'QUARTER(@exp)'
|
25
|
+
extract_day_of_year: 'DAY_OF_YEAR(@exp)'
|
26
|
+
extract_day_of_month: 'DAY(@exp)'
|
27
|
+
extract_day_of_week: 'DAY_OF_WEEK(@exp)'
|
28
|
+
extract_week_of_year: 'WEEK(@exp)'
|
29
|
+
extract_hour: 'HOUR(@exp)'
|
30
|
+
extract_minute: 'MINUTE(@exp)'
|
31
|
+
extract_year_month: "CAST(FORMAT('%04d%02d', year(@exp), month(@exp)) AS INTEGER)"
|
32
|
+
default_week_start_day: "monday"
|
33
|
+
week_start_day: "monday"
|
34
|
+
sunday_week_start_day: "DATE_ADD('day', -1,DATE_TRUNC('week', DATE_ADD('day',1, @exp)))"
|
35
|
+
monday_week_start_day: "DATE_ADD('day', 1, DATE_TRUNC('week', DATE_ADD('day',-1, @exp)))"
|
36
|
+
|
37
|
+
cast: "CAST(@exp AS @type)"
|
38
|
+
|
39
|
+
# string functions
|
40
|
+
trim: "TRIM(@exp)"
|
41
|
+
lower_case: "LOWER(@exp)"
|
42
|
+
upper_case: "UPPER(@exp)"
|
43
|
+
|
44
|
+
# null handling
|
45
|
+
if_null: "COALESCE(@exp, @when_null)"
|
46
|
+
null_if: "NULLIF(@exp, @target)"
|
47
|
+
null_if_zero: "NULLIF(@exp, 0)"
|
48
|
+
|
49
|
+
# Relevant db capabilities for query gen
|
50
|
+
supports_array_functions: true
|
51
|
+
supports_table_join: true
|
52
|
+
supports_full_join: true
|
53
|
+
supports_cross_join: true
|
54
|
+
supports_sub_queries: true
|
55
|
+
supports_common_table_expressions: true
|
56
|
+
supports_temp_tables: true
|
57
|
+
create_temp_table_template: "CREATE TEMPORARY TABLE @table AS \n@sql"
|
58
|
+
supports_window_functions: true
|
59
|
+
extend_ending_date_to_last_hour_of_day: false # druid needs this for inclusive filtering
|
60
|
+
|
61
|
+
# array operations
|
62
|
+
array_in_list: "ANY_MATCH(@exp, x -> x IN (@list)" # list is comma separated
|
63
|
+
array_exclude_list: "NONE_MATCH(@exp, x -> x IN (@list)" # list is comma separated
|
64
|
+
array_unnest_join: "CROSS JOIN UNNEST(@exp) @alias"
|
65
|
+
|
66
|
+
# joins
|
67
|
+
cross_join: "CROSS JOIN @relation"
|
68
|
+
|
69
|
+
# sql output behavior
|
70
|
+
temp_table_type: "cte" # options cte, subquery, temp
|
71
|
+
temp_table_prefix: ""
|
72
|
+
# Determines how measures across fact universes are combined.
|
73
|
+
# Default is full join when supported.
|
74
|
+
final_pass_measure_join_type: "full" # inner left right etc
|
75
|
+
apply_advanced_filtering_on_array_projections: false # druid needs a having clause or un-nesting
|
76
|
+
greedy_apply_date_filters: true
|
77
|
+
cross_universe_measure_filtering_strategy: "both" # both, final, intermediate
|
@@ -0,0 +1,81 @@
|
|
1
|
+
|
2
|
+
# quotes and string lit
|
3
|
+
quote: "\"@exp\""
|
4
|
+
string_literal: "'@exp'"
|
5
|
+
|
6
|
+
# Date Literal Formats
|
7
|
+
date_format: "%Y-%m-%d"
|
8
|
+
date_time_format: "%Y-%m-%d %H:%M:%S"
|
9
|
+
date_time_tz_format: "%Y-%m-%d %H:%M:%S %Z"
|
10
|
+
date_type: "string" # alternative is int, integer, dateint
|
11
|
+
day_name_format: "%W"
|
12
|
+
abbreviated_day_name_format: "%a"
|
13
|
+
month_name_format: "%M"
|
14
|
+
abbreviated_month_name_format: "%b"
|
15
|
+
|
16
|
+
# Date functions patterns
|
17
|
+
current_date: "CURRENT_DATE"
|
18
|
+
current_time: "CURRENT_TIME"
|
19
|
+
current_timestamp: "CURRENT_TIMESTAMP"
|
20
|
+
truncate_date: "DATE_TRUNC('@unit', @exp)"
|
21
|
+
date_add: "DATE_ADD('@unit', @val, @exp)"
|
22
|
+
date_diff: "DATE_DIFF('@unit', @start_exp, @end_exp)"
|
23
|
+
date_format_sql: "DATE_FORMAT(@exp, '@format')"
|
24
|
+
date_literal: "'@val'"
|
25
|
+
date_time_literal: "'@val'"
|
26
|
+
extract_year: 'YEAR(@exp)'
|
27
|
+
extract_month: 'MONTH(@exp)'
|
28
|
+
extract_quarter: 'QUARTER(@exp)'
|
29
|
+
extract_day_of_year: 'DAY_OF_YEAR(@exp)'
|
30
|
+
extract_day_of_month: 'DAY(@exp)'
|
31
|
+
extract_day_of_week: 'DAY_OF_WEEK(@exp)'
|
32
|
+
extract_week_of_year: 'WEEK(@exp)'
|
33
|
+
extract_hour: 'HOUR(@exp)'
|
34
|
+
extract_minute: 'MINUTE(@exp)'
|
35
|
+
extract_year_month: 'CAST((year(@exp) || month(@exp)) as integer)'
|
36
|
+
default_week_start_day: "monday"
|
37
|
+
week_start_day: "monday"
|
38
|
+
sunday_week_start_day: "DATE_ADD('day', -1,DATE_TRUNC('week', DATE_ADD('day',1, @exp)))"
|
39
|
+
monday_week_start_day: "DATE_ADD('day', 1, DATE_TRUNC('week', DATE_ADD('day',-1, @exp)))"
|
40
|
+
|
41
|
+
cast: "CAST(@exp AS @type)"
|
42
|
+
|
43
|
+
# string functions
|
44
|
+
trim: "TRIM(@exp)"
|
45
|
+
lower_case: "LOWER(@exp)"
|
46
|
+
upper_case: "UPPER(@exp)"
|
47
|
+
|
48
|
+
# null handling
|
49
|
+
if_null: "COALESCE(@exp, @when_null)"
|
50
|
+
null_if: "NULLIF(@exp, @target)"
|
51
|
+
null_if_zero: "NULLIF(@exp, 0)"
|
52
|
+
|
53
|
+
# Relevant db capabilities for query gen
|
54
|
+
supports_array_functions: true
|
55
|
+
supports_table_join: true
|
56
|
+
supports_full_join: true
|
57
|
+
supports_cross_join: true
|
58
|
+
supports_sub_queries: true
|
59
|
+
supports_common_table_expressions: true
|
60
|
+
supports_temp_tables: true
|
61
|
+
create_temp_table_template: "CREATE TEMPORARY TABLE @table AS \n@sql"
|
62
|
+
supports_window_functions: true
|
63
|
+
extend_ending_date_to_last_hour_of_day: false # druid needs this for inclusive filtering
|
64
|
+
|
65
|
+
# array operations
|
66
|
+
array_in_list: "ANY_MATCH(@exp, x -> x IN (@list)" # list is comma separated
|
67
|
+
array_exclude_list: "NONE_MATCH(@exp, x -> x IN (@list)" # list is comma separated
|
68
|
+
array_unnest_join: "CROSS JOIN UNNEST(@exp) @alias"
|
69
|
+
|
70
|
+
# joins
|
71
|
+
cross_join: "CROSS JOIN @relation"
|
72
|
+
|
73
|
+
# sql output behavior
|
74
|
+
temp_table_type: "cte" # options cte, subquery, temp
|
75
|
+
temp_table_prefix: ""
|
76
|
+
# Determines how measures across fact universes are combined.
|
77
|
+
# Default is full join when supported.
|
78
|
+
final_pass_measure_join_type: "full" # inner left right etc
|
79
|
+
apply_advanced_filtering_on_array_projections: false # druid needs a having clause or un-nesting
|
80
|
+
greedy_apply_date_filters: true
|
81
|
+
cross_universe_measure_filtering_strategy: "both" # both, final, intermediate
|
@@ -0,0 +1,51 @@
|
|
1
|
+
|
2
|
+
# quotes and string lit
|
3
|
+
quote: "\"@exp\""
|
4
|
+
string_literal: "'@exp'"
|
5
|
+
|
6
|
+
# Date Literal Formats
|
7
|
+
date_format: "%Y-%m-%d"
|
8
|
+
date_time_format: "%Y-%m-%d %H:%M:%S"
|
9
|
+
date_time_tz_format: "%Y-%m-%d %H:%M:%S %Z"
|
10
|
+
date_type: "string" # alternative is int, integer, dateint
|
11
|
+
day_name_format: "EEEE"
|
12
|
+
abbreviated_day_name_format: "EEE"
|
13
|
+
month_name_format: "MMMM"
|
14
|
+
abbreviated_month_name_format: "MMM"
|
15
|
+
|
16
|
+
date_add: "date_add(@unit, @val, @exp)"
|
17
|
+
date_diff: "date_diff(@unit, @start_exp, @end_exp)"
|
18
|
+
date_format_sql: "date_format(@exp, '@format')"
|
19
|
+
extract_day_of_year: 'dayofyear(@exp)'
|
20
|
+
extract_day_of_week: 'dayofweek(@exp)'
|
21
|
+
extract_week_of_year: 'weekofyear(@exp)'
|
22
|
+
extract_year_month: 'cast(concat(year(@exp), lpad(month(@exp), 2, "0")) as int)'
|
23
|
+
|
24
|
+
cast: "CAST(@exp AS @type)"
|
25
|
+
|
26
|
+
# string functions
|
27
|
+
trim: "trim(@exp)"
|
28
|
+
lower_case: "lower(@exp)"
|
29
|
+
upper_case: "upper(@exp)"
|
30
|
+
|
31
|
+
# null handling
|
32
|
+
if_null: "COALESCE(@exp, @when_null)"
|
33
|
+
null_if: "NULLIF(@exp, @target)"
|
34
|
+
null_if_zero: "NULLIF(@exp, 0)"
|
35
|
+
|
36
|
+
# Relevant db capabilities for query gen
|
37
|
+
supports_table_join: true
|
38
|
+
supports_full_join: true
|
39
|
+
supports_cross_join: true
|
40
|
+
supports_sub_queries: true
|
41
|
+
supports_common_table_expressions: true
|
42
|
+
supports_temp_tables: true
|
43
|
+
create_temp_table_template: "CREATE TEMPORARY TABLE @table AS \n@sql"
|
44
|
+
supports_window_functions: true
|
45
|
+
extend_ending_date_to_last_hour_of_day: false # druid needs this for inclusive filtering
|
46
|
+
|
47
|
+
# array operations
|
48
|
+
array_in_list: "exists(@exp, x -> x IN (@list))"
|
49
|
+
array_exclude_list: "not exists(@exp, x -> x IN (@list))"
|
50
|
+
array_unnest_join: "LATERAL VIEW explode(@exp) AS @alias"
|
51
|
+
|