summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRobert Speicher <robert@gitlab.com>2017-02-07 19:14:19 +0000
committerRobert Speicher <robert@gitlab.com>2017-02-07 19:14:19 +0000
commit58eae0961ea6e2147a288cda8a56a51303bbf13b (patch)
tree0bbd873650dfc889af8df7e197397959d774d411 /lib
parentd3aaa1a2a0313b7132479d4211e406fde5bc9324 (diff)
parent0fdf54ddf5894ec1057b7351140fdce4f0df0ed1 (diff)
downloadgitlab-ce-58eae0961ea6e2147a288cda8a56a51303bbf13b.tar.gz
Merge branch 'route-map' into 'master'
Add 'View on [env]' link to blobs and individual files in diffs See merge request !8867
Diffstat (limited to 'lib')
-rw-r--r--lib/gitlab/database.rb14
-rw-r--r--lib/gitlab/route_map.rb52
2 files changed, 66 insertions, 0 deletions
diff --git a/lib/gitlab/database.rb b/lib/gitlab/database.rb
index 55b8f888d53..dc2537d36aa 100644
--- a/lib/gitlab/database.rb
+++ b/lib/gitlab/database.rb
@@ -35,6 +35,20 @@ module Gitlab
order
end
+ def self.nulls_first_order(field, direction = 'ASC')
+ order = "#{field} #{direction}"
+
+ if Gitlab::Database.postgresql?
+ order << ' NULLS FIRST'
+ else
+ # `field IS NULL` will be `0` for non-NULL columns and `1` for NULL
+ # columns. In the (default) ascending order, `0` comes first.
+ order.prepend("#{field} IS NULL, ") if direction == 'DESC'
+ end
+
+ order
+ end
+
def self.random
Gitlab::Database.postgresql? ? "RANDOM()" : "RAND()"
end
diff --git a/lib/gitlab/route_map.rb b/lib/gitlab/route_map.rb
new file mode 100644
index 00000000000..89985d90c10
--- /dev/null
+++ b/lib/gitlab/route_map.rb
@@ -0,0 +1,52 @@
+module Gitlab
+ class RouteMap
+ class FormatError < StandardError; end
+
+ def initialize(data)
+ begin
+ entries = YAML.safe_load(data)
+ rescue
+ raise FormatError, 'Route map needs to be valid YAML'
+ end
+
+ raise FormatError, 'Route map needs to be an array' unless entries.is_a?(Array)
+
+ @map = entries.map { |entry| parse_entry(entry) }
+ end
+
+ def public_path_for_source_path(path)
+ mapping = @map.find { |mapping| path =~ mapping[:source] }
+ return unless mapping
+
+ path.sub(mapping[:source], mapping[:public])
+ end
+
+ private
+
+ def parse_entry(entry)
+ raise FormatError, 'Route map entry needs to be a hash' unless entry.is_a?(Hash)
+ raise FormatError, 'Route map entry requires a source key' unless entry.has_key?('source')
+ raise FormatError, 'Route map entry requires a public key' unless entry.has_key?('public')
+
+ source_regexp = entry['source']
+ public_path = entry['public']
+
+ unless source_regexp.start_with?('/') && source_regexp.end_with?('/')
+ raise FormatError, 'Route map entry source needs to start and end in a slash (/)'
+ end
+
+ source_regexp = source_regexp[1...-1].gsub('\/', '/')
+
+ begin
+ source_regexp = Regexp.new("^#{source_regexp}$")
+ rescue RegexpError => e
+ raise FormatError, "Route map entry source needs to be a valid regular expression: #{e}"
+ end
+
+ {
+ source: source_regexp,
+ public: public_path
+ }
+ end
+ end
+end