aboutsummaryrefslogtreecommitdiffstats
path: root/app/models/referential.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/referential.rb')
-rw-r--r--app/models/referential.rb71
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