TimezoneParser 0.4.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 25ef86372b8861bf6e4971ca261cf3f3c4d820e63d59c242a6a9f253910ac2c2
4
- data.tar.gz: 0a858e6277137ac2cdb158dfbf82318bf0446d4818438dea1fa1702e18c48e29
3
+ metadata.gz: 3142c5391513b96c7862dc7220c1ccd85e4288366a361935054113cc22629594
4
+ data.tar.gz: 5435d8f578bebcdb8ac8cba258b0a295e6c1b9bb6e0f3c1cdd2c32146150b70f
5
5
  SHA512:
6
- metadata.gz: 36277f05b9a6334c8b838bc333422b570e3984b034cf2d0d44493123ac21e30ee5836142e951028ddb26e530af1178585f361aa756ed26735d2d4d50048a58d5
7
- data.tar.gz: 6489d950773033d0d4c1ece559051c3e8e593a0a26fde08708255d63726819b7f2ca184adeedc5f24c5af293495450d9532e11ac796d8d5190d530cd116ec9a1
6
+ metadata.gz: ea39d10652896a5a4c21dca7943f6fc03493206e5286ba06b1ca993112557cf0aa2851470681f45468f676d4740659d5f5ab69cbe9ed40a58f1d276c0d7afce4
7
+ data.tar.gz: afab3a15077508cc496337d72af6d4d9f9bcf8c86decefa64ba2cd571ba081315b46d318a93ccaa00f4c905c317a5fb77bb10a625a186ae0d3ca1de633e57533
data/.gitignore CHANGED
@@ -16,4 +16,4 @@ test/tmp
16
16
  test/version_tmp
17
17
  vendor/
18
18
  tmp
19
- /data/*.dat
19
+ /data/*.db
data/README.md CHANGED
@@ -102,7 +102,6 @@ code coverage will also be generated
102
102
  ## Code status
103
103
  [![Gem Version](https://badge.fury.io/rb/TimezoneParser.png)](http://badge.fury.io/rb/TimezoneParser)
104
104
  [![Build Status](https://travis-ci.org/davispuh/TimezoneParser.png?branch=master)](https://travis-ci.org/davispuh/TimezoneParser)
105
- [![Dependency Status](https://gemnasium.com/davispuh/TimezoneParser.png)](https://gemnasium.com/davispuh/TimezoneParser)
106
105
  [![Coverage Status](https://coveralls.io/repos/davispuh/TimezoneParser/badge.png?branch=master)](https://coveralls.io/r/davispuh/TimezoneParser?branch=master)
107
106
  [![Code Climate](https://codeclimate.com/github/davispuh/TimezoneParser.png)](https://codeclimate.com/github/davispuh/TimezoneParser)
108
107
 
data/Rakefile CHANGED
@@ -5,6 +5,7 @@ require 'yard'
5
5
  require 'yaml'
6
6
  require 'pathname'
7
7
  require 'timezone_parser/data'
8
+ require 'timezone_parser/data/exporter'
8
9
 
9
10
  desc 'Default: run specs.'
10
11
  task :default => :spec
@@ -206,10 +207,7 @@ end
206
207
 
207
208
  desc 'Export data'
208
209
  task 'export' do
209
- ['abbreviations.yaml', 'timezones.yaml', 'countries.yaml', 'metazones.yaml',
210
- 'windows_zonenames.yaml', 'windows_timezones.yaml', 'windows_offsets.yaml',
211
- 'rails.yaml', 'rails_i18n.yaml'].each do |name|
212
- path = data_location + name
213
- Marshal.dump(YAML.load_file(path), File.open(path.dirname + (path.basename('.*').to_s + '.dat'), 'wb'))
214
- end
210
+ exporter = TimezoneParser::Data::Exporter.new(data_location)
211
+ exporter.exportDatabase
215
212
  end
213
+
@@ -16,11 +16,7 @@ Gem::Specification.new do |spec|
16
16
  spec.files = `git ls-files`.split($/)
17
17
  spec.files.delete_if { |name| name[-4, 4] == '.yaml' }
18
18
  spec.files << 'data/version.yaml'
19
- ['abbreviations.dat', 'countries.dat', 'metazones.dat',
20
- 'rails.dat', 'rails_i18n.dat', 'timezones.dat',
21
- 'windows_offsets.dat', 'windows_timezones.dat', 'windows_zonenames.dat'].each do |name|
22
- spec.files << 'data/' + name
23
- end
19
+ spec.files << 'data/timezones.db'
24
20
 
25
21
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
26
22
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
@@ -28,6 +24,7 @@ Gem::Specification.new do |spec|
28
24
 
29
25
  spec.add_runtime_dependency 'tzinfo'
30
26
  spec.add_runtime_dependency 'insensitive_hash'
27
+ spec.add_runtime_dependency 'sqlite3'
31
28
 
32
29
  spec.add_development_dependency 'bundler', '>= 1.3'
33
30
  spec.add_development_dependency 'rake'
@@ -0,0 +1,164 @@
1
+
2
+ CREATE TABLE Timezones (`ID` INTEGER PRIMARY KEY,
3
+ `Name` TEXT NOT NULL COLLATE NOCASE);
4
+ CREATE UNIQUE INDEX IDX_Timezones ON Timezones (`Name`);
5
+
6
+
7
+ CREATE TABLE Territories (`ID` INTEGER PRIMARY KEY,
8
+ `Territory` TEXT NOT NULL COLLATE NOCASE);
9
+ CREATE UNIQUE INDEX IDX_Territories ON Territories (`Territory`);
10
+
11
+
12
+ CREATE TABLE TerritoryContainment (`ID` INTEGER PRIMARY KEY,
13
+ `Parent` INTEGER NOT NULL,
14
+ `Territory` INTEGER NOT NULL,
15
+ FOREIGN KEY(`Parent`) REFERENCES Territories(`ID`),
16
+ FOREIGN KEY(`Territory`) REFERENCES Territories(`ID`));
17
+ CREATE UNIQUE INDEX IDX_TerritoryContainment ON TerritoryContainment (`Parent`, `Territory`);
18
+
19
+
20
+ CREATE TABLE TimezoneTerritories (`ID` INTEGER PRIMARY KEY,
21
+ `Timezone` INTEGER NOT NULL,
22
+ `Territory` INTEGER NOT NULL,
23
+ FOREIGN KEY(`Territory`) REFERENCES Territories(`ID`));
24
+ CREATE UNIQUE INDEX IDX_TimezoneTerritories ON TimezoneTerritories (`Timezone`, `Territory`);
25
+
26
+
27
+ CREATE TABLE Locales (`ID` INTEGER PRIMARY KEY,
28
+ `Name` TEXT NOT NULL COLLATE NOCASE,
29
+ `Parent` INTEGER);
30
+ CREATE UNIQUE INDEX IDX_Locales ON Locales (`Name`);
31
+
32
+
33
+ CREATE TABLE TimezoneNames (`ID` INTEGER PRIMARY KEY,
34
+ `Locale` INTEGER NOT NULL,
35
+ `Name` TEXT NOT NULL COLLATE BINARY,
36
+ `NameLowercase` TEXT NOT NULL COLLATE NOCASE,
37
+ `Types` INTEGER,
38
+ FOREIGN KEY(`Locale`) REFERENCES Locales(`ID`));
39
+ CREATE UNIQUE INDEX IDX_TimezoneNames ON TimezoneNames (`Locale`, `Name`);
40
+ CREATE INDEX IDX_TimezoneNamesLowercase ON TimezoneNames (`NameLowercase`);
41
+
42
+
43
+ CREATE TABLE Metazones (`ID` INTEGER PRIMARY KEY,
44
+ `Name` TEXT NOT NULL COLLATE NOCASE);
45
+ CREATE UNIQUE INDEX IDX_Metazones ON Metazones (`Name`);
46
+
47
+
48
+ CREATE TABLE MetazonePeriods (`ID` INTEGER PRIMARY KEY,
49
+ `Metazone` INTEGER NOT NULL,
50
+ `From` TEXT,
51
+ `To` TEXT,
52
+ FOREIGN KEY(`Metazone`) REFERENCES Metazones(`ID`));
53
+ CREATE UNIQUE INDEX IDX_MetazonePeriods ON MetazonePeriods (`Metazone`, `From`, `To`);
54
+
55
+
56
+ CREATE TABLE MetazonePeriod_Timezones (`ID` INTEGER PRIMARY KEY,
57
+ `MetazonePeriod` INTEGER NOT NULL,
58
+ `Timezone` INTEGER NOT NULL,
59
+ FOREIGN KEY(`MetazonePeriod`) REFERENCES MetazonePeriods(`ID`),
60
+ FOREIGN KEY(`Timezone`) REFERENCES Timezones(`ID`));
61
+ CREATE UNIQUE INDEX IDX_MetazonePeriod_Timezones ON MetazonePeriod_Timezones (`MetazonePeriod`, `Timezone`);
62
+
63
+
64
+ CREATE TABLE TimezoneName_Timezones (`ID` INTEGER PRIMARY KEY,
65
+ `Name` INTEGER NOT NULL,
66
+ `Timezone` INTEGER NOT NULL,
67
+ FOREIGN KEY(`Name`) REFERENCES TimezoneNames(`ID`),
68
+ FOREIGN KEY(`Timezone`) REFERENCES Timezones(`ID`));
69
+ CREATE UNIQUE INDEX IDX_TimezoneName_Timezones ON TimezoneName_Timezones (`Name`, `Timezone`);
70
+
71
+
72
+ CREATE TABLE TimezoneName_Metazones (`ID` INTEGER PRIMARY KEY,
73
+ `Name` INTEGER NOT NULL,
74
+ `Metazone` INTEGER NOT NULL,
75
+ FOREIGN KEY(`Name`) REFERENCES TimezoneNames(`ID`),
76
+ FOREIGN KEY(`Metazone`) REFERENCES Metazones(`ID`));
77
+ CREATE UNIQUE INDEX IDX_TimezoneName_Metazones ON TimezoneName_Metazones (`Name`, `Metazone`);
78
+
79
+
80
+ CREATE TABLE Abbreviations (`ID` INTEGER PRIMARY KEY,
81
+ `Name` TEXT NOT NULL COLLATE BINARY,
82
+ `NameLowercase` TEXT NOT NULL COLLATE NOCASE);
83
+ CREATE UNIQUE INDEX IDX_Abbreviations ON Abbreviations (`Name`);
84
+ CREATE UNIQUE INDEX IDX_AbbreviationsLowercase ON Abbreviations (`NameLowercase`);
85
+
86
+
87
+ CREATE TABLE AbbreviationOffsets (`ID` INTEGER PRIMARY KEY,
88
+ `Abbreviation` INTEGER NOT NULL,
89
+ `Offset` INTEGER,
90
+ `Types` INTEGER,
91
+ `From` TEXT,
92
+ `To` TEXT,
93
+ FOREIGN KEY(`Abbreviation`) REFERENCES Abbreviations(`ID`));
94
+ CREATE UNIQUE INDEX IDX_AbbreviationOffsets ON AbbreviationOffsets (`Abbreviation`, `Offset`, `From`, `To`);
95
+
96
+
97
+ CREATE TABLE AbbreviationOffset_Timezones (`ID` INTEGER PRIMARY KEY,
98
+ `Offset` INTEGER NOT NULL,
99
+ `Timezone` INTEGER NOT NULL,
100
+ FOREIGN KEY(`Offset`) REFERENCES AbbreviationOffsets(`ID`),
101
+ FOREIGN KEY(`Timezone`) REFERENCES Timezones(`ID`));
102
+ CREATE UNIQUE INDEX IDX_AbbreviationOffset_Timezones ON AbbreviationOffset_Timezones (`Offset`, `Timezone`);
103
+
104
+
105
+ CREATE TABLE AbbreviationOffset_Metazones (`ID` INTEGER PRIMARY KEY,
106
+ `Offset` INTEGER NOT NULL,
107
+ `Metazone` INTEGER NOT NULL,
108
+ FOREIGN KEY(`Offset`) REFERENCES AbbreviationOffsets(`ID`),
109
+ FOREIGN KEY(`Metazone`) REFERENCES Metazones(`ID`));
110
+ CREATE UNIQUE INDEX IDX_AbbreviationOffset_Metazones ON AbbreviationOffset_Metazones (`Offset`, `Metazone`);
111
+
112
+
113
+ CREATE TABLE RailsTimezones (`ID` INTEGER PRIMARY KEY,
114
+ `Name` TEXT NOT NULL COLLATE NOCASE,
115
+ `Timezone` INTEGER NOT NULL,
116
+ FOREIGN KEY(`Timezone`) REFERENCES Timezones(`ID`));
117
+ CREATE UNIQUE INDEX IDX_RailsTimezones ON RailsTimezones (`Name`);
118
+
119
+
120
+ CREATE TABLE RailsI18N (`ID` INTEGER PRIMARY KEY,
121
+ `Locale` INTEGER NOT NULL,
122
+ `Name` TEXT NOT NULL COLLATE BINARY,
123
+ `NameLowercase` TEXT NOT NULL COLLATE NOCASE,
124
+ `Zone` INTEGER NOT NULL,
125
+ FOREIGN KEY(`Locale`) REFERENCES Locales(`ID`),
126
+ FOREIGN KEY(`Zone`) REFERENCES RailsTimezones(`ID`));
127
+ CREATE UNIQUE INDEX IDX_RailsI18N ON RailsI18N (`Locale`, `Name`);
128
+ CREATE INDEX IDX_RailsI18NName ON RailsI18N (`NameLowercase`);
129
+
130
+
131
+ CREATE TABLE WindowsZones (`ID` INTEGER PRIMARY KEY,
132
+ `Name` TEXT NOT NULL COLLATE NOCASE,
133
+ `Standard` INTEGER NOT NULL,
134
+ `Daylight` INTEGER NOT NULL);
135
+ CREATE UNIQUE INDEX IDX_WindowsZones ON WindowsZones (`Name`);
136
+
137
+
138
+ CREATE TABLE WindowsZone_Timezones (`ID` INTEGER PRIMARY KEY,
139
+ `Zone` INTEGER NOT NULL,
140
+ `Territory` INTEGER NOT NULL,
141
+ `Timezone` INTEGER NOT NULL,
142
+ FOREIGN KEY(`Zone`) REFERENCES WindowsZones(`ID`),
143
+ FOREIGN KEY(`Territory`) REFERENCES Territories(`ID`),
144
+ FOREIGN KEY(`Timezone`) REFERENCES Timezones(`ID`));
145
+ CREATE UNIQUE INDEX IDX_WindowsZone_Timezones ON WindowsZone_Timezones (`Zone`, `Territory`, `Timezone`);
146
+
147
+
148
+ CREATE TABLE WindowsZoneNames (`ID` INTEGER PRIMARY KEY,
149
+ `Locale` INTEGER NOT NULL,
150
+ `Name` TEXT NOT NULL COLLATE BINARY,
151
+ `NameLowercase` TEXT NOT NULL COLLATE NOCASE,
152
+ `Types` INTEGER,
153
+ FOREIGN KEY(`Locale`) REFERENCES Locales(`ID`));
154
+ CREATE UNIQUE INDEX IDX_WindowsZoneNames ON WindowsZoneNames (`Locale`, `Name`);
155
+ CREATE INDEX IDX_WindowsZoneNamesLowercase ON WindowsZoneNames (`NameLowercase`);
156
+
157
+
158
+ CREATE TABLE WindowsZoneName_Zones (`ID` INTEGER PRIMARY KEY,
159
+ `Name` INTEGER NOT NULL,
160
+ `Zone` INTEGER NOT NULL,
161
+ FOREIGN KEY(`Name`) REFERENCES WindowsZoneNames(`ID`),
162
+ FOREIGN KEY(`Zone`) REFERENCES WindowsZones(`ID`));
163
+ CREATE UNIQUE INDEX IDX_WindowsZoneName_Zones ON WindowsZoneName_Zones (`Name`, `Zone`);
164
+
@@ -49,17 +49,6 @@ module TimezoneParser
49
49
  @@Locales
50
50
  end
51
51
 
52
- # Load Timezone data in memory from files
53
- #
54
- # If no modules are specified it will load default modules
55
- # @param modules [Array<Symbol>] list of modules
56
- # @see Modules
57
- # @see AllModules
58
- def self.preload(modules = @@Modules)
59
- modules = AllModules if modules.nil? or modules.empty?
60
- Data::Storage.preload(modules)
61
- end
62
-
63
52
  # Check if given Timezone name is a valid timezone
64
53
  # @param name [String] either Timezone name or abbreviation
65
54
  # @param locales [Array<String>] check only for these locales
@@ -112,13 +101,13 @@ module TimezoneParser
112
101
  offsets += Abbreviation::getOffsets(name, toTime, fromTime, regions, type) if modules.include?(:Abbreviations)
113
102
  return offsets.to_a if not all and not offsets.empty?
114
103
 
115
- offsets += Timezone::getOffsets(name, toTime, fromTime, locales, regions, all) if modules.include?(:Timezones)
104
+ offsets += Timezone::getOffsets(name, toTime, fromTime, locales, regions) if modules.include?(:Timezones)
116
105
  return offsets.to_a if not all and not offsets.empty?
117
106
 
118
- offsets += WindowsZone::getOffsets(name, locales, all) if modules.include?(:WindowsZones)
107
+ offsets += WindowsZone::getOffsets(name, locales) if modules.include?(:WindowsZones)
119
108
  return offsets.to_a if not all and not offsets.empty?
120
109
 
121
- offsets += RailsZone::getOffsets(name, toTime, fromTime, locales, all) if modules.include?(:RailsZones)
110
+ offsets += RailsZone::getOffsets(name, toTime, fromTime, locales) if modules.include?(:RailsZones)
122
111
  offsets.to_a
123
112
  end
124
113
 
@@ -146,13 +135,13 @@ module TimezoneParser
146
135
  timezones += Abbreviation::getTimezones(name, toTime, fromTime, regions, type) if modules.include?(:Abbreviations)
147
136
  return timezones.to_a if not all and not timezones.empty?
148
137
 
149
- timezones += Timezone::getTimezones(name, toTime, fromTime, locales, regions, all) if modules.include?(:Timezones)
138
+ timezones += Timezone::getTimezones(name, toTime, fromTime, locales, regions) if modules.include?(:Timezones)
150
139
  return timezones.to_a if not all and not timezones.empty?
151
140
 
152
- timezones += WindowsZone::getTimezones(name, locales, regions, all) if modules.include?(:WindowsZones)
141
+ timezones += WindowsZone::getTimezones(name, locales, regions) if modules.include?(:WindowsZones)
153
142
  return timezones.to_a if not all and not timezones.empty?
154
143
 
155
- timezones += RailsZone::getTimezones(name, locales, all) if modules.include?(:RailsZones)
144
+ timezones += RailsZone::getTimezones(name, locales) if modules.include?(:RailsZones)
156
145
  timezones.to_a
157
146
  end
158
147
  end
@@ -23,7 +23,6 @@ module TimezoneParser
23
23
  # @param abbreviation [String] Timezone abbreviation
24
24
  def initialize(abbreviation)
25
25
  @Abbreviation = abbreviation
26
- @Data = Data.new
27
26
  setTime
28
27
  set(@@Regions.dup, nil)
29
28
  end
@@ -42,59 +41,25 @@ module TimezoneParser
42
41
  # Check if abbreviation is valid
43
42
  # @return [Boolean] whether abbreviation is valid
44
43
  def isValid?
45
- Data::Storage.Abbreviations.has_key?(@Abbreviation)
46
- end
47
-
48
- # Abbreviation data
49
- # @return [Data] data
50
- def getData
51
- unless @Loaded
52
- @Loaded = true
53
- if isValid?
54
- data = Data::Storage.Abbreviations[@Abbreviation]
55
- if data.count == 1
56
- @Data.processEntry(data.first, @ToTime, @FromTime, @Regions)
57
- return @Data
58
- end
59
- entries = Data.filterData(data, @ToTime, @FromTime, @Type, @Regions)
60
- entries.each do |entry|
61
- @Data.processEntry(entry, @ToTime, @FromTime, @Regions)
62
- end
63
- return @Data
64
- end
65
- end
66
- @Data
67
- end
68
-
69
- # Get UTC offsets in seconds
70
- # @return [Array<Fixnum>] list of timezone offsets in seconds
71
- def getOffsets
72
- unless @Offsets
73
- @Offsets = getData.Offsets.to_a
74
- if @Offsets.empty? and not getTimezones.empty?
75
- types = nil
76
- types = [@Type] if @Type
77
- @Offsets = @Data.findOffsets(@ToTime, @FromTime, @Regions, types).to_a
78
- end
44
+ if @Valid.nil?
45
+ sql = 'SELECT 1 FROM `Abbreviations` WHERE `Name` = ? LIMIT 1'
46
+ @Valid = Data::Storage.getStatement(sql).execute(@Abbreviation).count > 0
79
47
  end
80
- @Offsets
48
+ @Valid
81
49
  end
82
50
 
83
51
  # Check if given Timezone abbreviation (case-sensitive) is a valid timezone
84
52
  # @param abbreviation [String] Timezone abbreviation
85
53
  # @return [Boolean] whether Timezone is valid
86
54
  def self.isValid?(abbreviation)
87
- Data::Storage.Abbreviations.has_key?(abbreviation)
55
+ Data::Storage.getStatement('SELECT 1 FROM `Abbreviations` WHERE `Name` = ? LIMIT 1').execute(abbreviation).count > 0
88
56
  end
89
57
 
90
58
  # Check if given Timezone abbreviation (case-insensitive) could be a valid timezone
91
59
  # @param abbreviation [String] Timezone abbreviation to check for
92
60
  # @return [Boolean] whether Timezone is valid
93
61
  def self.couldBeValid?(abbreviation)
94
- Data::Storage.Abbreviations.each_key do |abbr|
95
- return true if abbr.casecmp(abbreviation).zero?
96
- end
97
- false
62
+ Data::Storage.getStatement('SELECT 1 FROM `Abbreviations` WHERE `NameLowercase` = ? LIMIT 1').execute(abbreviation.downcase).count > 0
98
63
  end
99
64
 
100
65
  # Get UTC offsets in seconds for given Timezone abbreviation
@@ -126,5 +91,111 @@ module TimezoneParser
126
91
  def self.getMetazones(abbreviation)
127
92
  self.new(abbreviation).getMetazones
128
93
  end
94
+
95
+ protected
96
+
97
+ def getFilteredData(dataType)
98
+ types = nil
99
+ types = [@Type] if @Type
100
+
101
+ params = [@Abbreviation.downcase]
102
+ column = nil
103
+ joins = ' INNER JOIN `AbbreviationOffsets` AS O ON O.Abbreviation = A.ID'
104
+ regionJoins = ''
105
+ useMetazonePeriodFilter = false
106
+ case dataType
107
+ when :Offsets, :Timezones
108
+ column = '`Timezones`.`Name`'
109
+ if dataType == :Offsets
110
+ column = 'O.`Offset`, `Timezones`.`Name`, O.`Types`'
111
+ end
112
+ joins += ' LEFT JOIN `AbbreviationOffset_Timezones` AS T ON T.Offset = O.ID'
113
+ joins += ' LEFT JOIN `AbbreviationOffset_Metazones` AS M ON M.Offset = O.ID'
114
+ joins += ' LEFT JOIN `MetazonePeriods` MP ON M.Metazone = MP.Metazone'
115
+ joins += ' LEFT JOIN `MetazonePeriod_Timezones` MPT ON MPT.MetazonePeriod = MP.ID'
116
+ joins += ' LEFT JOIN `Timezones` ON (T.Timezone = Timezones.ID OR MPT.Timezone = Timezones.ID)'
117
+ regionJoins += ' LEFT JOIN `TimezoneTerritories` ON (TimezoneTerritories.Timezone = T.Timezone OR TimezoneTerritories.Timezone = MPT.Timezone)'
118
+ regionJoins += ' LEFT JOIN `Territories` ON TimezoneTerritories.Territory = Territories.ID'
119
+ useMetazonePeriodFilter = true
120
+ when :Metazones
121
+ column = '`Metazones`.`Name`'
122
+ joins += ' INNER JOIN `AbbreviationOffset_Metazones` AS M ON M.Offset = O.ID'
123
+ joins += ' INNER JOIN `Metazones` ON M.Metazone = Metazones.ID'
124
+ regionJoins += ' LEFT JOIN `AbbreviationOffset_Timezones` AS T ON T.Offset = O.ID'
125
+ regionJoins += ' LEFT JOIN `TimezoneTerritories` ON TimezoneTerritories.Timezone = T.Timezone'
126
+ regionJoins += ' LEFT JOIN `Territories` ON TimezoneTerritories.Territory = Territories.ID'
127
+ when :Types
128
+ column = 'O.`Types`'
129
+ else
130
+ raise StandardError, "Unkown dataType '#{dataType}'"
131
+ end
132
+ sql = 'SELECT DISTINCT ' + column + ' FROM `Abbreviations` AS A'
133
+ sql += joins
134
+ if not @Regions.nil? and not @Regions.empty?
135
+ sql += regionJoins
136
+ end
137
+ sql += ' WHERE A.`NameLowercase` = ?'
138
+ if not types.nil?
139
+ if types.include?(:standard) and not types.include?(:daylight)
140
+ sql += ' AND (O.`Types` & ?) > 0'
141
+ params << TIMEZONE_TYPE_STANDARD
142
+
143
+ else
144
+ sql += ' AND (O.`Types` & ?) > 0'
145
+ params << TIMEZONE_TYPE_DAYLIGHT
146
+ end
147
+ end
148
+ unless @FromTime.nil?
149
+ fromsql = '((O.`From` IS NULL AND O.`To` > ?) OR (O.`To` IS NULL AND O.`From` <= ?) OR (O.`From` <= ? AND O.`To` > ?) OR (O.`From` IS NULL AND O.`To` IS NULL))'
150
+ params += Array.new(4, @FromTime.to_s)
151
+ if useMetazonePeriodFilter
152
+ fromsql = '(' + fromsql + ' AND ((MP.`From` IS NULL AND MP.`To` > ?) OR (MP.`To` IS NULL AND MP.`From` <= ?) OR (MP.`From` <= ? AND MP.`To` > ?) OR (MP.`From` IS NULL AND MP.`To` IS NULL)))'
153
+ params += Array.new(4, @FromTime.to_s)
154
+ end
155
+ if @ToTime.nil?
156
+ sql += ' AND ' + fromsql
157
+ end
158
+ end
159
+ unless @ToTime.nil?
160
+ tosql = '((O.`From` IS NULL AND O.`To` >= ?) OR (O.`To` IS NULL AND O.`From` < ?) OR (O.`From` < ? AND O.`To` >= ?) OR (O.`From` IS NULL AND O.`To` IS NULL))'
161
+ params += Array.new(4, @ToTime.to_s)
162
+ if useMetazonePeriodFilter
163
+ tosql = '(' + tosql + ' AND ((MP.`From` IS NULL AND MP.`To` >= ?) OR (MP.`To` IS NULL AND MP.`From` < ?) OR (MP.`From` < ? AND MP.`To` >= ?) OR (MP.`From` IS NULL AND MP.`To` IS NULL)))'
164
+ params += Array.new(4, @ToTime.to_s)
165
+ end
166
+ if not @FromTime.nil?
167
+ sql += ' AND ((' + fromsql + ') OR (' + tosql + '))'
168
+ else
169
+ sql += ' AND ' + tosql
170
+ end
171
+ end
172
+ if not @Regions.nil? and not @Regions.empty?
173
+ sql += ' AND Territories.Territory IN (' + Array.new(@Regions.count, '?').join(',') + ')'
174
+ params += @Regions
175
+ end
176
+ sql += ' ORDER BY ' + column
177
+ if dataType == :Offsets
178
+ result = Set.new
179
+ timezonesTypes = []
180
+ Data::Storage.getStatement(sql).execute(*params).each do |row|
181
+ if row.first.nil?
182
+ timezonesTypes << [row[1], row[2]]
183
+ else
184
+ result << row.first
185
+ end
186
+ end
187
+
188
+ result += self.class.findOffsetsFromTimezonesTypes(timezonesTypes, @ToTime, @FromTime, types) if result.empty?
189
+
190
+ result = result.sort
191
+ else
192
+ result = Data::Storage.getStatement(sql).execute(*params).collect { |row| row.first }
193
+ if dataType == :Types
194
+ result = self.class.convertTypes(result)
195
+ end
196
+ end
197
+ result
198
+ end
199
+
129
200
  end
130
201
  end