Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/models/data_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class DataType < ApplicationRecord
has_many :data_type_identifiers, class_name: 'DataTypeIdentifier', inverse_of: :data_type
has_many :generic_types, class_name: 'GenericType', inverse_of: :data_type

has_many :owned_generic_types, class_name: 'GenericType', inverse_of: :owner

has_many :display_messages, -> { by_purpose(:display_message) },
class_name: 'Translation', as: :owner, inverse_of: :owner
has_many :aliases, -> { by_purpose(:alias) }, class_name: 'Translation', as: :owner, inverse_of: :owner
Expand Down
2 changes: 2 additions & 0 deletions app/models/data_type_rule.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class DataTypeRule < ApplicationRecord

belongs_to :data_type, inverse_of: :rules

has_many :owned_generic_types, class_name: 'GenericType', inverse_of: :owner

validates :variant, presence: true,
inclusion: {
in: VARIANTS.keys.map(&:to_s),
Expand Down
2 changes: 2 additions & 0 deletions app/models/generic_mapper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ class GenericMapper < ApplicationRecord
has_many :sources, class_name: 'DataTypeIdentifier', inverse_of: :generic_mapper
has_many :generic_combination_strategies, class_name: 'GenericCombinationStrategy', inverse_of: :generic_mapper

has_many :owned_generic_types, class_name: 'GenericType', inverse_of: :owner

validates :target, presence: true

def to_grpc
Expand Down
1 change: 1 addition & 0 deletions app/models/generic_type.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

class GenericType < ApplicationRecord
belongs_to :owner, polymorphic: true
belongs_to :data_type, class_name: 'DataType', inverse_of: :generic_types

has_many :generic_mappers, inverse_of: :generic_type
Expand Down
2 changes: 2 additions & 0 deletions app/models/runtime_function_definition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class RuntimeFunctionDefinition < ApplicationRecord
class_name: 'Translation', as: :owner, inverse_of: :owner
has_many :aliases, -> { by_purpose(:alias) }, class_name: 'Translation', as: :owner, inverse_of: :owner

has_many :owned_generic_types, class_name: 'GenericType', inverse_of: :owner

validates :runtime_name, presence: true,
length: { minimum: 3, maximum: 50 },
uniqueness: { case_sensitive: false, scope: :runtime_id }
Expand Down
2 changes: 2 additions & 0 deletions app/models/runtime_parameter_definition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ class RuntimeParameterDefinition < ApplicationRecord

has_many :parameter_definitions, inverse_of: :runtime_parameter_definition

has_many :owned_generic_types, class_name: 'GenericType', inverse_of: :owner

validates :runtime_name, length: { minimum: 3, maximum: 50 }, presence: true,
uniqueness: { case_sensitive: false, scope: :runtime_function_definition_id }
end
41 changes: 21 additions & 20 deletions app/services/runtimes/grpc/data_type_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@ module DataTypeHelper
# This method updates or creates GenericMappers based on the provided gRPC GenericMapper objects
# within the current runtime.
# @param generic_mappers [Array<Tucana::Shared::GenericMapper>] An array of gRPC GenericMapper objects.
def update_mappers(generic_mappers, t)
def update_mappers(generic_mappers, generic_type, t)
raise 'Including class must define current_runtime' unless respond_to?(:current_runtime)

generic_mappers.to_a.map do |generic_mapper|
mapper = GenericMapper.create_or_find_by(runtime: current_runtime,
target: generic_mapper.target,
sources: generic_mapper.source.map do |source|
find_data_type_identifier(source, t)
end)
mapper = GenericMapper.find_by(runtime: current_runtime, generic_type: generic_type)

mapper = GenericMapper.new(runtime: current_runtime, generic_type: generic_type) if mapper.nil?

mapper.target = generic_mapper.target
mapper.sources = generic_mapper.source.map do |source|
find_data_type_identifier(source, mapper, t, additional_dti_kwargs: { generic_mapper: mapper })
end

if mapper.nil? || !mapper.save
t.rollback_and_return! ServiceResponse.error(
Expand All @@ -28,22 +31,19 @@ def update_mappers(generic_mappers, t)

# This method finds or creates a DataTypeIdentifier based on the provided identifier within the current runtime.
# @param identifier [Tucana::Sagittarius::DataTypeIdentifier] The gRPC DataTypeIdentifier object.
def find_data_type_identifier(identifier, t)
def find_data_type_identifier(identifier, owner, t, additional_dti_kwargs: {})
if identifier.data_type_identifier.present?
return create_data_type_identifier(t, data_type_id: find_data_type(identifier.data_type_identifier, t).id)
return create_data_type_identifier(
t,
**additional_dti_kwargs,
data_type_id: find_data_type(identifier.data_type_identifier, t).id
)
end

if identifier.generic_type.present?
data_type = find_data_type(identifier.generic_type.data_type_identifier, t)

generic_type = GenericType.find_by(
data_type: data_type
)
if generic_type.nil?
generic_type = GenericType.create(
data_type: data_type
)
end
generic_type = owner.owned_generic_types.find_or_initialize_by(data_type: data_type)

if generic_type.nil?
t.rollback_and_return! ServiceResponse.error(
Expand All @@ -52,13 +52,14 @@ def find_data_type_identifier(identifier, t)
)
end

generic_type.assign_attributes(generic_mappers: update_mappers(identifier.generic_type.generic_mappers,
t))
generic_type.generic_mappers = update_mappers(identifier.generic_type.generic_mappers, generic_type, t)

return create_data_type_identifier(t, generic_type_id: generic_type.id)
return create_data_type_identifier(t, **additional_dti_kwargs, generic_type_id: generic_type.id)
end

return create_data_type_identifier(t, generic_key: identifier.generic_key) if identifier.generic_key.present?
if identifier.generic_key.present?
return create_data_type_identifier(t, **additional_dti_kwargs, generic_key: identifier.generic_key)
end

raise ArgumentError, "Invalid identifier: #{identifier.inspect}"
end
Expand Down
19 changes: 13 additions & 6 deletions app/services/runtimes/grpc/data_types/update_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,11 @@ def update_datatype(data_type, t)
db_object.removed_at = nil
db_object.variant = data_type.variant.to_s.downcase
if parent?(data_type)
db_object.parent_type = find_data_type_identifier(find_parent_rule(data_type).rule_config.parent_type, t)
db_object.parent_type = find_data_type_identifier(
find_parent_rule(data_type).rule_config.parent_type,
db_object,
t
)
end
db_object.rules = update_rules(data_type.rules, db_object, t)
db_object.names = update_translations(data_type.name, db_object.names)
Expand All @@ -142,34 +146,37 @@ def update_rules(rules, data_type, t)
db_rules = data_type.rules.first(rules.length)
rules.each_with_index do |rule, index|
db_rules[index] ||= DataTypeRule.new
db_rules[index].assign_attributes(variant: rule.variant.to_s.downcase, config: extend_rule_config(rule, t))
db_rules[index].assign_attributes(
variant: rule.variant.to_s.downcase,
config: extend_rule_config(rule, db_rules[index], t)
)
end

db_rules
end

def extend_rule_config(rule, t)
def extend_rule_config(rule, db_rule, t)
case rule.variant
when :parent_type
{}
when :contains_key
{
key: rule.rule_config.key,
data_type_identifier: rule.rule_config.data_type_identifier,
data_type_identifier_id: find_data_type_identifier(rule.rule_config.data_type_identifier, t).id,
data_type_identifier_id: find_data_type_identifier(rule.rule_config.data_type_identifier, db_rule, t).id,
}
when :contains_type, :return_type
{
data_type_identifier: rule.rule_config.data_type_identifier,
data_type_identifier_id: find_data_type_identifier(rule.rule_config.data_type_identifier, t).id,
data_type_identifier_id: find_data_type_identifier(rule.rule_config.data_type_identifier, db_rule, t).id,
}
when :input_types
{
input_types: rule.rule_config.input_types.map do |input_type|
{
input_identifier: input_type.input_identifier,
data_type_identifier: input_type.data_type_identifier,
data_type_identifier_id: find_data_type_identifier(input_type.data_type_identifier, t).id,
data_type_identifier_id: find_data_type_identifier(input_type.data_type_identifier, db_rule, t).id,
}
end,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,11 @@ def update_runtime_function_definition(runtime_function_definition, t)
)
db_object.removed_at = nil
db_object.return_type = if runtime_function_definition.return_type_identifier.present?
find_data_type_identifier(runtime_function_definition.return_type_identifier, t)
find_data_type_identifier(
runtime_function_definition.return_type_identifier,
db_object,
t
)
end
db_object.names = update_translations(runtime_function_definition.name, db_object.names)
db_object.descriptions = update_translations(runtime_function_definition.description, db_object.descriptions)
Expand Down Expand Up @@ -106,7 +110,7 @@ def update_parameters(runtime_function_definition, parameters, db_parameters, t)
db_param.runtime_function_definition = runtime_function_definition
db_param.runtime_name = real_param.runtime_name
db_param.removed_at = nil
db_param.data_type = find_data_type_identifier(real_param.data_type_identifier, t)
db_param.data_type = find_data_type_identifier(real_param.data_type_identifier, db_param, t)

db_param.names = update_translations(real_param.name, db_param.names)
db_param.descriptions = update_translations(real_param.description, db_param.descriptions)
Expand Down
7 changes: 7 additions & 0 deletions db/migrate/20260131170109_add_owner_to_generic_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class AddOwnerToGenericType < Code0::ZeroTrack::Database::Migration[1.0]
def change
add_reference :generic_types, :owner, polymorphic: true
end
end
1 change: 1 addition & 0 deletions db/schema_migrations/20260131170109
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
c6ed271c0a902a25fb5a7ca5e7137a0fefa65ca1f652368cce2e2599af9f2b96
6 changes: 5 additions & 1 deletion db/structure.sql
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,9 @@ CREATE TABLE generic_types (
id bigint NOT NULL,
data_type_id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL
updated_at timestamp with time zone NOT NULL,
owner_type character varying,
owner_id bigint
);

CREATE SEQUENCE generic_types_id_seq
Expand Down Expand Up @@ -1125,6 +1127,8 @@ CREATE INDEX index_generic_mappers_on_runtime_id ON generic_mappers USING btree

CREATE INDEX index_generic_types_on_data_type_id ON generic_types USING btree (data_type_id);

CREATE INDEX index_generic_types_on_owner ON generic_types USING btree (owner_type, owner_id);

CREATE INDEX index_good_job_executions_on_active_job_id_and_created_at ON good_job_executions USING btree (active_job_id, created_at);

CREATE INDEX index_good_job_executions_on_process_id_and_created_at ON good_job_executions USING btree (process_id, created_at);
Expand Down
1 change: 1 addition & 0 deletions spec/factories/generic_types.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
factory :generic_type do
generic_mappers { [] }
data_type
owner { data_type }
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@
create(:data_type_identifier, runtime: runtime, data_type: create(:data_type, runtime: runtime))
end

let!(:generic_type) do
create(:generic_type, data_type: create(:data_type, runtime: runtime))
end
let!(:return_type) { create(:data_type_identifier, runtime: runtime, generic_type: generic_type.reload).reload }
let!(:generic_base_type) { create(:data_type, runtime: runtime) }

let(:runtime_functions) do
[
Expand All @@ -43,7 +40,7 @@
],
return_type_identifier: {
generic_type: {
data_type_identifier: return_type.generic_type.data_type.identifier,
data_type_identifier: generic_base_type.identifier,
generic_mappers: [{ source: [{ generic_key: 'T' }], target: 'V', generic_combinations: [] }],
},
},
Expand Down Expand Up @@ -87,7 +84,7 @@
function = RuntimeFunctionDefinition.last
expect(function.runtime_name).to eq('runtime_function_id')
expect(function.return_type.generic_type.reload.data_type.identifier)
.to eq(return_type.generic_type.data_type.identifier)
.to eq(generic_base_type.identifier)
expect(function.names.first.content).to eq('Eine Funktion')
expect(function.descriptions.first.content).to eq('Eine Funktionsbeschreibung')
expect(function.documentations.first.content).to eq('Eine Funktionsdokumentation')
Expand All @@ -111,7 +108,7 @@
expect(function_definition.aliases.first.content).to eq('Ein Funktionsalias')
expect(function_definition.display_messages.first.content).to eq('Eine Funktionsanzeige')
expect(function_definition.return_type.generic_type.reload.data_type.identifier)
.to eq(return_type.generic_type.data_type.identifier)
.to eq(generic_base_type.identifier)
parameter_definition = ParameterDefinition.first
expect(parameter_definition.data_type.data_type.identifier).to eq(parameter_type.data_type.identifier)
expect(parameter_definition.names.first.content).to eq('Ein Parameter')
Expand Down