Oihana PHP Arango

ArangoDoctorAction uses trait:short, trait:short, trait:short, trait:short, trait:short, \oihana\commands\traits\IOTrait

The structure health check of the ArangoDB database — the global counterpart of the `views` action.

For every configured model (ArangoModelsTrait::$models), the action compares the declared structure with the server state through DoctorTrait::diagnose() — the collection (existence, type), the declared AQL::INDEXES (the lazy provisioning only creates them with the collection: an index added to an existing model is otherwise never created) and the declared AQL::VIEW.

Three modes, dry-run first:

  • default : report only. The exit code fails as soon as something is missing, drifted, invalid or unreachable — doctor green means the structure matches the declarations (CI-friendly). Orphans are reported but never fail.
  • --apply : repairs through DoctorTrait::repair() — creates the missing collections (with their indexes) and indexes, resynchronizes the views. Drifted indexes are only announced unless --force is added (an index is immutable: repairing means drop + recreate, with a window where queries lose it).
  • --prune : offers an interactive selection of the orphans (collections and views on the server that no configured model declares) to remove — never automatic, nothing in non-interactive mode.

Beyond the models, the action also reconciles two database-level registries: the collection-index registry (ArangoIndexesTrait) and the custom analyzer registry (ArangoAnalyzersTrait). For the analyzers it creates the missing ones under --apply and only signals the drifted ones — an analyzer is immutable, so repairing a drift (a cascade to the dependent Views) is never done here, even with --force: it is reserved for the dedicated arango:analyzers action (--fix / --force).

Like views --diff, the walk is side-effect free: the lazy provisioning of the resolved models is disabled through the container lazy entry.

Tags
author

Marc Alcaraz (ekameleon)

since
1.2.0

Table of Contents

Properties

$analyzers  : array<int, AnalyzerDefinition>|AnalyzerDefinition
The declared custom analyzers — a list of {@see AnalyzerDefinition} (a single one is tolerated in place of a one-element list).
$collectionIndexes  : array<string, IndexDefinition|IndexOptions|array<int, mixed>>
The collection→indexes registry — `[ collectionName => IndexOptions[] ]` (a single {@see IndexDefinition} / {@see IndexOptions} value object is tolerated in place of a one-element list).
$migrationsCollection  : string
The tracking collection name (one per database).
$migrationsNamespace  : string
The PHP namespace the version classes are declared in (e.g. `fr\bouney\migrations`).
$migrationsPath  : string|null
The directory holding the `Version*.php` migration files.
$models  : array<int, string>
Container ids of the `Documents` models to inspect.

Methods

getAnalyzerDefinitions()  : array<int, AnalyzerDefinition>
Returns the declared analyzers normalized to a flat {@see AnalyzerDefinition} list: a lone `AnalyzerDefinition` becomes a one-element list, and any entry that is not an `AnalyzerDefinition` is dropped (defensive against a malformed declaration).
agent()  : string
The acting agent (`user@host`) stamped on the tracking documents — shared by the `migrate` runs and the `doctor --apply` journal.
buildDatabase()  : Database|null
Builds a best-effort {@see Database} HTTP client from the resolved connection settings, or null when no usable endpoint/database is available or the client cannot be constructed.
doctor()  : int
Diagnoses (or repairs) the declared structure of the database.
gitCommit()  : string|null
The current git commit hash, or null outside a git repository — the history link stamped on every tracking document.
resolveDatabase()  : Database|null
Builds the best-effort {@see Database} HTTP client of an action run: every connection setting reads its CLI option first (`--database` / `--endpoint` / `--user` / `--password`) and falls back on the command configuration ({@see ArangoConfigTrait}).
resolveFacade()  : ArangoDB|null
Builds the best-effort high-level {@see ArangoDB} façade of an action run, from the same resolved connection settings as {@see resolveDatabase()} — the migration engine hands this façade to every {@see \oihana\arango\migrations\Migration}. Null when no usable endpoint is configured or the façade cannot be constructed.
doctorAccount()  : void
Accounts one diff report into the running doctor state: renders it, bumps the status counter, flips the health flag when the report is not in sync (and was not freshly applied), and collects it when applied. Shared by the model walk and the collection-index registry walk.
doctorJournal()  : void
Journals each applied object as a `CreateAction` in the tracking collection — the audit trail of `doctor --apply`, told apart from the versioned migrations by its `additionalType` ({@see MigrationKind::DOCTOR}).
doctorOrphans()  : array<int, string>
Computes and prints the orphans — collections (non-system) and views on the server that no configured model declares. Report only.
doctorPrune()  : void
Offers the interactive multi-selection of the orphans to remove and drops the chosen ones. Nothing happens in non-interactive mode.
doctorRenderReport()  : void
Prints one {@see DiffReport} as a status line (labelled with its {@see DiffKind}) plus one indented line per change.

Properties

$collectionIndexes

The collection→indexes registry — `[ collectionName => IndexOptions[] ]` (a single {@see IndexDefinition} / {@see IndexOptions} value object is tolerated in place of a one-element list).

public array<string, IndexDefinition|IndexOptions|array<int, mixed>> $collectionIndexes = []

$migrationsCollection

The tracking collection name (one per database).

public string $migrationsCollection = 'migrations'

$migrationsNamespace

The PHP namespace the version classes are declared in (e.g. `fr\bouney\migrations`).

public string $migrationsNamespace = ''

$migrationsPath

The directory holding the `Version*.php` migration files.

public string|null $migrationsPath = null

$models

Container ids of the `Documents` models to inspect.

public array<int, string> $models = []

Methods

getAnalyzerDefinitions()

Returns the declared analyzers normalized to a flat {@see AnalyzerDefinition} list: a lone `AnalyzerDefinition` becomes a one-element list, and any entry that is not an `AnalyzerDefinition` is dropped (defensive against a malformed declaration).

public getAnalyzerDefinitions() : array<int, AnalyzerDefinition>
Return values
array<int, AnalyzerDefinition>

agent()

The acting agent (`user@host`) stamped on the tracking documents — shared by the `migrate` runs and the `doctor --apply` journal.

protected agent() : string
Return values
string

buildDatabase()

Builds a best-effort {@see Database} HTTP client from the resolved connection settings, or null when no usable endpoint/database is available or the client cannot be constructed.

protected buildDatabase(string $endpoint, string $username, string $password, string $database) : Database|null

No network I/O happens here — the connection is only exercised when a request method (e.g. Database::collections()) is later called by the caller.

Parameters
$endpoint : string

The ArangoDB endpoint (e.g. tcp://127.0.0.1:8529).

$username : string

The connection user.

$password : string

The connection password.

$database : string

The target database name.

Return values
Database|null

doctor()

Diagnoses (or repairs) the declared structure of the database.

protected doctor(InputInterface $input, OutputInterface $output) : int
Parameters
$input : InputInterface
$output : OutputInterface
Tags
throws
ExitException

When the interactive prune selection is exited.

ReflectionException
Return values
int

gitCommit()

The current git commit hash, or null outside a git repository — the history link stamped on every tracking document.

protected gitCommit() : string|null
Return values
string|null

resolveDatabase()

Builds the best-effort {@see Database} HTTP client of an action run: every connection setting reads its CLI option first (`--database` / `--endpoint` / `--user` / `--password`) and falls back on the command configuration ({@see ArangoConfigTrait}).

protected resolveDatabase(InputInterface $input) : Database|null

One-stop shop for the actions — see buildDatabase() for the null-on-failure semantics.

Parameters
$input : InputInterface

The action input carrying the optional CLI overrides.

Return values
Database|null

resolveFacade()

Builds the best-effort high-level {@see ArangoDB} façade of an action run, from the same resolved connection settings as {@see resolveDatabase()} — the migration engine hands this façade to every {@see \oihana\arango\migrations\Migration}. Null when no usable endpoint is configured or the façade cannot be constructed.

protected resolveFacade(InputInterface $input) : ArangoDB|null
Parameters
$input : InputInterface

The action input carrying the optional CLI overrides.

Return values
ArangoDB|null

doctorAccount()

Accounts one diff report into the running doctor state: renders it, bumps the status counter, flips the health flag when the report is not in sync (and was not freshly applied), and collects it when applied. Shared by the model walk and the collection-index registry walk.

private doctorAccount(SymfonyStyle $io, DiffReport $report, bool $apply, array<string, int> &$counters, array<int, DiffReport&$applied, bool &$healthy) : void
Parameters
$io : SymfonyStyle
$report : DiffReport
$apply : bool
$counters : array<string, int>

The status counters, by reference.

$applied : array<int, DiffReport>

The applied reports, by reference.

$healthy : bool

The health flag, by reference.

doctorJournal()

Journals each applied object as a `CreateAction` in the tracking collection — the audit trail of `doctor --apply`, told apart from the versioned migrations by its `additionalType` ({@see MigrationKind::DOCTOR}).

private doctorJournal(InputInterface $input, array<int, DiffReport$applied) : void

Best-effort: nothing is journaled when nothing was applied or the database is unreachable, and a journal failure never fails the run. The migration runner ignores these rows.

Parameters
$input : InputInterface
$applied : array<int, DiffReport>

The reports actually created / repaired.

Tags
throws
ReflectionException

doctorOrphans()

Computes and prints the orphans — collections (non-system) and views on the server that no configured model declares. Report only.

private doctorOrphans(InputInterface $input, SymfonyStyle $io, array<int, string> $declaredCollections, array<int, string> $declaredViews) : array<int, string>

The migrations tracking collection (ArangoMigrationsTrait::$migrationsCollection) is never an orphan: no model declares it, yet both migrate and doctor --apply write their journal there. It is excluded by its configured name (so a renamed tracking collection is honoured), which also keeps it out of the --prune selection.

Parameters
$input : InputInterface
$io : SymfonyStyle
$declaredCollections : array<int, string>

The collections declared by the configured models.

$declaredViews : array<int, string>

The view names declared by the configured models.

Return values
array<int, string>

The orphan labels (collection : name / view : name).

doctorPrune()

Offers the interactive multi-selection of the orphans to remove and drops the chosen ones. Nothing happens in non-interactive mode.

private doctorPrune(InputInterface $input, OutputInterface $output, SymfonyStyle $io, array<int, string> $orphans) : void
Parameters
$input : InputInterface
$output : OutputInterface
$io : SymfonyStyle
$orphans : array<int, string>

The orphan labels (doctorOrphans()).

Tags
throws
ExitException

When the selection is exited.

doctorRenderReport()

Prints one {@see DiffReport} as a status line (labelled with its {@see DiffKind}) plus one indented line per change.

private doctorRenderReport(SymfonyStyle $io, DiffReport $report, bool $apply) : void
Parameters
$io : SymfonyStyle
$report : DiffReport

The report to render.

$apply : bool

Whether the report comes from repair().

On this page

Search results