-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDIH.php
More file actions
157 lines (125 loc) · 3.82 KB
/
DIH.php
File metadata and controls
157 lines (125 loc) · 3.82 KB
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<?php
declare(strict_types=1);
namespace DIH;
require_once 'Solr.php';
require_once 'DB.php';
class DIH {
private $xp;
private $db;
private $solr;
// constructor, load DIH file
public function __construct(string $dihFile, string $core) { //{{{
if (!file_exists($dihFile)) {
throw new \Exception('DIH file not found');
}
$dom = new \DomDocument();
if (!$dom->load($dihFile)) {
throw new \Exception('DIH file not XML');
}
$this->xp = new \DomXPath($dom);
// connect to database
$this->db();
// connect to Solr
$this->solr = new Solr($core);
}
//}}}
// do import defined by action with optional value
public function import(string $action, string $option='') { //{{{
// loop over entities
foreach ($this->xp->query('/dataConfig/document/entity') as $e) {
$this->entity($e, $action, $option);
}
}
//}}}
// handle SQL query and field mapping for entity
private function entity(\DomElement $e, string $action, string $option) { //{{{
// get SQL
$sql = DIH::fmtSQL($e->getAttribute($action), $action, $option);
// map database columns to Solr document fields
$fields = $this->xp->query('field', $e);
$fieldMap = DIH::fieldMappings($fields);
// generate Solr input documents
$docs = DIH::solrDocs($fieldMap, $this->db->query($sql));
// add add to Solr
$this->solr->addDocuments($docs,
$e->getAttribute('pk'));
}
//}}}
// connect to database
private function db() {
$ds = '/dataConfig/dataSource[@type="JdbcDataSource"]';
$dataSource = $this->xp->query($ds)->item(0);
$dsn = DIH::dbConnectionDetails($dataSource->getAttribute('url'));
$this->db = new DB($dsn,
$dataSource->getAttribute('user'),
$dataSource->getAttribute('password'));
}
// get database PDO DSN from JDBC string
static function dbConnectionDetails(string $url) : string { //{{{
$matches = [];
if (1 !== preg_match('/jdbc:([a-z]+):\/\/([^\/:]+):?([0-9]*)\/(.*)/',
$url, $matches)) {
throw new \Exception('Problem getting DB connection details');
}
$details = ['host' => $matches[2], 'dbname' => $matches[4]];
if ($matches[3]) {
$details['port'] = (int) $matches[3];
}
// put together DSN
return sprintf('%s:%s',
$matches[1],
http_build_query($details, '', ';'));
}
//}}}
// turn <field column="surname" name="surname_t"/> into surname => [surname_t]
static function fieldMappings(\DomNodelist $fields) : array { //{{{
$arr = [];
foreach ($fields as $f) {
$dbCol = $f->getAttribute('column');
if (!isset($arr[$dbCol])) {
$arr[$dbCol] = [];
}
$arr[$dbCol][] = $f->getAttribute('name');
}
return $arr;
}
//}}}
// create SolrInputDocuments from DB rows and mapping
static function solrDocs(array $fields, array $rows) : array { //{{{
$docs = [];
// loop over rows (one per document)
foreach ($rows as $r) {
$doc = new \SolrInputDocument();
// loop over columns in row
foreach ($r as $col => $val) {
// loop over Solr document fields for given column
foreach ($fields[$col] as $f) {
$doc->addField($f, (string) $val);
}
}
$docs[] = $doc;
}
return $docs;
}
//}}}
// format SQL - replace possible placeholder with value
static function fmtSQL(string $sql, string $action, string $option) : string { //{{{
$pat = '';
switch ($action) {
case 'deltaImportQuery':
$pat = '${dih.delta.id}';
break;
case 'deltaQuery':
$pat = '${dih.last_index_time}';
break;
default:
break;
}
if ($pat) {
$sql = str_replace($pat, $option, $sql);
}
return $sql;
}
//}}}
}
?>