Use commit timestamps for ElasticSearch and sort on last commit time.
[phorkie.git] / src / phorkie / Database / Adapter / Elasticsearch / Indexer.php
1 <?php
2 namespace phorkie;
3
4 class Database_Adapter_Elasticsearch_Indexer implements Database_IIndexer
5 {
6     public function __construct()
7     {
8         $this->searchInstance = $GLOBALS['phorkie']['cfg']['elasticsearch'];
9     }
10
11
12     public function addRepo(Repository $repo, $crdate = null, $modate = null)
13     {
14         if ($crdate == null) {
15             $crdate = time();
16         }
17         if ($modate == null) {
18             $modate = time();
19         }
20         $this->updateRepo($repo, $crdate, $modate);
21     }
22
23     public function updateRepo(Repository $repo, $crdate = null, $modate = null)
24     {
25         //add repository
26         $r = new Database_Adapter_Elasticsearch_HTTPRequest(
27             $this->searchInstance . 'repo/' . $repo->id,
28             \HTTP_Request2::METHOD_PUT
29         );
30         $repoData = array(
31             'id'          => $repo->id,
32             'description' => $repo->getDescription(),
33             'tstamp'      => gmdate('c', time()),
34         );
35         if ($crdate == null) {
36             $crdate = $this->getCrDate($repo);
37         }
38         if ($crdate !== null) {
39             $repoData['crdate'] = gmdate('c', $crdate);
40         }
41         if ($modate == null) {
42             $modate = $this->getMoDate($repo);
43         }
44         if ($modate !== null) {
45             $repoData['modate'] = gmdate('c', $modate);
46         }
47
48         $r->setBody(json_encode((object)$repoData));
49         $r->send();
50
51         //add files
52         //clean up before adding files; files might have been deleted
53         $this->deleteRepoFiles($repo);
54
55         foreach ($repo->getFiles() as $file) {
56             $r = new Database_Adapter_Elasticsearch_HTTPRequest(
57                 $this->searchInstance . 'file/?parent=' . $repo->id,
58                 \HTTP_Request2::METHOD_POST
59             );
60             $r->setBody(
61                 json_encode(
62                     (object)array(
63                         'name'      => $file->getFilename(),
64                         'extension' => $file->getExt(),
65                         'content'   => $file->isText() ? $file->getContent() : '',
66                     )
67                 )
68             );
69             $r->send();
70         }
71     }
72
73     /**
74      * When updating the repository, we don't have a creation date.
75      * We need to keep it, but elasticsearch does not have a simple way
76      * to update some fields only (without using a custom script).
77      *
78      * @return integer Unix timestamp
79      */
80     protected function getCrDate(Repository $repo)
81     {
82         $r = new Database_Adapter_Elasticsearch_HTTPRequest(
83             $this->searchInstance . 'repo/' . $repo->id,
84             \HTTP_Request2::METHOD_GET
85         );
86         $json = json_decode($r->send()->getBody());
87
88         if (!isset($json->_source->crdate)) {
89             return null;
90         }
91
92         return strtotime($json->_source->crdate);
93     }
94
95     /**
96      * When updating the repository, we don't have a modification date.
97      * We need to keep it, but elasticsearch does not have a simple way
98      * to update some fields only (without using a custom script).
99      *
100      * @return integer Unix timestamp
101      */
102     protected function getMoDate(Repository $repo)
103     {
104         $r = new Database_Adapter_Elasticsearch_HTTPRequest(
105             $this->searchInstance . 'repo/' . $repo->id,
106             \HTTP_Request2::METHOD_GET
107         );
108         $json = json_decode($r->send()->getBody());
109
110         if (!isset($json->_source->modate)) {
111             return null;
112         }
113
114         return strtotime($json->_source->modate);
115     }
116
117     public function deleteAllRepos()
118     {
119         $r = new Database_Adapter_Elasticsearch_HTTPRequest(
120             $this->searchInstance . 'repo/_query',
121             \HTTP_Request2::METHOD_DELETE
122         );
123         $r->allow404 = true;
124         $r->setBody(
125             json_encode(
126                 (object)array(
127                     'match_all' => (object)array()
128                 )
129             )
130         );
131         $r->send();
132         $r = new Database_Adapter_Elasticsearch_HTTPRequest(
133             $this->searchInstance . 'file/_query',
134             \HTTP_Request2::METHOD_DELETE
135         );
136         $r->allow404 = true;
137         $r->setBody(
138             json_encode(
139                 (object)array(
140             'match_all' => (object)array()
141                 )
142             )
143         );
144         $r->send();
145     }
146
147     public function deleteRepo(Repository $repo)
148     {
149         //delete repository from index
150         $r = new Database_Adapter_Elasticsearch_HTTPRequest(
151             $this->searchInstance . 'repo/' . $repo->id,
152             \HTTP_Request2::METHOD_DELETE
153         );
154         $r->allow404 = true;
155         $r->send();
156
157         $this->deleteRepoFiles($repo);
158     }
159
160     protected function deleteRepoFiles(Repository $repo)
161     {
162         //delete files of that repository
163         $r = new Database_Adapter_Elasticsearch_HTTPRequest(
164             $this->searchInstance . 'file/_query',
165             \HTTP_Request2::METHOD_DELETE
166         );
167         $r->allow404 = true;
168         $r->setBody(
169             json_encode(
170                 (object)array(
171                     'field' => (object)array(
172                         '_parent' => $repo->id
173                     )
174                 )
175             )
176         );
177         $r->send();
178     }
179
180 }
181
182 ?>