| 
									
										
										
										
											2019-03-16 09:37:35 +00:00
										 |  |  | # frozen_string_literal: true | 
					
						
							| 
									
										
										
										
											2019-03-15 01:32:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-08 15:13:57 +00:00
										 |  |  | # Redmine - project management software | 
					
						
							| 
									
										
										
										
											2021-03-25 06:58:56 +00:00
										 |  |  | # Copyright (C) 2006-2021  Jean-Philippe Lang | 
					
						
							| 
									
										
										
										
											2015-02-08 15:13:57 +00:00
										 |  |  | # | 
					
						
							|  |  |  | # This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  | # modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  | # as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  | # of the License, or (at your option) any later version. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | # but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  | # GNU General Public License for more details. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | # along with this program; if not, write to the Free Software | 
					
						
							|  |  |  | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module Redmine | 
					
						
							|  |  |  |   # Helper module to get information about the Redmine database | 
					
						
							|  |  |  |   module Database | 
					
						
							|  |  |  |     class << self | 
					
						
							| 
									
										
										
										
											2020-04-20 02:06:57 +00:00
										 |  |  |       # Returns true if the database is SQLite | 
					
						
							|  |  |  |       def sqlite? | 
					
						
							|  |  |  |         ActiveRecord::Base.connection.adapter_name =~ /sqlite/i | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-08 15:13:57 +00:00
										 |  |  |       # Returns true if the database is PostgreSQL | 
					
						
							|  |  |  |       def postgresql? | 
					
						
							| 
									
										
										
										
											2019-03-27 02:15:24 +00:00
										 |  |  |         /postgresql/i.match?(ActiveRecord::Base.connection.adapter_name) | 
					
						
							| 
									
										
										
										
											2015-02-08 15:13:57 +00:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       # Returns the PostgreSQL version or nil if another DBMS is used | 
					
						
							|  |  |  |       def postgresql_version | 
					
						
							|  |  |  |         postgresql? ? ActiveRecord::Base.connection.send(:postgresql_version) : nil | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       # Returns true if the database is a PostgreSQL >=9.0 database with the unaccent extension installed | 
					
						
							|  |  |  |       def postgresql_unaccent? | 
					
						
							|  |  |  |         if postgresql? | 
					
						
							|  |  |  |           return @postgresql_unaccent unless @postgresql_unaccent.nil? | 
					
						
							| 
									
										
										
										
											2020-12-04 13:59:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-08 15:13:57 +00:00
										 |  |  |           begin | 
					
						
							| 
									
										
										
										
											2020-12-04 13:59:14 +00:00
										 |  |  |             sql = | 
					
						
							|  |  |  |               "SELECT name FROM pg_available_extensions " \ | 
					
						
							|  |  |  |                 "WHERE installed_version IS NOT NULL and name = 'unaccent'" | 
					
						
							|  |  |  |             @postgresql_unaccent = | 
					
						
							|  |  |  |               postgresql_version >= 90000 && | 
					
						
							|  |  |  |                 ActiveRecord::Base.connection.select_value(sql).present? | 
					
						
							| 
									
										
										
										
											2015-02-08 15:13:57 +00:00
										 |  |  |           rescue | 
					
						
							|  |  |  |             false | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           false | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-30 20:59:47 +00:00
										 |  |  |       # Returns true if the database is MySQL | 
					
						
							|  |  |  |       def mysql? | 
					
						
							| 
									
										
										
										
											2019-03-27 02:15:24 +00:00
										 |  |  |         /mysql/i.match?(ActiveRecord::Base.connection.adapter_name) | 
					
						
							| 
									
										
										
										
											2015-09-30 20:59:47 +00:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-02 08:32:18 +00:00
										 |  |  |       # Returns a SQL statement for case/accent (if possible) insensitive match | 
					
						
							|  |  |  |       def like(left, right, options={}) | 
					
						
							|  |  |  |         neg = (options[:match] == false ? 'NOT ' : '') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if postgresql? | 
					
						
							|  |  |  |           if postgresql_unaccent? | 
					
						
							|  |  |  |             "unaccent(#{left}) #{neg}ILIKE unaccent(#{right})" | 
					
						
							|  |  |  |           else | 
					
						
							|  |  |  |             "#{left} #{neg}ILIKE #{right}" | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2021-10-09 06:35:47 +00:00
										 |  |  |         elsif mysql? | 
					
						
							| 
									
										
										
										
											2015-08-02 08:32:18 +00:00
										 |  |  |           "#{left} #{neg}LIKE #{right}" | 
					
						
							| 
									
										
										
										
											2021-10-09 06:35:47 +00:00
										 |  |  |         else | 
					
						
							|  |  |  |           "#{left} #{neg}LIKE #{right} ESCAPE '\\'" | 
					
						
							| 
									
										
										
										
											2015-08-02 08:32:18 +00:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-12 19:52:28 +00:00
										 |  |  |       # Returns a SQL statement to cast a timestamp column to a date given a time zone | 
					
						
							|  |  |  |       # Returns nil if not implemented for the current database | 
					
						
							|  |  |  |       def timestamp_to_date(column, time_zone) | 
					
						
							|  |  |  |         if postgresql? | 
					
						
							|  |  |  |           if time_zone | 
					
						
							|  |  |  |             identifier = ActiveSupport::TimeZone.find_tzinfo(time_zone.name).identifier | 
					
						
							|  |  |  |             "(#{column}::timestamptz AT TIME ZONE '#{identifier}')::date" | 
					
						
							|  |  |  |           else | 
					
						
							|  |  |  |             "#{column}::date" | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2018-12-16 07:03:47 +00:00
										 |  |  |         elsif mysql? | 
					
						
							|  |  |  |           if time_zone | 
					
						
							|  |  |  |             user_identifier = ActiveSupport::TimeZone.find_tzinfo(time_zone.name).identifier | 
					
						
							|  |  |  |             local_identifier = ActiveSupport::TimeZone.find_tzinfo(Time.zone.name).identifier | 
					
						
							| 
									
										
										
										
											2019-09-12 22:55:44 +00:00
										 |  |  |             "DATE(CONVERT_TZ(#{column},'#{local_identifier}', '#{user_identifier}'))" | 
					
						
							| 
									
										
										
										
											2018-12-16 07:03:47 +00:00
										 |  |  |           else | 
					
						
							|  |  |  |             "DATE(#{column})" | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2018-12-12 19:52:28 +00:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-08 15:13:57 +00:00
										 |  |  |       # Resets database information | 
					
						
							|  |  |  |       def reset | 
					
						
							|  |  |  |         @postgresql_unaccent = nil | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |