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
4 changes: 2 additions & 2 deletions Gemfile.sqlite-vec.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
mxrb (0.1.2)
mxrb (0.1.3)
base64 (~> 0.2)
bigdecimal (~> 3.1)
bson (~> 5.2)
Expand Down Expand Up @@ -126,7 +126,7 @@ CHECKSUMS
json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583
language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0
lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
mxrb (0.1.2)
mxrb (0.1.3)
onnxruntime (0.11.5-arm64-darwin) sha256=9f2f45b3ac16999c466ac352562195e03a011cc930b8750c0b1e43a49c1ca5d9
onnxruntime (0.11.5-x86_64-darwin) sha256=19c18e90eb101f69a3232dfdd1742e77d69e2df623b106b670221629d4b4cc15
onnxruntime (0.11.5-x86_64-linux) sha256=13f20de606a8fb32ba404bca9e1fc47f0eab4605c909252dbcf6db4fb106c9e6
Expand Down
3 changes: 3 additions & 0 deletions bin/mxrb
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ end

SCAFFOLD_COMMANDS = (Mxrb::Scaffold::Help::COMMANDS.keys - ["design"]).freeze

progress_disabled = ARGV.delete("--no-progress")
command = ARGV.shift
Mxrb::Progress.configure(enabled: false) if progress_disabled || ARGV.include?("--json")

case command
when '--version', '-v'
Expand Down Expand Up @@ -1506,6 +1508,7 @@ else
mxrb — Pure-Ruby Mendix .mpr toolkit

Commands:
--no-progress Disable interactive progress rendering
--version, -v Show the installed MXRB version
doctor [DIR] [--json] Check project files and local toolchain
benchmark <file.mpr> Measure open, index and validation time
Expand Down
8 changes: 8 additions & 0 deletions docs/pt-BR/entity-dsl.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ entity :AnimalSearchResult do
string :Name
end

entity :AnimalSummaryView do
oql_view source: "VetClinic.AnimalSummarySource"
string :Name
integer :Total
end

entity :Animal do
before_commit microflow: "VetClinic.VAL_Animal"
after_commit microflow: "VetClinic.ACT_AfterAnimalCommit"
Expand All @@ -111,6 +117,8 @@ end

Em `access_rule`, `read:` e `write:` aceitam `:all`, `:none` ou uma lista de
atributos. Declare um ou mais papéis qualificados como primeiros argumentos.
`oql_view` liga a entidade ao `ViewEntitySourceDocument`; ao exportar um projeto
existente, a consulta OQL aparece junto da entidade em `domain/oql_views`.

Use `mxrb entity --help` para o comando e `mxrb generate project.rb` seguido de
`mxrb validate App.mpr` para validar o resultado.
28 changes: 28 additions & 0 deletions docs/pt-BR/writing.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
`mxrb generate` avalia uma definição Ruby e cria ou atualiza o MPR. Nomes
Mendix são chaves estáveis, portanto reaplicar a definição não duplica units.

Operações demoradas exibem progresso em `stderr` quando executadas em um
terminal interativo. Quando o total é conhecido, o MXRB mostra barra e
porcentagem; operações externas sem total confiável mostram spinner e tempo
decorrido. Pipes, redirecionamentos e saídas `--json` permanecem limpos. Use
`--no-progress` ou `MXRB_PROGRESS=0` para desativar explicitamente.

Para iniciar em uma pasta vazia:

```sh
Expand Down Expand Up @@ -122,6 +128,28 @@ usam `bson_binary`. Alterações nesse Ruby sobrepõem o baseline antes das escr
tipadas. Corpos de flow possuem `body_fingerprint`: o grafo nativo é reutilizado
quando o Ruby não mudou e regenerado após uma edição.

Export mappings, import mappings e JSON structures são materializados por
módulo em `infrastructure/mappings/{exports,imports,json_structures}`. Esses
arquivos mantêm `UnitID` e container/pasta originais, podem editar toda a
estrutura profunda em Ruby e têm precedência sobre o baseline durante o
`generate`.

Serviços REST, OData e web services publicados são exportados para
`infrastructure/endpoints`; recursos, operações, métodos HTTP, paths,
parâmetros e referências a microflows permanecem no mesmo arquivo Ruby.
Serviços consumidos são roteados para `infrastructure/integrations`, enquanto
message definitions e XML schemas ficam em `infrastructure/mappings`.

O Domain Model exportado separa entidades persistentes em `domain/entities`,
DTOs/non-persistent em `domain/dtos` e entidades de OQL View em
`domain/oql_views`. O arquivo da OQL View também contém seu
`DomainModels$ViewEntitySourceDocument`, portanto a consulta `Oql` pode ser
editada no mesmo Ruby sem perder a referência da entidade. Datasets OQL ficam
em `application/queries/datasets`; enumerations e constants ficam em
`domain/enumerations` e `domain/constants`. Scheduled events ficam em
`application/jobs/scheduled_events`. O `domain/model.rb` e o
`application/application.rb` carregam automaticamente todas essas categorias.

A DSL cobre criação/alteração/retrieve/commit/delete, chamadas de microflow,
Java, JavaScript, nanoflow e app service, páginas, REST, listas, decisões,
loops, eventos de erro e rescue.
Expand Down
19 changes: 12 additions & 7 deletions lib/mxrb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require_relative "mxrb/version"
require_relative "mxrb/errors"
require_relative "mxrb/progress"
require_relative "mxrb/doctor"
require_relative "mxrb/benchmark"
require_relative "mxrb/project_lifecycle"
Expand Down Expand Up @@ -139,14 +140,18 @@ module Mxrb
#
# Mxrb.open("MyApp.mpr") { |p| puts p.modules.map(&:name) }
#
def self.open(path, readonly: true, &block)
project = Model::Project.open(path, readonly: readonly)
return project unless block
def self.open(path, readonly: true, &block) # rubocop:disable Metrics/MethodLength
return Model::Project.open(path, readonly: readonly) unless block

begin
block.call(project)
ensure
project.close
Progress.with("Loading #{File.basename(path)}") do |progress|
progress.update(detail: "opening model")
project = Model::Project.open(path, readonly: readonly)
begin
progress.update(detail: "processing model")
block.call(project)
ensure
project.close
end
end
end

Expand Down
40 changes: 27 additions & 13 deletions lib/mxrb/compiler/packager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,24 @@ def initialize(mpr_path, deployment: nil)
@deployment = File.expand_path(deployment || File.join(@project_root, 'deployment'))
end

def pack(output:, force: false)
output_path = File.expand_path(output)
validate_input!(output_path, force:)
version = Mxrb.open(@mpr_path, &:mendix_version)
adapter = Adapter.for(version)
metadata = adapter.validate_deployment!(@deployment)
adapter.validate_freshness!(@mpr_path, @deployment)
files, directories = inventory
write_atomically(output_path, files, directories)
package_result(output_path, version, metadata)
def pack(output:, force: false) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
Progress.with("Packing #{File.basename(@mpr_path)}") do |progress|
output_path = File.expand_path(output)
validate_input!(output_path, force:)
version = Mxrb.open(@mpr_path, &:mendix_version)
adapter = Adapter.for(version)
metadata = adapter.validate_deployment!(@deployment)
adapter.validate_freshness!(@mpr_path, @deployment)
files, directories = inventory
progress.update(
current: 3, total: files.size + directories.size + 4,
detail: "#{files.size} files"
)
write_atomically(output_path, files, directories, progress)
package_result(output_path, version, metadata).tap do
progress.advance(detail: 'package checksum')
end
end
end

private
Expand Down Expand Up @@ -69,13 +77,19 @@ def relative(path)
path.delete_prefix("#{@deployment}/").tr('\\', '/')
end

def write_atomically(output, files, directories)
def write_atomically(output, files, directories, progress) # rubocop:disable Metrics/MethodLength
FileUtils.mkdir_p(File.dirname(output))
Dir.mktmpdir('mxrb-mda-', File.dirname(output)) do |tmpdir|
temporary = File.join(tmpdir, 'package.mda')
Zip::File.open(temporary, create: true) do |archive|
directories.each { add_directory(archive, _1) }
files.each { add_file(archive, _1) }
directories.each do |directory|
add_directory(archive, directory)
progress.advance(detail: relative(directory))
end
files.each do |file|
add_file(archive, file)
progress.advance(detail: relative(file))
end
end
FileUtils.mv(temporary, output, force: true)
end
Expand Down
27 changes: 16 additions & 11 deletions lib/mxrb/compiler/portable_packager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -309,17 +309,22 @@ def initialize(mpr_path, deployment: nil, mendix_home: nil)
@mendix_home = mendix_home && File.expand_path(mendix_home)
end

def pack(output:, force: false)
output_path = File.expand_path(output)
validate_output!(output_path, force:)
version = Mxrb.open(@mpr_path, &:mendix_version)
adapter = Adapter.for(version)
metadata = adapter.validate_deployment!(@deployment)
adapter.validate_freshness!(@mpr_path, @deployment)
runtime = runtime_root(version)
validate_runtime!(runtime)
PortableArchiveWriter.new(@deployment, runtime, metadata).write(output_path)
result(output_path, version, metadata)
def pack(output:, force: false) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
Progress.with("Packing portable Runtime for #{File.basename(@mpr_path)}") do |progress|
output_path = File.expand_path(output)
validate_output!(output_path, force:)
progress.update(detail: 'validating deployment')
version = Mxrb.open(@mpr_path, &:mendix_version)
adapter = Adapter.for(version)
metadata = adapter.validate_deployment!(@deployment)
adapter.validate_freshness!(@mpr_path, @deployment)
runtime = runtime_root(version)
validate_runtime!(runtime)
progress.update(detail: 'writing Runtime archive')
PortableArchiveWriter.new(@deployment, runtime, metadata).write(output_path)
progress.update(detail: 'calculating checksum')
result(output_path, version, metadata)
end
end

private
Expand Down
21 changes: 19 additions & 2 deletions lib/mxrb/dsl/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -872,15 +872,21 @@ def scheduled_event(name, microflow:, interval: 1, unit: :days, enabled: true, &
@scheduled_events << sb.to_h
end

def native_document(name, type:, deep_structure:, containment: 'Documents')
def native_document(name, type:, deep_structure:, containment: 'Documents',
unit_id: nil, container_id: nil)
raise ArgumentError, 'deep_structure requires a Hash' unless deep_structure.is_a?(Hash)

@native_documents << {
name: name.to_s, type: type.to_s, containment: containment.to_s,
unit_id: unit_id&.to_s, container_id: container_id&.to_s,
doc: { '$Type' => type.to_s, 'Name' => name.to_s }.merge(deep_structure)
}
end

def bson_binary(base64, subtype: :generic)
BSON::Binary.new(Base64.strict_decode64(base64), subtype.to_sym)
end

# Native responsive application shell. It deliberately uses only Mendix
# core widgets, so generated projects do not depend on Atlas Core merely
# to display their navigation.
Expand Down Expand Up @@ -1070,6 +1076,7 @@ def initialize(name)
@generalization = nil
@system_members = nil
@indexes = nil
@oql_view = nil
end

ATTR_TYPES.each do |type|
Expand All @@ -1081,6 +1088,16 @@ def initialize(name)
def non_persistent! = (@persistable = false)
def documentation(d) = (@doc = d)

# Marks an entity as an OQL-backed view. Modern Mendix projects keep the
# query in a separate ViewEntitySourceDocument; older projects may keep
# it directly on the embedded entity.
def oql_view(source: nil, query: nil)
raise ArgumentError, 'oql_view requires source or query' if source.nil? && query.nil?

@oql_view = { source: source&.to_s, query: query&.to_s }.compact
@persistable = false
end

def generalizes(entity)
@generalization = entity.to_s
end
Expand Down Expand Up @@ -1164,7 +1181,7 @@ def to_h
name: @name, persistable: @persistable, documentation: @doc,
attributes: @attributes, associations: @associations, lifecycle: @lifecycle,
access_rules: @access_rules, generalization: @generalization,
system_members: @system_members, indexes: @indexes
system_members: @system_members, indexes: @indexes, oql_view: @oql_view
}
end

Expand Down
Loading
Loading