Skip to content
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

Add GRPC Handler for RuntimeFunctionDefinition and RuntimeParameterDefinition #362

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
13 changes: 13 additions & 0 deletions app/grpc/runtime_function_handler.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

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

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

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

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

class RuntimeFunctionDefinition < ApplicationRecord
belongs_to :return_type, class_name: 'DataType'
belongs_to :namespace

has_many :parameters, class_name: 'RuntimeParameterDefinition', inverse_of: :runtime_function_definition

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

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

validates :name, length: { minimum: 3, maximum: 50 }, presence: true,
uniqueness: { case_sensitive: false, scope: :runtime_function_definition_id }
end
86 changes: 86 additions & 0 deletions app/services/runtime_function_definitions/update_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# frozen_string_literal: true

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|
runtime_function_definitions.each do |runtime_function_definition|
unless update_runtime_function_definition(runtime_function_definition, t)
t.rollback_and_return! ServiceResponse.error(message: 'Failed to update runtime function definition',
payload: runtime_function_definition.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(namespace: current_runtime.namespace,
runtime_name: runtime_function_definition.runtime_name)
if runtime_function_definition.return_type_identifier.present?
db_object.return_type = find_data_type(runtime_function_definition.return_type_identifier, t)
else
db_object.return_type = nil
end
db_object.parameters = update_parameters(runtime_function_definition.runtime_parameter_definitions, db_object.parameters, t)
db_object.translations = update_translations(runtime_function_definition.name, db_object.translations)
db_object.save
end

def find_data_type(identifier, t)
data_type = DataType.find_by(namespace: [nil, current_runtime.namespace], 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)
db_parameters.each do |db_param|
if parameters.find { |real_param| real_param.runtime_name == db_param.runtime_name }
db_param.removed_at = nil
else
db_param.removed_at = Time.zone.now
end
end

parameters.each do |real_param|
db_param = db_parameters.find { |db_param| db_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.datatype = find_data_type(real_param.data_type_identifier, t)
db_param.translations = update_translations(real_param.name, db_param.translations)
end

db_parameters
end

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

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

class CreateRuntimeFunctionDefinitions < Sagittarius::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 :namespace, null: false, index: false, foreign_key: { on_delete: :cascade }
t.text :runtime_name, null: false, limit: 50

t.index %i[namespace_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 < Sagittarius::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 :name, null: false, limit: 50

t.timestamp_with_timezone :removed_at, null: true

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

t.timestamps_with_timezone
end
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
76 changes: 72 additions & 4 deletions db/structure.sql
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ ALTER SEQUENCE audit_events_id_seq OWNED BY audit_events.id;

CREATE TABLE backup_codes (
id bigint NOT NULL,
token text NOT NULL,
token text,
user_id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
Expand Down Expand Up @@ -334,6 +334,44 @@ CREATE SEQUENCE organizations_id_seq

ALTER SEQUENCE organizations_id_seq OWNED BY organizations.id;

CREATE TABLE runtime_function_definitions (
id bigint NOT NULL,
return_type_id bigint NOT NULL,
namespace_id bigint NOT NULL,
runtime_name text NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
CONSTRAINT check_fe8fff4f27 CHECK ((char_length(runtime_name) <= 50))
);

CREATE SEQUENCE runtime_function_definitions_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;

ALTER SEQUENCE runtime_function_definitions_id_seq OWNED BY runtime_function_definitions.id;

CREATE TABLE runtime_parameter_definitions (
id bigint NOT NULL,
runtime_function_definition_id bigint NOT NULL,
data_type_id bigint NOT NULL,
name text NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
CONSTRAINT check_95aff0700e CHECK ((char_length(name) <= 50))
);

CREATE SEQUENCE runtime_parameter_definitions_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;

ALTER SEQUENCE runtime_parameter_definitions_id_seq OWNED BY runtime_parameter_definitions.id;

CREATE TABLE runtimes (
id bigint NOT NULL,
name text NOT NULL,
Expand Down Expand Up @@ -468,6 +506,10 @@ ALTER TABLE ONLY namespaces ALTER COLUMN id SET DEFAULT nextval('namespaces_id_s

ALTER TABLE ONLY organizations ALTER COLUMN id SET DEFAULT nextval('organizations_id_seq'::regclass);

ALTER TABLE ONLY runtime_function_definitions ALTER COLUMN id SET DEFAULT nextval('runtime_function_definitions_id_seq'::regclass);

ALTER TABLE ONLY runtime_parameter_definitions ALTER COLUMN id SET DEFAULT nextval('runtime_parameter_definitions_id_seq'::regclass);

ALTER TABLE ONLY runtimes ALTER COLUMN id SET DEFAULT nextval('runtimes_id_seq'::regclass);

ALTER TABLE ONLY translations ALTER COLUMN id SET DEFAULT nextval('translations_id_seq'::regclass);
Expand Down Expand Up @@ -538,6 +580,12 @@ ALTER TABLE ONLY namespaces
ALTER TABLE ONLY organizations
ADD CONSTRAINT organizations_pkey PRIMARY KEY (id);

ALTER TABLE ONLY runtime_function_definitions
ADD CONSTRAINT runtime_function_definitions_pkey PRIMARY KEY (id);

ALTER TABLE ONLY runtime_parameter_definitions
ADD CONSTRAINT runtime_parameter_definitions_pkey PRIMARY KEY (id);

ALTER TABLE ONLY runtimes
ADD CONSTRAINT runtimes_pkey PRIMARY KEY (id);

Expand All @@ -556,14 +604,20 @@ ALTER TABLE ONLY user_sessions
ALTER TABLE ONLY users
ADD CONSTRAINT users_pkey PRIMARY KEY (id);

CREATE UNIQUE INDEX idx_on_namespace_id_runtime_name_dba40f4549 ON runtime_function_definitions USING btree (namespace_id, runtime_name);

CREATE UNIQUE INDEX idx_on_namespace_role_id_ability_a092da8841 ON namespace_role_abilities USING btree (namespace_role_id, ability);

CREATE UNIQUE INDEX idx_on_role_id_project_id_5d4b5917dc ON namespace_role_project_assignments USING btree (role_id, project_id);

CREATE UNIQUE INDEX idx_on_runtime_function_definition_id_name_4860aebcbe ON runtime_parameter_definitions USING btree (runtime_function_definition_id, name);

CREATE UNIQUE INDEX index_application_settings_on_setting ON application_settings USING btree (setting);

CREATE INDEX index_audit_events_on_author_id ON audit_events USING btree (author_id);

CREATE INDEX index_backup_codes_on_user_id ON backup_codes USING btree (user_id);

CREATE UNIQUE INDEX "index_backup_codes_on_user_id_LOWER_token" ON backup_codes USING btree (user_id, lower(token));

CREATE INDEX index_data_type_rules_on_data_type_id ON data_type_rules USING btree (data_type_id);
Expand Down Expand Up @@ -626,6 +680,10 @@ CREATE UNIQUE INDEX index_namespaces_on_parent_id_and_parent_type ON namespaces

CREATE UNIQUE INDEX "index_organizations_on_LOWER_name" ON organizations USING btree (lower(name));

CREATE INDEX index_runtime_function_definitions_on_return_type_id ON runtime_function_definitions USING btree (return_type_id);

CREATE INDEX index_runtime_parameter_definitions_on_data_type_id ON runtime_parameter_definitions USING btree (data_type_id);

CREATE INDEX index_runtimes_on_namespace_id ON runtimes USING btree (namespace_id);

CREATE UNIQUE INDEX index_runtimes_on_token ON runtimes USING btree (token);
Expand All @@ -636,8 +694,6 @@ CREATE UNIQUE INDEX index_user_identities_on_provider_id_and_identifier ON user_

CREATE INDEX index_user_identities_on_user_id ON user_identities USING btree (user_id);

CREATE UNIQUE INDEX index_user_identities_on_user_id_and_provider_id ON user_identities USING btree (user_id, provider_id);

CREATE UNIQUE INDEX index_user_sessions_on_token ON user_sessions USING btree (token);

CREATE INDEX index_user_sessions_on_user_id ON user_sessions USING btree (user_id);
Expand All @@ -651,21 +707,27 @@ CREATE UNIQUE INDEX index_users_on_totp_secret ON users USING btree (totp_secret
ALTER TABLE ONLY namespace_roles
ADD CONSTRAINT fk_rails_205092c9cb FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;

ALTER TABLE ONLY runtime_parameter_definitions
ADD CONSTRAINT fk_rails_260318ad67 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE;

ALTER TABLE ONLY namespace_licenses
ADD CONSTRAINT fk_rails_38f693332d FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;

ALTER TABLE ONLY data_types
ADD CONSTRAINT fk_rails_4434ad0b90 FOREIGN KEY (parent_type_id) REFERENCES data_types(id) ON DELETE RESTRICT;

ALTER TABLE ONLY backup_codes
ADD CONSTRAINT fk_rails_556c1feac3 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
ADD CONSTRAINT fk_rails_556c1feac3 FOREIGN KEY (user_id) REFERENCES users(id);

ALTER TABLE ONLY namespace_members
ADD CONSTRAINT fk_rails_567f152a62 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;

ALTER TABLE ONLY namespace_member_roles
ADD CONSTRAINT fk_rails_585a684166 FOREIGN KEY (role_id) REFERENCES namespace_roles(id) ON DELETE CASCADE;

ALTER TABLE ONLY runtime_function_definitions
ADD CONSTRAINT fk_rails_5f0aa31141 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;

ALTER TABLE ONLY namespace_role_project_assignments
ADD CONSTRAINT fk_rails_623f8a5b72 FOREIGN KEY (role_id) REFERENCES namespace_roles(id);

Expand All @@ -681,6 +743,9 @@ ALTER TABLE ONLY namespace_member_roles
ALTER TABLE ONLY namespace_role_abilities
ADD CONSTRAINT fk_rails_6f3304b078 FOREIGN KEY (namespace_role_id) REFERENCES namespace_roles(id) ON DELETE CASCADE;

ALTER TABLE ONLY runtime_function_definitions
ADD CONSTRAINT fk_rails_73ca8569ea FOREIGN KEY (return_type_id) REFERENCES data_types(id) ON DELETE RESTRICT;

ALTER TABLE ONLY data_type_rules
ADD CONSTRAINT fk_rails_7759633ff8 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE CASCADE;

Expand All @@ -693,6 +758,9 @@ ALTER TABLE ONLY namespace_members
ALTER TABLE ONLY namespace_projects
ADD CONSTRAINT fk_rails_d4f50e2f00 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;

ALTER TABLE ONLY runtime_parameter_definitions
ADD CONSTRAINT fk_rails_e64f825793 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE RESTRICT;

ALTER TABLE ONLY runtimes
ADD CONSTRAINT fk_rails_eeb42116cc FOREIGN KEY (namespace_id) REFERENCES namespaces(id);

Expand Down
11 changes: 11 additions & 0 deletions spec/factories/runtime_function_definitions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

FactoryBot.define do
sequence(:runtime_function_definition_name) { |n| "runtime_function_definition#{n}" }

factory :runtime_function_definition do
runtime_name { generate(:runtime_function_definition_name) }
return_type factory: :data_type
namespace
end
end
11 changes: 11 additions & 0 deletions spec/factories/runtime_parameter_definitions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

FactoryBot.define do
sequence(:runtime_parameter_definition_name) { |n| "runtime_parameter_definition#{n}" }

factory :runtime_parameter_definition do
runtime_function_definition
data_type
name { generate(:runtime_parameter_definition_name) }
end
end
17 changes: 17 additions & 0 deletions spec/models/runtime_function_definition_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe RuntimeFunctionDefinition do
subject { create(:runtime_function_definition) }

describe 'validations' do
it { is_expected.to have_many(:parameters).inverse_of(:runtime_function_definition) }

it { is_expected.to validate_presence_of(:runtime_name) }
it { is_expected.to validate_uniqueness_of(:runtime_name).case_insensitive.scoped_to(:namespace_id) }
it { is_expected.to validate_length_of(:runtime_name).is_at_most(50) }

it { is_expected.to validate_presence_of(:namespace) }
end
end
16 changes: 16 additions & 0 deletions spec/models/runtime_parameter_definition_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe RuntimeParameterDefinition do
subject { create(:runtime_parameter_definition) }

describe 'validations' do
it { is_expected.to validate_presence_of(:name) }
it { is_expected.to validate_uniqueness_of(:name).case_insensitive.scoped_to(:runtime_function_definition_id) }
it { is_expected.to validate_length_of(:name).is_at_most(50) }

it { is_expected.to validate_presence_of(:runtime_function_definition) }
it { is_expected.to validate_presence_of(:data_type) }
end
end
Loading