Class: Mxrb::Model::Project

Inherits:
Object
  • Object
show all
Defined in:
lib/mxrb/model/project.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(mpr) ⇒ Project

Returns a new instance of Project.



14
15
16
# File 'lib/mxrb/model/project.rb', line 14

def initialize(mpr)
  @mpr = mpr
end

Instance Attribute Details

#mprObject (readonly)

Returns the value of attribute mpr.



8
9
10
# File 'lib/mxrb/model/project.rb', line 8

def mpr
  @mpr
end

Class Method Details

.open(path, readonly: true) ⇒ Object



10
11
12
# File 'lib/mxrb/model/project.rb', line 10

def self.open(path, readonly: true)
  new(IO::MprFile.open(path, readonly: readonly))
end

Instance Method Details

#add_attribute!(entity, name:, type: :string, **opts) ⇒ Object



115
116
# File 'lib/mxrb/model/project.rb', line 115

def add_attribute!(entity, name:, type: :string, **opts) =
plan_add_attribute(entity, name: name, type: type, **opts).apply!

#add_entity!(mod, name:, **opts) ⇒ Object



128
# File 'lib/mxrb/model/project.rb', line 128

def add_entity!(mod, name:, **opts) = plan_add_entity(mod, name: name, **opts).apply!

#all_unitsObject

── Low-level exploration ───────────────────────────────────────────



45
# File 'lib/mxrb/model/project.rb', line 45

def all_units   = @mpr.all_units

#analyze(**options) ⇒ Object Also known as: lint



108
# File 'lib/mxrb/model/project.rb', line 108

def analyze(**options) = Semantic::Analyzer.new(self).analyze(**options)

#architecture_definitionObject



52
# File 'lib/mxrb/model/project.rb', line 52

def architecture_definition = @mpr.architecture_definition

#batch_plan(plans) ⇒ Object

── Batch plan ──────────────────────────────────────────────────────────



136
# File 'lib/mxrb/model/project.rb', line 136

def batch_plan(plans) = Semantic::BatchPlan.new(project: self, plans: Array(plans))

#callees_of(name) ⇒ Object



94
# File 'lib/mxrb/model/project.rb', line 94

def callees_of(name) = semantic_index.callees_of(name)

#callers_of(name) ⇒ Object



93
# File 'lib/mxrb/model/project.rb', line 93

def callers_of(name) = semantic_index.callers_of(name)

#change_attribute!(attribute, **updates) ⇒ Object



124
# File 'lib/mxrb/model/project.rb', line 124

def change_attribute!(attribute, **updates) = plan_change_attribute(attribute, **updates).apply!

#children_of(uuid) ⇒ Object



50
# File 'lib/mxrb/model/project.rb', line 50

def children_of(uuid) = @mpr.children_of(uuid)

#clear_semantic_cache!Object



79
80
81
82
83
# File 'lib/mxrb/model/project.rb', line 79

def clear_semantic_cache!
  removed = @mpr.clear_index_cache!
  @semantic_index = nil
  removed
end

#closeObject



180
# File 'lib/mxrb/model/project.rb', line 180

def close = @mpr.close

#describe_artifact(name) ⇒ Object



90
# File 'lib/mxrb/model/project.rb', line 90

def describe_artifact(name) = semantic_index.describe(name)

#design_systemObject



39
# File 'lib/mxrb/model/project.rb', line 39

def design_system = (@design_system ||= DesignSystem.new(File.dirname(@mpr.path)))

#entitiesObject



28
# File 'lib/mxrb/model/project.rb', line 28

def entities    = modules.flat_map(&:entities)

#evaluate(&block) ⇒ Object



137
138
139
# File 'lib/mxrb/model/project.rb', line 137

def evaluate(&block)
  Evaluation::Suite.new(self).tap { _1.instance_eval(&block) }.run
end

#extract!(name, as:, object_ids:) ⇒ Object



105
# File 'lib/mxrb/model/project.rb', line 105

def extract!(name, as:, object_ids:) = plan_extract(name, as: as, object_ids: object_ids).apply!

#find_artifact(name, kind: nil) ⇒ Object



84
# File 'lib/mxrb/model/project.rb', line 84

def find_artifact(name, kind: nil) = semantic_index.find(name, kind: kind)

#format_versionObject



20
# File 'lib/mxrb/model/project.rb', line 20

def format_version  = @mpr.format_version

#impact_of(name, transitive: true) ⇒ Object



95
96
# File 'lib/mxrb/model/project.rb', line 95

def impact_of(name, transitive: true) =
semantic_index.impact_of(name, transitive: transitive)

#inline!(name, calling:) ⇒ Object



107
# File 'lib/mxrb/model/project.rb', line 107

def inline!(name, calling:) = plan_inline(name, calling: calling).apply!

#inspectObject



182
183
184
# File 'lib/mxrb/model/project.rb', line 182

def inspect
  "#<Mxrb::Project name=#{name.inspect} version=#{mendix_version.inspect} format=#{format_version}>"
end

#mendix_versionObject



19
# File 'lib/mxrb/model/project.rb', line 19

def mendix_version  = @mpr.mendix_version

#microflowsObject



30
# File 'lib/mxrb/model/project.rb', line 30

def microflows  = modules.flat_map(&:microflows)

#migrate_to!(version) ⇒ Object Also known as: upgrade_to!, downgrade_to!

Structurally migrates the project to a different Mendix version. Requires an MXRB architecture definition stored in the MPR (i.e. the project was generated by MXRB). Re-runs the Writer with the target version so all version-specific BSON structures are regenerated correctly. Idempotent — safe to call multiple times.

Raises:

  • (ArgumentError)


146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/mxrb/model/project.rb', line 146

def migrate_to!(version)
  v = version.to_s
  raise ArgumentError, "version must be a non-empty string" if v.empty?

  definition = @mpr.architecture_definition
  raise ArgumentError,
        "no MXRB architecture definition found in this MPR — " \
        "structural migration requires a project generated by MXRB" unless definition

  path    = @mpr.path
  readonly = @mpr.readonly?
  raise ArgumentError, "project is opened read-only; reopen with readonly: false" if readonly

  updated = definition.merge(version: v)
  @mpr.close
  Writer.new(path, updated).write!
  @mpr = IO::MprFile.open(path, readonly: false)
  @mpr.update_version!(v)
  refresh!
  self
end

#modulesObject

── Artefacts ──────────────────────────────────────────────────────



24
25
26
# File 'lib/mxrb/model/project.rb', line 24

def modules
  @modules ||= @mpr.units_by_containment("Modules").map { Module.new(_1, @mpr) }
end

#move!(name, to:) ⇒ Object



102
# File 'lib/mxrb/model/project.rb', line 102

def move!(name, to:) = plan_move(name, to: to).apply!

#nameObject



18
# File 'lib/mxrb/model/project.rb', line 18

def name            = @mpr.project_name


32
33
34
35
36
37
# File 'lib/mxrb/model/project.rb', line 32

def navigation
  @navigation ||= begin
    raw = all_units.find { parse_bson(_1)["$Type"] == "Navigation$NavigationDocument" }
    Navigation.new(raw && parse_bson(raw))
  end
end

#oql?Boolean

Returns:

  • (Boolean)


57
# File 'lib/mxrb/model/project.rb', line 57

def oql? = !oql_queries.empty?

#oql_analysis(dialect: :postgresql) ⇒ Object



62
63
64
65
# File 'lib/mxrb/model/project.rb', line 62

def oql_analysis(dialect: :postgresql)
  analyzer = Oql::Analyzer.new(dialect:)
  oql_queries.map { analyzer.analyze(_1) }.freeze
end

#oql_queriesObject

── Native OQL inspection ───────────────────────────────────────────



56
# File 'lib/mxrb/model/project.rb', line 56

def oql_queries = (@oql_catalog ||= Oql::Catalog.new(self)).queries

#oql_sql_views(dialect: :postgresql) ⇒ Object



58
59
60
61
# File 'lib/mxrb/model/project.rb', line 58

def oql_sql_views(dialect: :postgresql)
  translator = Oql::Translator.new(dialect:)
  oql_queries.map { translator.translate(_1) }.freeze
end

#pagesObject



29
# File 'lib/mxrb/model/project.rb', line 29

def pages       = modules.flat_map(&:pages)

#parse_bson(raw) ⇒ Object



51
# File 'lib/mxrb/model/project.rb', line 51

def parse_bson(raw)   = @mpr.parse_contents(raw)

#plan_add_attribute(entity, name:, type: :string, **opts) ⇒ Object

── Domain model mutation ───────────────────────────────────────────────



113
114
# File 'lib/mxrb/model/project.rb', line 113

def plan_add_attribute(entity, name:, type: :string, **opts) =
Semantic::DomainMutator.new(self).plan_add_attribute(entity, name: name, type: type, **opts)

#plan_add_entity(mod, name:, **opts) ⇒ Object



126
127
# File 'lib/mxrb/model/project.rb', line 126

def plan_add_entity(mod, name:, **opts) =
Semantic::DomainMutator.new(self).plan_add_entity(mod, name: name, **opts)

#plan_change_attribute(attribute, **updates) ⇒ Object



122
123
# File 'lib/mxrb/model/project.rb', line 122

def plan_change_attribute(attribute, **updates) =
Semantic::DomainMutator.new(self).plan_change_attribute(attribute, **updates)

#plan_design_token_migration(replacements) ⇒ Object



40
41
# File 'lib/mxrb/model/project.rb', line 40

def plan_design_token_migration(replacements) =
design_system.plan_literal_migration(replacements)

#plan_extract(name, as:, object_ids:) ⇒ Object



103
104
# File 'lib/mxrb/model/project.rb', line 103

def plan_extract(name, as:, object_ids:) =
Semantic::Extractor.new(self).plan(name, as: as, object_ids: object_ids)

#plan_inline(name, calling:) ⇒ Object



106
# File 'lib/mxrb/model/project.rb', line 106

def plan_inline(name, calling:) = Semantic::Inliner.new(self).plan(name, calling: calling)

#plan_move(name, to:) ⇒ Object



101
# File 'lib/mxrb/model/project.rb', line 101

def plan_move(name, to:) = Semantic::Mover.new(self).plan(name, to: to)

#plan_remove(name) ⇒ Object



99
# File 'lib/mxrb/model/project.rb', line 99

def plan_remove(name) = Semantic::Remover.new(self).plan(name)

#plan_remove_attribute(attribute) ⇒ Object



118
119
# File 'lib/mxrb/model/project.rb', line 118

def plan_remove_attribute(attribute) =
Semantic::DomainMutator.new(self).plan_remove_attribute(attribute)

#plan_remove_entity(entity) ⇒ Object



130
131
# File 'lib/mxrb/model/project.rb', line 130

def plan_remove_entity(entity) =
Semantic::DomainMutator.new(self).plan_remove_entity(entity)

#plan_rename(name, to:) ⇒ Object



97
# File 'lib/mxrb/model/project.rb', line 97

def plan_rename(name, to:) = Semantic::Renamer.new(self).plan(name, to: to)

#query(sql, *b) ⇒ Object



48
# File 'lib/mxrb/model/project.rb', line 48

def query(sql, *b) = @mpr.query(sql, *b)

#raw_unit(uuid) ⇒ Object



49
# File 'lib/mxrb/model/project.rb', line 49

def raw_unit(uuid) = @mpr.unit(uuid)

#references_from(name) ⇒ Object



92
# File 'lib/mxrb/model/project.rb', line 92

def references_from(name) = semantic_index.references_from(name)

#references_to(name) ⇒ Object



91
# File 'lib/mxrb/model/project.rb', line 91

def references_to(name) = semantic_index.references_to(name)

#refresh!Object



171
172
173
174
175
176
177
178
# File 'lib/mxrb/model/project.rb', line 171

def refresh!
  @modules = nil
  @semantic_index = nil
  @navigation = nil
  @design_system = nil
  @oql_catalog = nil
  self
end

#remove!(name) ⇒ Object



100
# File 'lib/mxrb/model/project.rb', line 100

def remove!(name) = plan_remove(name).apply!

#remove_attribute!(attribute) ⇒ Object



120
# File 'lib/mxrb/model/project.rb', line 120

def remove_attribute!(attribute) = plan_remove_attribute(attribute).apply!

#remove_entity!(entity) ⇒ Object



132
# File 'lib/mxrb/model/project.rb', line 132

def remove_entity!(entity) = plan_remove_entity(entity).apply!

#rename!(name, to:) ⇒ Object



98
# File 'lib/mxrb/model/project.rb', line 98

def rename!(name, to:) = plan_rename(name, to: to).apply!

#search_artifacts(query, **filters) ⇒ Object



85
# File 'lib/mxrb/model/project.rb', line 85

def search_artifacts(query, **filters) = semantic_index.search(query, **filters)

#semantic_cache_infoObject



70
71
72
73
74
# File 'lib/mxrb/model/project.rb', line 70

def semantic_cache_info
  @mpr.index_cache_info(
    current_fingerprint: Semantic::Index.fingerprint(self)
  )
end

#semantic_indexObject

── Semantic analysis ───────────────────────────────────────────────



69
# File 'lib/mxrb/model/project.rb', line 69

def semantic_index = (@semantic_index ||= Semantic::Index.new(self))

#semantic_search_artifacts(query, **options) ⇒ Object



86
87
# File 'lib/mxrb/model/project.rb', line 86

def semantic_search_artifacts(query, **options) =
semantic_index.semantic_search_artifacts(query, **options)

#semantic_search_hits(query, **options) ⇒ Object



88
89
# File 'lib/mxrb/model/project.rb', line 88

def semantic_search_hits(query, **options) =
semantic_index.semantic_search_hits(query, **options)

#table_info(n) ⇒ Object



47
# File 'lib/mxrb/model/project.rb', line 47

def table_info(n) = @mpr.table_info(n)

#tablesObject



46
# File 'lib/mxrb/model/project.rb', line 46

def tables      = @mpr.tables

#warm_semantic_cache!Object



75
76
77
78
# File 'lib/mxrb/model/project.rb', line 75

def warm_semantic_cache!
  semantic_index
  semantic_cache_info
end