Skip to content

Commit 97c1885

Browse files
added examples with test data
1 parent 7c9ef26 commit 97c1885

27 files changed

+1133
-0
lines changed

examples/complex.php

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
<?php
2+
3+
/**
4+
*
5+
* complex test case. after executing php -q complex.php this should be output:
6+
* Processing 1006 / 6
7+
* Done 4 / 6
8+
*
9+
* WHY? Bacause:
10+
*
11+
* Job 1001: The CSV says done: 1. Transform converts this to processed = 1.
12+
* Status: Already Done. Will be skipped by the loop.
13+
* Job 1002: The CSV says done: true. Transform converts this to processed = 1.
14+
* Status: Already Done. Will be skipped by the loop.
15+
* Job 1003: The CSV has done: (empty) but working: yes. Transform converts this to processed = 0 and in_progress = 1.
16+
* Status: In Progress. The queue assumes another process is handling it. Will be skipped by the loop.
17+
* Job 1004: The CSV says state: error.
18+
* Status: Error. Will be skipped by the loop.
19+
* Job 1005: The CSV says done: yes. Transform converts this to processed = 1.
20+
* Status: Already Done. Will be skipped by the loop.
21+
* Job 1006: All status-related columns are empty. The database sets its defaults.
22+
* Status: Queued (processed = 0, in_progress = 0). This is the only job that is eligible for processing.
23+
*
24+
* final:
25+
* Job 1001: Yes (was done on import)
26+
* Job 1002: Yes (was done on import)
27+
* Job 1003: No (still in progress)
28+
* Job 1004: No (is an error)
29+
* Job 1005: Yes (was done on import)
30+
* Job 1006: Yes (was processed by the loop)
31+
*/
32+
declare(strict_types=1);
33+
34+
require __DIR__ . '/../vendor/autoload.php';
35+
36+
use guycalledseven\JobQueue\SqliteQueue;
37+
use guycalledseven\JobQueue\CsvProfile;
38+
use guycalledseven\JobQueue\CsvImporter;
39+
use guycalledseven\JobQueue\CsvExporter;
40+
41+
$csv = __DIR__ . '/data/complex.csv';
42+
$db = __DIR__ . '/data/complex-queue.sqlite';
43+
$csv_out = __DIR__ . '/data/complex_out.csv';
44+
45+
$q = SqliteQueue::open($db);
46+
47+
$importer = new CsvImporter($q);
48+
$exporter = new CsvExporter($q);
49+
50+
$q->dropAndRecreate(true); // clean up DB file size and stats
51+
// $q->vacuum(); // just optimize
52+
53+
$profileIn = new CsvProfile();
54+
// Header mapping
55+
$profileIn->aliases = [
56+
'id' => ['id', 'msisdn', 'number'],
57+
'processed' => ['processed', 'done'],
58+
'in_progress' => ['in_progress', 'working'],
59+
'status' => ['status', 'state'],
60+
'result' => ['result', 'ok'],
61+
'updated_at' => ['updated_at', 'timestamp', 'last_update'],
62+
'last_error' => ['last_error', 'error', 'message'],
63+
];
64+
// Value normalization and transformation
65+
$profileIn->transforms = [
66+
'processed' => fn ($v) => ($v === '' || $v === null) ? null : (int)!!in_array(strtolower((string)$v), ['1', 'true', 'yes', 'ok'], true),
67+
'in_progress' => fn ($v) => ($v === '' || $v === null) ? null : (int)!!in_array(strtolower((string)$v), ['1', 'true', 'yes'], true),
68+
'result' => fn ($v) => ($v === '' || $v === null) ? null : (int)!!in_array(strtolower((string)$v), ['1', 'true', 'yes', 'ok'], true),
69+
'status' => fn ($v) => $v === null ? 'queued' : strtolower((string)$v),
70+
];
71+
72+
// import with flexible headers and passthrough extras
73+
$importer->import($csv, $profileIn, ';', true);
74+
75+
76+
$total = $q->totalItems();
77+
78+
79+
// Loop until empty
80+
while ($job = $q->fetchNext()) {
81+
$id = $job['id'];
82+
echo("Processing $id / $total\n");
83+
try {
84+
// sleep(1);
85+
// throw new \Exception('testna greska');
86+
// your long work using $id
87+
// $ok = false;
88+
$ok = true;
89+
// create additional field data
90+
$q->updateById($id, [
91+
'segment' => 1,
92+
'note' => 'bla',
93+
]);
94+
95+
// $ok = false; // or true based on your logic
96+
$ok ? $q->markSuccess($id)
97+
: $q->markFailure($id, 'Processor returned false');
98+
} catch (Throwable $e) {
99+
$q->markFailure($id, $e->getMessage());
100+
}
101+
}
102+
103+
$p = $q->progress();
104+
echo("Done {$p['done']} / {$p['total']}\n");
105+
106+
/**
107+
* different types of export
108+
*/
109+
110+
// Minimal progress report - Only queue state.
111+
$out = new CsvProfile();
112+
$out->export_columns = ['id','status','result','updated_at'];
113+
$out->labels = [
114+
'id' => 'ID','status' => 'Status','result' => 'Result','updated_at' => 'Updated At'
115+
];
116+
$exporter->export($csv_out . '_report.csv', $out, ';');
117+
118+
// Ops audit - Include errors and processing flags.
119+
$out = new CsvProfile();
120+
$out->export_columns = ['id','processed','in_progress','status','result','updated_at','last_error'];
121+
$exporter->export($csv_out . '_audit.csv', $out, ';');
122+
123+
// Business handoff - State + selected extras mapped from extras JSON.
124+
$out = new CsvProfile();
125+
$out->export_columns = ['id','status','result','updated_at','segment','note'];
126+
$out->labels = ['segment' => 'Segment','note' => 'Note'];
127+
$exporter->export($csv_out . '_handoff.csv', $out, ';');
128+
129+
// Merge with original input - Echo input extras plus final state.
130+
$out = new CsvProfile();
131+
$out->export_columns = ['id','segment','note','status','result','updated_at','last_error'];
132+
$exporter->export($csv_out . '_merge.csv', $out, ';');
133+
134+
135+
// Full dump - Everything core, then your chosen extras.
136+
$profileOut = new CsvProfile();
137+
$profileOut->export_columns = [
138+
'id','processed','in_progress','status','result','updated_at','last_error',
139+
// extras you want to expose:
140+
'segment','note','batch','crm_id'
141+
];
142+
$exporter->export($csv_out, $profileOut, ';');

examples/csvqueue.php

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
require __DIR__ . '/../vendor/autoload.php';
6+
7+
use guycalledseven\JobQueue\CsvQueue;
8+
use guycalledseven\JobQueue\CsvProfile;
9+
use guycalledseven\JobQueue\CsvImporter;
10+
use guycalledseven\JobQueue\CsvExporter;
11+
12+
$csv = __DIR__ . '/data/csvqueue.csv';
13+
$csv_out = __DIR__ . '/data/csvqueue_out.csv';
14+
15+
// To use the fast, robust SQLite engine:
16+
// $queue = \guycalledseven\JobQueue\SqliteQueue::open('./my-queue.sqlite');
17+
18+
// To use the slower, file-based CSV engine:
19+
try {
20+
$q = CsvQueue::load($csv);
21+
} catch (RuntimeException $e) {
22+
die("Error: " . $e->getMessage());
23+
}
24+
25+
// $q = CsvQueue::open($csv); // Safe: creates the file if it's the first
26+
27+
// import minimal set from csv
28+
$profileIn = new CsvProfile();
29+
$profileIn->aliases = [
30+
'id' => ['id'] // only column we expect
31+
];
32+
33+
$importer = new CsvImporter($q);
34+
$exporter = new CsvExporter($q);
35+
36+
$importer->import($csv, $profileIn, ';');
37+
38+
$total = $q->totalItems();
39+
40+
41+
// Loop until empty
42+
while ($job = $q->fetchNext()) {
43+
$id = $job['id'];
44+
echo("Processing $id / $total\n");
45+
try {
46+
sleep(3);
47+
// throw new \Exception('testna greska');
48+
// your long work using $id
49+
// $ok = false;
50+
$ok = true;
51+
// create additional field data
52+
$q->updateById($id, [
53+
'segment' => 1,
54+
'note' => 'bla',
55+
]);
56+
57+
// $ok = false; // or true based on your logic
58+
$ok ? $q->markSuccess($id)
59+
: $q->markFailure($id, 'Processor returned false');
60+
} catch (Throwable $e) {
61+
$q->markFailure($id, $e->getMessage());
62+
}
63+
}
64+
65+
$p = $q->progress();
66+
echo("Done {$p['done']} / {$p['total']}\n");
67+
68+
// export minimal data set to csv
69+
$profileOut = new CsvProfile();
70+
$profileOut->export_columns = [
71+
'id',
72+
'status',
73+
'result',
74+
'segment',
75+
'note' // pulled from extras
76+
];
77+
$profileOut->labels = [ // optional pretty headers
78+
'status' => 'Status',
79+
'segment' => 'Segment data'
80+
];
81+
82+
$exporter->export($csv_out, $profileOut, ';');

examples/data/complex-queue.sqlite

24 KB
Binary file not shown.

examples/data/complex.csv

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
msisdn;done;working;state;ok;timestamp;error
2+
1001;1;0;ok;1;2025-11-09 09:12:03;
3+
1002;true;no;OK;yes;2025-11-09 09:12:04;temporary failure
4+
1003;;yes;queued;;2025-11-09 09:12:05;
5+
1004;false;;error;0;2025-11-09 09:12:06;api timeout
6+
1005;yes;no;;yes;;network lag
7+
1006;;;;;; ; extra spaces

examples/data/complex_out.csv

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
id;processed;in_progress;status;result;updated_at;last_error;segment;note;batch;crm_id
2+
1001;1;0;ok;1;"2025-11-09 09:12:03";;;;;
3+
1002;1;0;ok;1;"2025-11-09 09:12:04";"temporary failure";;;;
4+
1003;0;1;queued;;"2025-11-09 09:12:05";;;;;
5+
1004;0;0;error;0;"2025-11-09 09:12:06";"api timeout";;;;
6+
1005;1;0;queued;1;;"network lag";;;;
7+
1006;1;0;ok;1;"2025-11-10 23:27:32";;1;bla;;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
id;processed;in_progress;status;result;updated_at;last_error
2+
1001;1;0;ok;1;"2025-11-09 09:12:03";
3+
1002;1;0;ok;1;"2025-11-09 09:12:04";"temporary failure"
4+
1003;0;1;queued;;"2025-11-09 09:12:05";
5+
1004;0;0;error;0;"2025-11-09 09:12:06";"api timeout"
6+
1005;1;0;queued;1;;"network lag"
7+
1006;1;0;ok;1;"2025-11-10 23:27:32";
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
id;status;result;updated_at;Segment;Note
2+
1001;ok;1;"2025-11-09 09:12:03";;
3+
1002;ok;1;"2025-11-09 09:12:04";;
4+
1003;queued;;"2025-11-09 09:12:05";;
5+
1004;error;0;"2025-11-09 09:12:06";;
6+
1005;queued;1;;;
7+
1006;ok;1;"2025-11-10 23:27:32";1;bla
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
id;segment;note;status;result;updated_at;last_error
2+
1001;;;ok;1;"2025-11-09 09:12:03";
3+
1002;;;ok;1;"2025-11-09 09:12:04";"temporary failure"
4+
1003;;;queued;;"2025-11-09 09:12:05";
5+
1004;;;error;0;"2025-11-09 09:12:06";"api timeout"
6+
1005;;;queued;1;;"network lag"
7+
1006;1;bla;ok;1;"2025-11-10 23:27:32";
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
ID;Status;Result;"Updated At"
2+
1001;ok;1;"2025-11-09 09:12:03"
3+
1002;ok;1;"2025-11-09 09:12:04"
4+
1003;queued;;"2025-11-09 09:12:05"
5+
1004;error;0;"2025-11-09 09:12:06"
6+
1005;queued;1;
7+
1006;ok;1;"2025-11-10 23:27:32"

examples/data/csvqueue.csv

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
id;bla
2+
1;
3+
2;
4+
3;
5+
4;
6+
5;
7+
6;
8+
7;
9+
8;
10+
9;

0 commit comments

Comments
 (0)