snippet.rb 3.6 KB
Newer Older
D
Dmitriy Zaporozhets 已提交
1 2 3 4
# == Schema Information
#
# Table name: snippets
#
V
Valery Sizov 已提交
5 6 7 8 9 10 11 12 13 14
#  id               :integer          not null, primary key
#  title            :string(255)
#  content          :text
#  author_id        :integer          not null
#  project_id       :integer
#  created_at       :datetime
#  updated_at       :datetime
#  file_name        :string(255)
#  type             :string(255)
#  visibility_level :integer          default(0), not null
D
Dmitriy Zaporozhets 已提交
15
#
D
Dmitriy Zaporozhets 已提交
16

G
gitlabhq 已提交
17
class Snippet < ActiveRecord::Base
V
Valery Sizov 已提交
18
  include Gitlab::VisibilityLevel
19
  include Linguist::BlobHelper
20
  include Participable
21 22
  include Referable
  include Sortable
G
gitlabhq 已提交
23

V
Valery Sizov 已提交
24
  default_value_for :visibility_level, Snippet::PRIVATE
25

R
Robert Speicher 已提交
26 27
  belongs_to :author, class_name: 'User'
  belongs_to :project
A
Andrew8xx8 已提交
28

29
  has_many :notes, as: :noteable, dependent: :destroy
G
gitlabhq 已提交
30

D
Dmitriy Zaporozhets 已提交
31
  delegate :name, :email, to: :author, prefix: true, allow_nil: true
G
gitlabhq 已提交
32

A
Andrey Kumanyaev 已提交
33
  validates :author, presence: true
N
Nihad Abbasov 已提交
34
  validates :title, presence: true, length: { within: 0..255 }
35 36
  validates :file_name,
    length: { within: 0..255 },
D
Douwe Maan 已提交
37 38
    format: { with: Gitlab::Regex.file_name_regex,
              message: Gitlab::Regex.file_name_regex_message }
V
Valeriy Sizov 已提交
39
  validates :content, presence: true
V
Valery Sizov 已提交
40
  validates :visibility_level, inclusion: { in: Gitlab::VisibilityLevel.values }
G
gitlabhq 已提交
41

A
Andrey Kumanyaev 已提交
42
  # Scopes
V
Valery Sizov 已提交
43 44 45 46
  scope :are_internal,  -> { where(visibility_level: Snippet::INTERNAL) }
  scope :are_private, -> { where(visibility_level: Snippet::PRIVATE) }
  scope :are_public, -> { where(visibility_level: Snippet::PUBLIC) }
  scope :public_and_internal, -> { where(visibility_level: [Snippet::PUBLIC, Snippet::INTERNAL]) }
A
Andrew8xx8 已提交
47
  scope :fresh,   -> { order("created_at DESC") }
N
Nihad Abbasov 已提交
48

49 50
  participant :author, :notes

51 52 53 54
  def self.reference_prefix
    '$'
  end

55 56 57 58 59
  # Pattern used to extract `$123` snippet references from text
  #
  # This pattern supports cross-project references.
  def self.reference_pattern
    %r{
60 61
      (#{Project.reference_pattern})?
      #{Regexp.escape(reference_prefix)}(?<snippet>\d+)
62 63 64
    }x
  end

65 66 67 68
  def self.link_reference_pattern
    super("snippets", /(?<snippet>\d+)/)
  end

69 70 71 72 73 74 75 76 77 78
  def to_reference(from_project = nil)
    reference = "#{self.class.reference_prefix}#{id}"

    if cross_project_reference?(from_project)
      reference = project.to_reference + reference
    end

    reference
  end

G
gitlabhq 已提交
79
  def self.content_types
N
Nihad Abbasov 已提交
80
    [
G
gitlabhq 已提交
81 82 83 84 85
      ".rb", ".py", ".pl", ".scala", ".c", ".cpp", ".java",
      ".haml", ".html", ".sass", ".scss", ".xml", ".php", ".erb",
      ".js", ".sh", ".coffee", ".yml", ".md"
    ]
  end
G
gitlabhq 已提交
86

87 88 89 90
  def data
    content
  end

91 92 93 94
  def hook_attrs
    attributes
  end

95 96 97 98
  def size
    0
  end

99
  def name
100 101 102
    file_name
  end

103 104 105 106
  def sanitized_file_name
    file_name.gsub(/[^a-zA-Z0-9_\-\.]+/, '')
  end

107
  def mode
108
    nil
G
gitlabhq 已提交
109
  end
N
Nihad Abbasov 已提交
110

V
Valery Sizov 已提交
111 112
  def visibility_level_field
    visibility_level
113
  end
V
Valery Sizov 已提交
114

115
  class << self
116 117 118 119 120 121 122
    # Searches for snippets with a matching title or file name.
    #
    # This method uses ILIKE on PostgreSQL and LIKE on MySQL.
    #
    # query - The search query as a String.
    #
    # Returns an ActiveRecord::Relation.
123
    def search(query)
124
      t = arel_table
125 126 127
      pattern = "%#{query}%"

      where(t[:title].matches(pattern).or(t[:file_name].matches(pattern)))
128 129
    end

130 131 132 133 134 135 136
    # Searches for snippets with matching content.
    #
    # This method uses ILIKE on PostgreSQL and LIKE on MySQL.
    #
    # query - The search query as a String.
    #
    # Returns an ActiveRecord::Relation.
137
    def search_code(query)
138 139 140 141
      table   = Snippet.arel_table
      pattern = "%#{query}%"

      where(table[:content].matches(pattern))
142 143 144
    end

    def accessible_to(user)
V
Valery Sizov 已提交
145
      where('visibility_level IN (?) OR author_id = ?', [Snippet::INTERNAL, Snippet::PUBLIC], user)
146 147
    end
  end
G
gitlabhq 已提交
148
end