Skip to content

Commit 7a4d3fc

Browse files
committed
feat(command): idempotence by default
1 parent 788d04d commit 7a4d3fc

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ oce-import-codes /path/to/icd10cm_order_2024.txt.zip \
8080

8181
# Dry run to test
8282
oce-import-codes /path/to/RxNorm_full_01012024.zip --openemr-path=/var/www/openemr --dry-run
83+
84+
# Force import even if already loaded
85+
oce-import-codes /path/to/RxNorm_full_01012024.zip --openemr-path=/var/www/openemr --force
8386
```
8487

8588
## Usage
@@ -92,6 +95,8 @@ oce-import-codes [OPTIONS] <file-path>
9295

9396
**Auto-Detection**: The tool automatically detects the code type from the filename. If detection fails, you can manually specify the code type using `--code-type`.
9497

98+
**Skip Behavior**: By default, the tool checks if a code package with the same type, version, revision date, and file checksum has already been imported. If found, it will skip the import to avoid duplicates. Use `--force` to override this behavior and import anyway.
99+
95100
### Arguments
96101

97102
| Argument | Description | Required |
@@ -112,6 +117,7 @@ oce-import-codes [OPTIONS] <file-path>
112117
| `--dry-run` | Test without database changes | `false` |
113118
| `--cleanup` | Remove temp files after import | `false` |
114119
| `--temp-dir` | Custom temporary directory | - |
120+
| `--force` | Force import even if same version appears loaded | `false` |
115121

116122
## Docker/Kubernetes Deployment
117123

src/Command/ImportCodesCommand.php

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ protected function configure()
5454
->addOption('dry-run', null, InputOption::VALUE_NONE, 'Perform a dry run without making database changes')
5555
->addOption('cleanup', null, InputOption::VALUE_NONE, 'Clean up temporary files after import')
5656
->addOption('temp-dir', null, InputOption::VALUE_REQUIRED, 'Custom temporary directory path')
57+
->addOption('force', null, InputOption::VALUE_NONE, 'Force import even if the same version appears to be already loaded')
5758
->addUsage('/path/to/RxNorm_full_01012024.zip --openemr-path=/var/www/openemr')
5859
->addUsage('/path/to/SnomedCT_USEditionRF2_PRODUCTION_20240301T120000Z.zip')
5960
->addUsage('/path/to/icd10cm_order_2024.txt.zip --cleanup');
@@ -70,6 +71,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
7071
$dryRun = $input->getOption('dry-run');
7172
$cleanup = $input->getOption('cleanup');
7273
$tempDir = $input->getOption('temp-dir');
74+
$force = $input->getOption('force');
7375

7476
// Resolve relative paths to absolute paths
7577
if (!$this->is_absolute_path($filePath)) {
@@ -136,7 +138,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
136138
['OpenEMR Path' => $openemrPath],
137139
['Site' => $site],
138140
['Dry Run' => $dryRun ? 'Yes' : 'No'],
139-
['Cleanup' => $cleanup ? 'Yes' : 'No']
141+
['Cleanup' => $cleanup ? 'Yes' : 'No'],
142+
['Force Import' => $force ? 'Yes' : 'No']
140143
);
141144

142145
if ($metadata['rf2']) {
@@ -165,6 +168,17 @@ protected function execute(InputInterface $input, OutputInterface $output): int
165168
$this->importer->setTempDir($tempDir);
166169
}
167170

171+
// Check if already loaded (unless force flag is set)
172+
if (!$force && !$dryRun && $metadata['supported'] && $metadata['revision_date'] && $metadata['version']) {
173+
$trackingCodeType = ($codeType === 'SNOMED_RF2') ? 'SNOMED' : $codeType;
174+
$fileChecksum = $metadata['checksum'] ?: md5_file($filePath);
175+
176+
if ($this->isAlreadyLoaded($trackingCodeType, $metadata['revision_date'], $metadata['version'], $fileChecksum)) {
177+
$io->warning("Code package appears to be already loaded (same type, version, revision date, and file checksum)");
178+
$io->note("Use --force flag to import anyway, or --dry-run to test without checking");
179+
return Command::SUCCESS;
180+
}
181+
}
168182

169183
try {
170184
// Step 1: File handling
@@ -259,4 +273,21 @@ private function is_absolute_path(string $path): bool
259273
return false;
260274
}
261275

276+
/**
277+
* Check if a code package is already loaded with the same metadata
278+
*/
279+
private function isAlreadyLoaded(string $codeType, string $revisionDate, string $version, string $fileChecksum): bool
280+
{
281+
if (!function_exists('sqlQuery')) {
282+
return false;
283+
}
284+
285+
$result = sqlQuery(
286+
"SELECT COUNT(*) as count FROM `standardized_tables_track` WHERE `name` = ? AND `revision_date` = ? AND `revision_version` = ? AND `file_checksum` = ?",
287+
array($codeType, $revisionDate, $version, $fileChecksum)
288+
);
289+
290+
return $result && $result['count'] > 0;
291+
}
292+
262293
}

0 commit comments

Comments
 (0)