summaryrefslogtreecommitdiffstats
path: root/library/Icingadb/Data/CsvResultSet.php
diff options
context:
space:
mode:
Diffstat (limited to 'library/Icingadb/Data/CsvResultSet.php')
-rw-r--r--library/Icingadb/Data/CsvResultSet.php85
1 files changed, 85 insertions, 0 deletions
diff --git a/library/Icingadb/Data/CsvResultSet.php b/library/Icingadb/Data/CsvResultSet.php
new file mode 100644
index 0000000..746a7e4
--- /dev/null
+++ b/library/Icingadb/Data/CsvResultSet.php
@@ -0,0 +1,85 @@
+<?php
+
+/* Icinga DB Web | (c) 2022 Icinga GmbH | GPLv2 */
+
+namespace Icinga\Module\Icingadb\Data;
+
+use DateTime;
+use DateTimeZone;
+use Icinga\Module\Icingadb\Redis\VolatileStateResults;
+use ipl\Orm\Model;
+use ipl\Orm\Query;
+
+class CsvResultSet extends VolatileStateResults
+{
+ protected $isCacheDisabled = true;
+
+ /**
+ * @return array<string, ?string>
+ */
+ public function current(): array
+ {
+ return $this->extractKeysAndValues(parent::current());
+ }
+
+ protected function formatValue(string $key, $value): ?string
+ {
+ if (
+ $value
+ && (
+ $key === 'id'
+ || substr($key, -3) === '_id'
+ || substr($key, -3) === '.id'
+ || substr($key, -9) === '_checksum'
+ || substr($key, -4) === '_bin'
+ )
+ ) {
+ $value = bin2hex($value);
+ }
+
+ if (is_bool($value)) {
+ return $value ? 'true' : 'false';
+ } elseif (is_string($value)) {
+ return '"' . str_replace('"', '""', $value) . '"';
+ } elseif (is_array($value)) {
+ return '"' . implode(',', $value) . '"';
+ } elseif ($value instanceof DateTime) {
+ return $value->setTimezone(new DateTimeZone('UTC'))
+ ->format('Y-m-d\TH:i:s.vP');
+ } else {
+ return $value;
+ }
+ }
+
+ protected function extractKeysAndValues(Model $model, string $path = ''): array
+ {
+ $keysAndValues = [];
+ foreach ($model as $key => $value) {
+ $keyPath = ($path ? $path . '.' : '') . $key;
+ if ($value instanceof Model) {
+ $keysAndValues += $this->extractKeysAndValues($value, $keyPath);
+ } else {
+ $keysAndValues[$keyPath] = $this->formatValue($key, $value);
+ }
+ }
+
+ return $keysAndValues;
+ }
+
+ public static function stream(Query $query): void
+ {
+ $query->setResultSetClass(__CLASS__);
+
+ foreach ($query as $i => $keysAndValues) {
+ if ($i === 0) {
+ echo implode(',', array_keys($keysAndValues));
+ }
+
+ echo "\r\n";
+
+ echo implode(',', array_values($keysAndValues));
+ }
+
+ exit;
+ }
+}