public function restore() { // check db $url = "http://{$this->adminUrl}{$this->host}:{$this->port}/" . urlencode($this->database) . "/"; fwrite(STDOUT, "Checking db '{$this->database}' at {$this->host}:{$this->port} ..." . PHP_EOL); $curl = getCommonCurl($url); $result = trim(curl_exec($curl)); $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); if (200 == $statusCode) { // $this->database exists $exists = true; $db_info = json_decode($result, true); $docCount = isset($db_info['doc_count']) ? $db_info['doc_count'] : 0; fwrite(STDOUT, "{$this->database} '{$this->database}' has {$docCount} documents." . PHP_EOL); } elseif (404 == $statusCode) { // $this->database not found $exists = false; $docCount = 0; } else { // unknown status fwrite(STDOUT, "ERROR: Unsupported response when checking db '{$this->database}' status (http status code = {$statusCode}) " . $result . PHP_EOL); return; } if ($this->drop && $exists) { // drop $this->database fwrite(STDOUT, "Deleting {$this->database} '{$this->database}'..." . PHP_EOL); $curl = getCommonCurl($url); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); $result = trim(curl_exec($curl)); $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); if (200 != $statusCode) { fwrite(STDOUT, "ERROR: Unsupported response when deleting db '{$this->database}' (http status code = {$statusCode}) " . $result . PHP_EOL); return; } $exists = false; $docCount = 0; } if ($docCount && !$this->forceRestore) { // has documents, but no force fwrite(STDOUT, "ERROR: {$this->database} '{$this->database}' has {$docCount} documents. Refusing to restore without -F force flag." . PHP_EOL); return; } if (!$exists) { // create db fwrite(STDOUT, "Creating {$this->database} '{$this->database}'..." . PHP_EOL); $curl = getCommonCurl($url); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT'); $result = trim(curl_exec($curl)); $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); if (201 != $statusCode) { fwrite(STDOUT, "ERROR: Unsupported response when creating db '{$this->database}' (http status code = {$statusCode}) " . $result . PHP_EOL); return; } } if ($this->separateFiles) { $files = array(); foreach (glob("{$this->separateFiles}/*") as $file) { if ($file != '.' && $file != '..' && $file != 'dummy') { $files[] = json_decode(file_get_contents($file), true); } } $decodedContent = new stdClass(); $decodedContent->new_edits = false; $decodedContent->docs = $files; } else { // post dump $fileContent = file_get_contents($filename); $decodedContent = json_decode($fileContent); } fwrite(STDOUT, ">>>>>>>>>>>>>>>>> RESTORING STARTED <<<<<<<<<<<<<<<<<<<<<" . PHP_EOL); foreach ($decodedContent->docs as $documentTemp) { if (!is_array($documentTemp)) { $documentTemp = (array) $documentTemp; } //we need to fetch the latest revision of the document, because in order to upload a new version of document we MUST know latest rev ID $url = "http://{$this->adminUrl}{$this->host}:{$this->port}/" . urlencode($this->database) . "/" . urlencode($documentTemp["_id"]); $curl = getCommonCurl($url); $result = trim(curl_exec($curl)); $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); if ($statusCode == 200) { $result = json_decode($result, true); if (isset($result["_rev"]) && $result["_rev"]) { $documentTemp["_rev"] = $result["_rev"]; } } if (isset($documentTemp["_revisions"])) { unset($documentTemp["_revisions"]); } $url = "http://{$this->adminUrl}{$this->host}:{$this->port}/" . urlencode($this->database) . "/" . urlencode($documentTemp["_id"]); fwrite(STDOUT, "Restoring '{$documentTemp['_id']}|rev:{$documentTemp['_rev']}' into db '{$this->database}' at {$this->host}:{$this->port}.." . PHP_EOL); //If we don't wont to upload attachments then we need to remove content from the file used for upload if (!$this->inlineAttachment && isset($documentTemp["_attachments"]) && $documentTemp["_attachments"]) { unset($documentTemp["_attachments"]); unset($documentTemp["unnamed"]); } $documentTemp = clearEmptyKey($documentTemp); $curl = getCommonCurl($url); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT'); /* or PUT */ curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($documentTemp)); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-type: application/json', 'Accept: */*')); // TODO: use next string when get ideas why it is not working and how to fix it. //curl_setopt($curl, CURLOPT_INFILE, $filehandle); // strange, but this does not work $result = trim(curl_exec($curl)); //fclose($filehandle); $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); /* if ($statusCode < 200 || 299 < $statusCode) { fwrite(STDOUT, "ERROR: Unable to post data to \"{$url}\" (http status code = {$statusCode}) " . $result . PHP_EOL); } */ $messages = json_decode($result, true); $errors = 0; if (is_array($messages)) { if (isset($messages['error'])) { $doc_id = isset($messages['id']) ? $messages['id'] : $documentTemp["_id"]; $reason = isset($messages['reason']) ? $messages['reason'] : $messages['error']; fwrite(STDOUT, "ERROR: [{$doc_id}] = {$reason}" . PHP_EOL); $errors++; } else { if (isset($messages['ok'])) { $doc_id = isset($messages['id']) ? $messages['id'] : '?'; fwrite(STDOUT, "SUCCESS: [{$doc_id}] restored!" . PHP_EOL); } } } } fwrite(STDOUT, ">>>>>>>>>>>>>>>>> RESTORING FINISHED! <<<<<<<<<<<<<<<<<<<<<" . PHP_EOL); }
public function download() { // get all docs IDs $url = "http://{$this->host}:{$this->port}/" . $this->database . "/_all_docs"; fwrite(STDERR, "Fetching all documents info from db '{$this->database}' at {$this->host}:{$this->port} ..." . PHP_EOL); $curl = getCommonCurl($url); $result = trim(curl_exec($curl)); $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); if (200 == $statusCode) { $all_docs = json_decode($result, true); } else { // unknown status fwrite(STDERR, "ERROR: Unsupported response when fetching all documents info from db '{$this->database}' (http status code = {$this->statusCode}) " . PHP_EOL); return; //exit(2); } if (!isset($all_docs['rows']) || !count($all_docs['rows']) || !is_array($all_docs['rows'])) { //if we want to save each document in separate file if ($this->separateFiles) { if (!file_exists('./' . $this->databaseName)) { mkdir('./' . $this->databaseName, 0777, true); } if (!count($all_docs['rows'])) { $dummy = fopen('./' . $this->databaseName . '/' . 'dummy', "a+"); fwrite($dummy, "1", 1); fclose($dummy); } } fwrite(STDERR, "ERROR: No documents found in db '{$this->database}'." . PHP_EOL); } if (!$this->separateFiles) { // first part of dump if (!$this->noHistory) { fwrite($this->fp, '{"new_edits":false,"docs":[' . PHP_EOL); } else { fwrite($this->fp, '{"docs":[' . PHP_EOL); } } $first = true; $count = count($all_docs['rows']); fwrite(STDERR, "Found {$count} documents..." . PHP_EOL); $i = 1; foreach ($all_docs['rows'] as $doc) { // foreach DOC get all revs if (!$this->noHistory) { $url = "http://{$this->host}:{$this->port}/{$this->database}/" . urlencode($doc['id']) . "?revs=true&revs_info=true" . ($this->inlineAttachment ? "&attachments=true" : ""); } else { $url = "http://{$this->host}:{$this->port}/{$this->database}/" . urlencode($doc['id']) . ($this->inlineAttachment || $this->binaryAttachments ? "?attachments=true" : ""); } //fwrite(STDERR, "[{$doc['id']}]"); $percentage = round($i++ / sizeof($all_docs['rows']) * 100, 2); fwrite(STDERR, "Processing database \"{$this->database}\": {$percentage}%\n"); $curl = getCommonCurl($url); curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-type: application/json', 'Accept: *\\/*')); $result = $wholeDocument = curl_exec($curl); $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); if (200 == $statusCode) { $doc_revs = json_decode($result); $doc_revs = (array) $doc_revs; } else { // unknown status fwrite(STDERR, "ERROR: Unsupported response when fetching document [{$doc['id']}] from db '{$this->database}' (http status code = {$statusCode}) " . PHP_EOL); return; //exit(2); } //REVISIONS if (isset($doc_revs['_revs_info']) && count($doc_revs['_revs_info']) > 1) { $revs_info = toArray($doc_revs["_revs_info"]); $revs_info = clearEmptyKey($revs_info); fwrite(STDERR, "" . PHP_EOL); // we have more than one revision $revs_info = array_reverse($revs_info); $lastRev = end($revs_info); $lastRev = $lastRev['rev']; reset($revs_info); foreach ($revs_info as $rev) { // foreach rev fetch DB/ID?rev=REV&revs=true //fwrite(STDERR, "[{$doc['id']}] @ {$rev['rev']}"); if ('available' === $rev['status']) { $url = "http://{$this->host}:{$this->port}/{$this->database}/" . urlencode($doc['id']) . "?revs=true&rev=" . urlencode($rev['rev']); $curl = getCommonCurl($url); $result = curl_exec($curl); $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); if (200 == $statusCode) { $full_doc = trim($result); } else { // unknown status fwrite(STDERR, "ERROR: Unsupported response when fetching document [{$doc['id']}] revision [{$rev['rev']}] from db '{$this->database}' (http status code = {$statusCode}) " . PHP_EOL); return; //exit(2); } if (is_callable($this->callbackFilter) && !call_user_func($this->callbackFilter, json_decode($full_doc, true), $lastRev)) { fwrite(STDERR, " = skipped" . PHP_EOL); continue; // skip that doc version because callback returned false } else { //fwrite(STDERR, "" . PHP_EOL); } } elseif ('missing' === $rev['status']) { //fwrite(STDERR, " = missing" . PHP_EOL); continue; // missing docs are not available anyhow } elseif ('deleted' === $rev['status']) { //fwrite(STDERR, " = deleted" . PHP_EOL); continue; // we will never get deleted docs as we do not have them in _all_docs list } else { //fwrite(STDERR, " = unsupported revision status" . PHP_EOL); continue; // who knows :) } if ($this->prettyJsonOutput) { $full_doc = indent($full_doc); } //if we want to save each document in separate file if ($this->separateFiles) { if (!file_exists('./' . $this->databaseName)) { mkdir('./' . $this->databaseName, 0777, true); } $myfile = fopen("./" . $this->databaseName . "/" . $doc['id'] . '_rev' . $rev['rev'] . ".json", "w"); fwrite($myfile, $full_doc); fclose($myfile); //Or if we want to join them together } else { // add document to dump if (!$first) { fwrite($this->fp, ', ' . PHP_EOL . $full_doc); } else { fwrite($this->fp, $full_doc); } $first = false; } } //NO REVISIONS } else { // we have only one revision unset($doc_revs['_revs_info']); $lastRev = $doc_revs['_rev']; if (is_callable($this->callbackFilter) && !call_user_func($this->callbackFilter, $doc_revs, $lastRev)) { fwrite(STDERR, " = skipped" . PHP_EOL); continue; // skip that doc version because callback returned false } else { fwrite(STDERR, "" . PHP_EOL); } if ($this->noHistory) { unset($doc_revs['_rev']); } if (!$this->inlineAttachment && !$this->binaryAttachments) { unset($doc_revs["_attachments"]); } $doc_revs = clearEmptyKey($doc_revs); $full_doc = json_encode($doc_revs, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); $doc_revs = toArray($doc_revs); if ($this->binaryAttachments && !$this->inlineAttachment && isset($doc_revs["_attachments"]) && $doc_revs["_attachments"]) { foreach ($doc_revs["_attachments"] as $key => $value) { $doc_revs["_attachments"][$key]["length"] = strlen($value["data"]); $doc_revs["_attachments"][$key]["stub"] = true; unset($doc_revs["_attachments"][$key]["data"]); } } if ($this->prettyJsonOutput) { $full_doc = indent($full_doc); } //IF we want to save each document in separate file if ($this->separateFiles) { if (!file_exists('./' . $this->databaseName)) { mkdir('./' . $this->databaseName, 0777, true); } $myfile = fopen("./" . $this->databaseName . "/" . $doc['id'] . ".json", "wb"); if ($myfile != false) { fwrite($myfile, $full_doc); fclose($myfile); } //Or if we want to join them together.. } else { if ($full_doc !== null && $full_doc !== false) { if (!$first) { fwrite($this->fp, ', ' . PHP_EOL . $full_doc); } else { fwrite($this->fp, $full_doc); } $first = false; } } /* * Binary attachments */ if ($this->binaryAttachments && $doc_revs["_attachments"]) { foreach ($doc_revs["_attachments"] as $attachment_id => $content) { $tempUrl = "http://{$this->host}:{$this->port}/{$this->database}/" . urlencode($doc['id']) . "/" . urlencode($attachment_id); $folder = $this->databaseName . '/' . $doc['id']; if (!file_exists('./' . $folder)) { mkdir('./' . $folder, 0777, true); } $ch = getCommonCurl($tempUrl); $fp = fopen('./' . $folder . '/' . $attachment_id, 'wb'); //download attachment to current folder curl_setopt($ch, CURLOPT_FILE, $fp); curl_setopt($ch, CURLOPT_HEADER, 0); curl_exec($ch); curl_close($ch); fclose($fp); } } } } // end of dump if (!$this->separateFiles) { fwrite($this->fp, PHP_EOL . ']}' . PHP_EOL); } if ($this->fp) { fclose($this->fp); } return; //exit(0); }
// create db fwrite(STDERR, "Creating database '{$database}'..." . PHP_EOL); $curl = getCommonCurl($url); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT'); $result = trim(curl_exec($curl)); $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); if (201 != $statusCode) { fwrite(STDERR, "ERROR: Unsupported response when creating db '{$database}' (http status code = {$statusCode}) " . $result . PHP_EOL); exit(2); } } // post dump $url = "http://{$host}:{$port}/{$database}/_bulk_docs"; fwrite(STDERR, "Restoring '{$filename}' into db '{$database}' at {$host}:{$port} ..." . PHP_EOL); $curl = getCommonCurl($url); curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, file_get_contents($filename)); // TODO: use next string when get ideas why it is not working and how to fix it. //curl_setopt($curl, CURLOPT_INFILE, $filehandle); // strange, but this does not work $result = trim(curl_exec($curl)); //fclose($filehandle); $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); if ($statusCode < 200 || 299 < $statusCode) { fwrite(STDERR, "ERROR: Unable to post data to \"{$url}\" (http status code = {$statusCode}) " . $result . PHP_EOL); exit(2); } $messages = json_decode($result, true); $errors = 0;
} else { fwrite(STDOUT, $full_doc); } $first = false; } /* * Binary attachments */ if ($binaryAttachments && $doc_revs["_attachments"]) { foreach ($doc_revs["_attachments"] as $attachment_id => $content) { $tempUrl = "http://{$host}:{$port}/{$database}/" . urlencode($doc['id']) . "/" . $attachment_id; //create folder if (!file_exists('./' . $doc['id'])) { mkdir('./' . $doc['id'], 0777, true); } $ch = getCommonCurl($tempUrl); $fp = fopen('./' . $doc['id'] . '/' . $attachment_id, 'wb'); //download attachment to current folder curl_setopt($ch, CURLOPT_FILE, $fp); curl_setopt($ch, CURLOPT_HEADER, 0); curl_exec($ch); curl_close($ch); fclose($fp); } } } } // end of dump fwrite(STDOUT, PHP_EOL . ']}' . PHP_EOL); exit(0); ////////////////////////////////////////////////////////////////////////////////