14560: Only index the first 1M bytes of ft-searchable data.
[arvados.git] / services / api / app / models / arvados_model.rb
index 2edbb935a1238d4456725d145b5c1ffce800fc47..74d1d950763ded3fe8bc18acfa050df84bf07da1 100644 (file)
@@ -240,7 +240,7 @@ class ArvadosModel < ActiveRecord::Base
     end.compact.uniq
   end
 
-  # Return a query with read permissions restricted to the union of of the
+  # Return a query with read permissions restricted to the union of the
   # permissions of the members of users_list, i.e. if something is readable by
   # any user in users_list, it will be readable in the query returned by this
   # function.
@@ -258,6 +258,7 @@ class ArvadosModel < ActiveRecord::Base
     # Collect the UUIDs of the authorized users.
     sql_table = kwargs.fetch(:table_name, table_name)
     include_trash = kwargs.fetch(:include_trash, false)
+    include_old_versions = kwargs.fetch(:include_old_versions, false)
 
     sql_conds = nil
     user_uuids = users_list.map { |u| u.uuid }
@@ -316,6 +317,15 @@ class ArvadosModel < ActiveRecord::Base
 
     end
 
+    if !include_old_versions && sql_table == "collections"
+      exclude_old_versions = "#{sql_table}.uuid = #{sql_table}.current_version_uuid"
+      if sql_conds.nil?
+        sql_conds = exclude_old_versions
+      else
+        sql_conds += " AND #{exclude_old_versions}"
+      end
+    end
+
     self.where(sql_conds,
                user_uuids: user_uuids,
                permission_link_classes: ['permission', 'resources'])
@@ -363,7 +373,13 @@ class ArvadosModel < ActiveRecord::Base
         end
 
         self[:name] = new_name
-        self[:uuid] = nil if uuid_was.nil? && !uuid.nil?
+        if uuid_was.nil? && !uuid.nil?
+          self[:uuid] = nil
+          if self.is_a? Collection
+            # Reset so that is assigned to the new UUID
+            self[:current_version_uuid] = nil
+          end
+        end
         conn.exec_query 'SAVEPOINT save_with_unique_name'
         retry
       ensure
@@ -387,7 +403,7 @@ class ArvadosModel < ActiveRecord::Base
       cast = serialized_attributes[column] ? '::text' : ''
       "coalesce(#{column}#{cast},'')"
     end
-    "to_tsvector('english', #{parts.join(" || ' ' || ")})"
+    "to_tsvector('english', substr(#{parts.join(" || ' ' || ")}, 0, 1000000))"
   end
 
   def self.apply_filters query, filters
@@ -537,12 +553,12 @@ class ArvadosModel < ActiveRecord::Base
 
   def update_modified_by_fields
     current_time = db_current_time
-    self.created_at = created_at_was || current_time
+    self.created_at ||= created_at_was || current_time
     self.updated_at = current_time
     self.owner_uuid ||= current_default_owner if self.respond_to? :owner_uuid=
-    self.modified_at = current_time
     if !anonymous_updater
       self.modified_by_user_uuid = current_user ? current_user.uuid : nil
+      self.modified_at = current_time
     end
     self.modified_by_client_uuid = current_api_client ? current_api_client.uuid : nil
     true
@@ -596,16 +612,24 @@ class ArvadosModel < ActiveRecord::Base
     end
   end
 
-  def self.where_serialized(colname, value)
+  def self.where_serialized(colname, value, md5: false)
+    colsql = colname.to_s
+    if md5
+      colsql = "md5(#{colsql})"
+    end
     if value.empty?
       # rails4 stores as null, rails3 stored as serialized [] or {}
-      sql = "#{colname.to_s} is null or #{colname.to_s} IN (?)"
+      sql = "#{colsql} is null or #{colsql} IN (?)"
       sorted = value
     else
-      sql = "#{colname.to_s} IN (?)"
+      sql = "#{colsql} IN (?)"
       sorted = deep_sort_hash(value)
     end
-    where(sql, [sorted.to_yaml, SafeJSON.dump(sorted)])
+    params = [sorted.to_yaml, SafeJSON.dump(sorted)]
+    if md5
+      params = params.map { |x| Digest::MD5.hexdigest(x) }
+    end
+    where(sql, params)
   end
 
   Serializer = {
@@ -764,8 +788,8 @@ class ArvadosModel < ActiveRecord::Base
   end
 
   def is_audit_logging_enabled?
-    return Rails.configuration.max_audit_log_age == 0 &&
-           Rails.configuration.max_audit_log_delete_batch > 0
+    return !(Rails.configuration.max_audit_log_age.to_i == 0 &&
+             Rails.configuration.max_audit_log_delete_batch.to_i > 0)
   end
 
   def log_start_state