-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDuckDB.php
106 lines (101 loc) · 3.4 KB
/
DuckDB.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<?php
namespace My\Library;
if (!extension_loaded('FFI')) {
throw new \Exception('Ekstensi FFI tidak tersedia. Pastikan FFI diaktifkan di konfigurasi PHP Anda.');
}
use \FFI;
class DuckDB{
private FFI $ffi;
private FFI\CData $db;
private FFI\CData $conn;
private $type;
public function __construct(string $databasePath){
$this->type = [
0=>'INVALID',
1=>'BOOLEAN',
2=>'TINYINT',
3=>'SMALLINT',
4=>'INTEGER',
5=>'BIGINT',
6=>'UTINYINT',
7=>'USMALLINT',
8=>'UINTEGER',
9=>'UBIGINT',
10=>'FLOAT',
11=>'DOUBLE',
12=>'TIMESTAMP',
13=>'DATE',
14=>'TIME',
15=>'INTERVAL',
16=>'HUGEINT',
17=>'VARCHAR',
18=>'BLOB',
19=>'DECIMAL',
20=>'TIMESTAMP_S',
21=>'TIMESTAMP_MS',
22=>'TIMESTAMP_NS',
23=>'ENUM',
24=>'LIST',
25=>'STRUCT',
26=>'MAP',
27=>'UUID',
28=>'UNION',
29=>'BIT',
30=>'TIME_TZ',
31=>'TIMESTAMP_TZ',
32=>'UHUGEINT',
33=>'ARRAY',
];
try{
$header = file_get_contents(__DIR__.'/myduck.h');
$lib_so = __DIR__.'/libduckdb.so';
$this->ffi = FFI::cdef($header,$lib_so);
$this->db = $this->ffi->new('duckdb_database');
$this->conn = $this->ffi->new('duckdb_connection');
$this->ffi->duckdb_open($databasePath, FFI::addr($this->db));
$this->ffi->duckdb_connect($this->db, FFI::addr($this->conn));
}catch(\Exception $ex){
return $ex->getMessage();
}
}
public function __destruct()
{
$this->ffi->duckdb_disconnect(FFI::addr($this->conn));
$this->ffi->duckdb_close(FFI::addr($this->db));
FFI::free($this->conn);
FFI::free($this->db);
unset($this->ffi);
}
public function query(string $query){
try{
$result = $this->ffi->new('duckdb_result');
$this->ffi->duckdb_query($this->conn, $query, FFI::addr($result));
$jmlCol = $this->ffi->duckdb_column_count(FFI::addr($result));
$jmlRow = $this->ffi->duckdb_row_count(FFI::addr($result));
if($jmlRow<1){
$this->ffi->duckdb_destroy_result(FFI::addr($result));
return null;
}
$data = [];
$column = [];
for ($col=0;$col<$jmlCol;$col++) {
$colName = $this->ffi->duckdb_column_name(FFI::addr($result),$col);
$colType = $this->ffi->duckdb_column_type(FFI::addr($result),$col);
$column[] = [
'type'=>$this->type[$colType],
'name'=>$colName
];
for ($row=0;$row<$jmlRow;$row++) {
$value = $this->ffi->duckdb_value_varchar(FFI::addr($result), $col, $row);
$data[$row][$colName] = FFI::string($value);
FFI::free($value);
}
//FFI::free($colName);
}
$this->ffi->duckdb_destroy_result(FFI::addr($result));
return $data;
}catch(\Exception $ex){
return $ex->getMessage();
}
}
}