Skip to content

Add GRPC Handler for RuntimeFunctionDefinition and RuntimeParameterDefinition #362

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ gem 'good_job', '~> 4.0'
gem 'rotp'

gem 'grpc', '~> 1.67'
gem 'tucana', '0.0.15'
gem 'tucana', '0.0.17'

gem 'code0-identities', '~> 0.0.1'

Expand Down
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ GEM
test-prof (1.4.4)
thor (1.3.2)
timeout (0.4.3)
tucana (0.0.15)
tucana (0.0.17)
grpc (~> 1.64)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
Expand Down Expand Up @@ -405,7 +405,7 @@ DEPENDENCIES
simplecov (~> 0.22.0)
simplecov-cobertura (~> 2.1)
test-prof (~> 1.0)
tucana (= 0.0.15)
tucana (= 0.0.17)
tzinfo-data

RUBY VERSION
Expand Down
16 changes: 16 additions & 0 deletions app/grpc/runtime_function_handler.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

class RuntimeFunctionHandler < Tucana::Sagittarius::RuntimeFunctionDefinitionService::Service
include GrpcHandler

def update(request, _call)
current_runtime = Runtime.find(Code0::ZeroTrack::Context.current[:runtime][:id])

response = Runtimes::RuntimeFunctionDefinitions::UpdateService.new(
current_runtime,
request.runtime_functions
).execute

Tucana::Sagittarius::RuntimeFunctionDefinitionUpdateResponse.new(success: response.success?)
end
end
10 changes: 10 additions & 0 deletions app/models/function_definition.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

class FunctionDefinition < ApplicationRecord
belongs_to :runtime_function_definition
belongs_to :return_type, class_name: 'DataType', optional: true

has_many :names, -> { by_purpose(:name) }, class_name: 'Translation', as: :owner, inverse_of: :owner
has_many :descriptions, -> { by_purpose(:description) }, class_name: 'Translation', as: :owner, inverse_of: :owner
has_many :documentations, -> { by_purpose(:documentation) }, class_name: 'Translation', as: :owner, inverse_of: :owner
end
10 changes: 10 additions & 0 deletions app/models/parameter_definition.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

class ParameterDefinition < ApplicationRecord
belongs_to :runtime_parameter_definition
belongs_to :data_type

has_many :names, -> { by_purpose(:name) }, class_name: 'Translation', as: :owner, inverse_of: :owner
has_many :descriptions, -> { by_purpose(:description) }, class_name: 'Translation', as: :owner, inverse_of: :owner
has_many :documentations, -> { by_purpose(:documentation) }, class_name: 'Translation', as: :owner, inverse_of: :owner
end
14 changes: 14 additions & 0 deletions app/models/runtime_function_definition.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

class RuntimeFunctionDefinition < ApplicationRecord
belongs_to :return_type, class_name: 'DataType', optional: true
belongs_to :runtime

has_many :function_definitions, inverse_of: :runtime_function_definition
has_many :parameters, class_name: 'RuntimeParameterDefinition', inverse_of: :runtime_function_definition
has_many :names, -> { by_purpose(:name) }, class_name: 'Translation', as: :owner, inverse_of: :owner

validates :runtime_name, presence: true,
length: { minimum: 3, maximum: 50 },
uniqueness: { case_sensitive: false, scope: :runtime_id }
end
12 changes: 12 additions & 0 deletions app/models/runtime_parameter_definition.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

class RuntimeParameterDefinition < ApplicationRecord
belongs_to :runtime_function_definition, inverse_of: :parameters
belongs_to :data_type

has_many :names, -> { by_purpose(:name) }, class_name: 'Translation', as: :owner, inverse_of: :owner
has_many :parameter_definitions, inverse_of: :runtime_parameter_definition

validates :runtime_name, length: { minimum: 3, maximum: 50 }, presence: true,
uniqueness: { case_sensitive: false, scope: :runtime_function_definition_id }
end
2 changes: 2 additions & 0 deletions app/models/translation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ class Translation < ApplicationRecord

validates :code, presence: true
validates :content, presence: true

scope :by_purpose, ->(purpose) { where(purpose: purpose) }
end
108 changes: 108 additions & 0 deletions app/services/runtimes/runtime_function_definitions/update_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# frozen_string_literal: true

module Runtimes
module RuntimeFunctionDefinitions
class UpdateService
include Sagittarius::Database::Transactional

attr_reader :current_runtime, :runtime_function_definitions

def initialize(current_runtime, runtime_function_definitions)
@current_runtime = current_runtime
@runtime_function_definitions = runtime_function_definitions
end

def execute
transactional do |t|
# rubocop:disable Rails/SkipsModelValidations -- when marking definitions as removed, we don't care about validations
RuntimeFunctionDefinition.where(runtime: current_runtime).update_all(removed_at: Time.zone.now)
# rubocop:enable Rails/SkipsModelValidations
runtime_function_definitions.each do |runtime_function_definition|
response = update_runtime_function_definition(runtime_function_definition, t)
unless response.persisted?
t.rollback_and_return! ServiceResponse.error(message: 'Failed to update runtime function definition',
payload: response.errors)
end
end

ServiceResponse.success(message: 'Updated runtime function definition', payload: runtime_function_definitions)
end
end

protected

def update_runtime_function_definition(runtime_function_definition, t)
db_object = RuntimeFunctionDefinition.find_or_initialize_by(
runtime: current_runtime,
runtime_name: runtime_function_definition.runtime_name
)
db_object.removed_at = nil
db_object.return_type = if runtime_function_definition.return_type_identifier.present?
find_data_type(runtime_function_definition.return_type_identifier, t)
end
db_object.parameters = update_parameters(runtime_function_definition.runtime_parameter_definitions,
db_object.parameters, t)
db_object.names = update_translations(runtime_function_definition.name, db_object.names)

if db_object.function_definitions.empty?
definition = FunctionDefinition.new
definition.names = update_translations(runtime_function_definition.name, definition.names)
definition.return_type = db_object.return_type

db_object.function_definitions << definition
end
db_object.save
db_object
end

def find_data_type(identifier, t)
data_type = DataType.find_by(runtime: current_runtime, identifier: identifier)

if data_type.nil?
t.rollback_and_return! ServiceResponse.error(message: "Could not find datatype with identifier #{identifier}",
payload: :no_datatype_for_identifier)
end

data_type
end

def update_parameters(parameters, db_parameters, t)
# rubocop:disable Rails/SkipsModelValidations -- when marking definitions as removed, we don't care about validations
db_parameters.update_all(removed_at: Time.zone.now)
# rubocop:enable Rails/SkipsModelValidations

parameters.each do |real_param|
db_param = db_parameters.find { |current_param| current_param.runtime_name == real_param.runtime_name }
if db_param.nil?
db_param = RuntimeParameterDefinition.new
db_parameters << db_param
end
db_param.runtime_name = real_param.runtime_name
db_param.removed_at = nil
db_param.data_type = find_data_type(real_param.data_type_identifier, t)
db_param.names = update_translations(real_param.name, db_param.names)

next unless db_param.parameter_definitions.empty?

definition = ParameterDefinition.new
definition.names = update_translations(real_param.name, definition.names)
definition.data_type = db_param.data_type

db_param.parameter_definitions << definition
end

db_parameters
end

def update_translations(real_translations, translation_relation)
db_translations = translation_relation.first(real_translations.length)
real_translations.each_with_index do |translation, index|
db_translations[index] ||= translation_relation.build
db_translations[index].assign_attributes(code: translation.code, content: translation.content)
end

db_translations
end
end
end
end
17 changes: 17 additions & 0 deletions db/migrate/20250112173532_create_runtime_function_definitions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

class CreateRuntimeFunctionDefinitions < Code0::ZeroTrack::Database::Migration[1.0]
def change
create_table :runtime_function_definitions do |t|
t.references :return_type, null: true, foreign_key: { to_table: :data_types, on_delete: :restrict }
t.references :runtime, null: false, index: false, foreign_key: { on_delete: :cascade }
t.text :runtime_name, null: false, limit: 50

t.datetime_with_timezone :removed_at, null: true

t.index %i[runtime_id runtime_name], unique: true

t.timestamps_with_timezone
end
end
end
17 changes: 17 additions & 0 deletions db/migrate/20250112174055_create_runtime_parameter_definitions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

class CreateRuntimeParameterDefinitions < Code0::ZeroTrack::Database::Migration[1.0]
def change
create_table :runtime_parameter_definitions do |t|
t.references :runtime_function_definition, index: false, null: false, foreign_key: { on_delete: :cascade }
t.references :data_type, null: false, foreign_key: { on_delete: :restrict }
t.text :runtime_name, null: false, limit: 50

t.datetime_with_timezone :removed_at, null: true

t.index %i[runtime_function_definition_id runtime_name], unique: true

t.timestamps_with_timezone
end
end
end
13 changes: 13 additions & 0 deletions db/migrate/20250202193702_create_function_definitions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

class CreateFunctionDefinitions < Code0::ZeroTrack::Database::Migration[1.0]
def change
create_table :function_definitions do |t|
t.references :runtime_function_definition, null: false, foreign_key: { on_delete: :cascade }

t.references :return_type, null: true, foreign_key: { to_table: :data_types, on_delete: :restrict }

t.timestamps_with_timezone
end
end
end
13 changes: 13 additions & 0 deletions db/migrate/20250202193919_create_parameter_definitions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

class CreateParameterDefinitions < Code0::ZeroTrack::Database::Migration[1.0]
def change
create_table :parameter_definitions do |t|
t.references :runtime_parameter_definition, null: false, foreign_key: { on_delete: :cascade }
t.references :data_type, null: false, foreign_key: { on_delete: :restrict }
t.jsonb :default_value, null: true

t.timestamps_with_timezone
end
end
end
7 changes: 7 additions & 0 deletions db/migrate/20250318210403_add_purpose_to_translations.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class AddPurposeToTranslations < Code0::ZeroTrack::Database::Migration[1.0]
def change
add_column :translations, :purpose, :text
end
end
1 change: 1 addition & 0 deletions db/schema_migrations/20250112173532
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a0d27be6aad8dae7984bcdd0852e46534776bca0e0714f6ace3c5ff76870dac8
1 change: 1 addition & 0 deletions db/schema_migrations/20250112174055
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
98c5428b47c9184d281251a4db05a97bc964686db899bd88f37f7936a517d1f6
1 change: 1 addition & 0 deletions db/schema_migrations/20250202193702
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
499a2dbfbc7f73d2c026c1dbe0c5acf742c5955d13017793486a77ea2bff3e9f
1 change: 1 addition & 0 deletions db/schema_migrations/20250202193919
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
d0be45016d71e376ef308818c8b8f68cba3a6fa1bac4ac845d10556445e55021
1 change: 1 addition & 0 deletions db/schema_migrations/20250318210403
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
039ea3147f26dee7f83f28a724d6c98033c6362337d2dd3c4b9a057294535207
Loading