diff options
Diffstat (limited to 'app/models/referential.rb')
| -rw-r--r-- | app/models/referential.rb | 71 |
1 files changed, 68 insertions, 3 deletions
diff --git a/app/models/referential.rb b/app/models/referential.rb index 0522d72c0..0c6e71d47 100644 --- a/app/models/referential.rb +++ b/app/models/referential.rb @@ -3,6 +3,8 @@ class Referential < ApplicationModel include DataFormatEnumerations include ObjectidFormatterSupport + STATES = %i(pending active failed archived) + validates_presence_of :name validates_presence_of :slug validates_presence_of :prefix @@ -24,6 +26,7 @@ class Referential < ApplicationModel has_one :user has_many :api_keys, class_name: 'Api::V1::ApiKey', dependent: :destroy + has_many :import_resources, class_name: 'Import::Resource', dependent: :destroy belongs_to :organisation validates_presence_of :organisation @@ -57,8 +60,13 @@ class Referential < ApplicationModel belongs_to :referential_suite + scope :pending, -> { where(ready: false, failed_at: nil, archived_at: nil) } + scope :active, -> { where(ready: true, failed_at: nil, archived_at: nil) } + scope :failed, -> { where.not(failed_at: nil) } + scope :archived, -> { where.not(archived_at: nil) } scope :ready, -> { where(ready: true) } + scope :in_periode, ->(periode) { where(id: referential_ids_in_periode(periode)) } scope :include_metadatas_lines, ->(line_ids) { where('referential_metadata.line_ids && ARRAY[?]::bigint[]', line_ids) } scope :order_by_validity_period, ->(dir) { joins(:metadatas).order("unnest(periodes) #{dir}") } @@ -116,6 +124,20 @@ class Referential < ApplicationModel @_models_with_checksum || [] end + OPERATIONS = [Import::Netex, Import::Gtfs] + + def last_operation + operations = [] + Referential::OPERATIONS.each do |klass| + operations << klass.for_referential(self).limit(1).select("'#{klass.name}' as kind, id, created_at").order('created_at DESC').to_sql + end + sql = "SELECT * FROM ((#{operations.join(') UNION (')})) AS subquery ORDER BY subquery.created_at DESC" + res = ActiveRecord::Base.connection.execute(sql).first + if res + res["kind"].constantize.find(res["id"]) + end + end + def lines if metadatas.blank? workbench ? workbench.lines : associated_lines @@ -249,7 +271,8 @@ class Referential < ApplicationModel stop_area_referential: from.stop_area_referential, created_from: from, objectid_format: from.objectid_format, - metadatas: from.metadatas.map { |m| ReferentialMetadata.new_from(m, organisation) } + metadatas: from.metadatas.map { |m| ReferentialMetadata.new_from(m, organisation) }, + ready: false ) end @@ -300,12 +323,13 @@ class Referential < ApplicationModel before_create :create_schema after_create :clone_schema, if: :created_from + after_create :active!, unless: :created_from before_destroy :destroy_schema before_destroy :destroy_jobs def referential_read_only? - in_referential_suite? || archived? + !ready? || in_referential_suite? || archived? end def in_referential_suite? @@ -375,7 +399,7 @@ class Referential < ApplicationModel query = "select distinct(public.referential_metadata.referential_id) FROM public.referential_metadata, unnest(line_ids) line, LATERAL unnest(periodes) period WHERE public.referential_metadata.referential_id - IN (SELECT public.referentials.id FROM public.referentials WHERE referentials.workbench_id = #{workbench_id} and referentials.archived_at is null and referentials.referential_suite_id is null #{not_myself}) + IN (SELECT public.referentials.id FROM public.referentials WHERE referentials.workbench_id = #{workbench_id} and referentials.archived_at is null and referentials.referential_suite_id is null #{not_myself} AND referentials.failed_at IS NULL) AND line in (#{line_ids.join(',')}) and (#{periods_query});" self.class.connection.select_values(query).map(&:to_i) @@ -449,6 +473,7 @@ class Referential < ApplicationModel end def destroy_schema + return unless ActiveRecord::Base.connection.schema_names.include?(slug) Apartment::Tenant.drop slug end @@ -527,6 +552,46 @@ class Referential < ApplicationModel ready.not_merged.not_in_referential_suite end + ### STATE + + def state + return :failed if failed_at.present? + return :archived if archived_at.present? + ready? ? :active : :pending + end + + def pending! + update ready: false, failed_at: nil, archived_at: nil + end + + def failed! + update ready: false, failed_at: Time.now, archived_at: nil + end + + def active! + update ready: true, failed_at: nil, archived_at: nil + end + + def archived! + update failed_at: nil, archived_at: Time.now + end + + STATES.each do |s| + define_method "#{s}?" do + state == s + end + end + + def pending_while + vals = attributes.slice(*%w(ready archived_at failed_at)) + pending! + begin + yield + ensure + update vals + end + end + private def lock_table |
