Produce valid JSON on export
The JSON export now generates valid JSON data, but this means that the resulting JSON format has changed. Fixes #12307 Signed-off-by: Michal Čihař <michal@cihar.com>
This commit is contained in:
parent
25ede08182
commit
136b85fc97
@ -17,6 +17,7 @@ phpMyAdmin - ChangeLog
|
||||
- issue #12196 Removed $cfg['ThemePath']
|
||||
- issue #6274 Add support for export user settings as config.inc.php snippet
|
||||
- issue #5555 Better report query errors while generating SQL exports
|
||||
- issue #12307 Produce valid JSON on export
|
||||
|
||||
4.6.3 (not yet released)
|
||||
- issue #12249 Fixed cookie path on Windows
|
||||
|
||||
@ -152,6 +152,88 @@ JSON (JavaScript Object Notation) is a lightweight data-interchange format. It
|
||||
is easy for humans to read and write and it is easy for machines to parse and
|
||||
generate.
|
||||
|
||||
.. versionchanged:: 4.7.0
|
||||
|
||||
The generated JSON structure has been changed in phpMyAdmin 4.7.0 to
|
||||
produce valid JSON data.
|
||||
|
||||
The generated JSON is list of objects with following attributes:
|
||||
|
||||
.. js:data:: type
|
||||
|
||||
Type of given object, can be one of:
|
||||
|
||||
``header``
|
||||
Export header containing comment and phpMyAdmin version.
|
||||
``database``
|
||||
Start of a database marker, containing name of database.
|
||||
``table``
|
||||
Table data export.
|
||||
|
||||
.. js:data:: version
|
||||
|
||||
Used in ``header`` :js:data:`type` and indicates phpMyAdmin version.
|
||||
|
||||
.. js:data:: comment
|
||||
|
||||
Optional textual comment.
|
||||
|
||||
.. js:data:: name
|
||||
|
||||
Object name - either table or database based on :js:data:`type`.
|
||||
|
||||
.. js:data:: database
|
||||
|
||||
Database name for ``table`` :js:data:`type`.
|
||||
|
||||
.. js:data:: data
|
||||
|
||||
Table content for ``table`` :js:data:`type`.
|
||||
|
||||
Sample output:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
[
|
||||
{
|
||||
"comment": "Export to JSON plugin for PHPMyAdmin",
|
||||
"type": "header",
|
||||
"version": "4.7.0-dev"
|
||||
},
|
||||
{
|
||||
"name": "cars",
|
||||
"type": "database"
|
||||
},
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"car_id": "1",
|
||||
"description": "Green Chrysler 300",
|
||||
"make_id": "5",
|
||||
"mileage": "113688",
|
||||
"price": "13545.00",
|
||||
"transmission": "automatic",
|
||||
"yearmade": "2007"
|
||||
}
|
||||
],
|
||||
"database": "cars",
|
||||
"name": "cars",
|
||||
"type": "table"
|
||||
},
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"make": "Chrysler",
|
||||
"make_id": "5"
|
||||
}
|
||||
],
|
||||
"database": "cars",
|
||||
"name": "makes",
|
||||
"type": "table"
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
LaTeX
|
||||
-----
|
||||
|
||||
|
||||
@ -24,6 +24,8 @@ use PMA;
|
||||
*/
|
||||
class ExportJson extends ExportPlugin
|
||||
{
|
||||
private $first = true;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
@ -32,6 +34,24 @@ class ExportJson extends ExportPlugin
|
||||
$this->setProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the data into JSON
|
||||
*
|
||||
* @param mixed $data Data to encode
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function encode($data)
|
||||
{
|
||||
if (isset($GLOBALS['json_pretty_print'])
|
||||
&& $GLOBALS['json_pretty_print']
|
||||
) {
|
||||
return json_encode($data, JSON_PRETTY_PRINT);
|
||||
} else {
|
||||
return json_encode($data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the export JSON properties
|
||||
*
|
||||
@ -79,14 +99,17 @@ class ExportJson extends ExportPlugin
|
||||
*/
|
||||
public function exportHeader()
|
||||
{
|
||||
PMA_exportOutputHandler(
|
||||
'/**' . $GLOBALS['crlf']
|
||||
. ' Export to JSON plugin for PHPMyAdmin' . $GLOBALS['crlf']
|
||||
. ' @version ' . PMA_VERSION . $GLOBALS['crlf']
|
||||
. ' */' . $GLOBALS['crlf'] . $GLOBALS['crlf']
|
||||
global $crlf;
|
||||
|
||||
$meta = array(
|
||||
'type' => 'header',
|
||||
'version' => PMA_VERSION,
|
||||
'comment' => 'Export to JSON plugin for PHPMyAdmin',
|
||||
);
|
||||
|
||||
return true;
|
||||
return PMA_exportOutputHandler(
|
||||
'[' . $crlf . $this->encode($meta) . ',' . $crlf
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -96,7 +119,9 @@ class ExportJson extends ExportPlugin
|
||||
*/
|
||||
public function exportFooter()
|
||||
{
|
||||
return true;
|
||||
global $crlf;
|
||||
|
||||
return PMA_exportOutputHandler(']' . $crlf);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -109,14 +134,20 @@ class ExportJson extends ExportPlugin
|
||||
*/
|
||||
public function exportDBHeader($db, $db_alias = '')
|
||||
{
|
||||
global $crlf;
|
||||
|
||||
if (empty($db_alias)) {
|
||||
$db_alias = $db;
|
||||
}
|
||||
PMA_exportOutputHandler(
|
||||
'// Database \'' . $db_alias . '\'' . $GLOBALS['crlf']
|
||||
|
||||
$meta = array(
|
||||
'type' => 'database',
|
||||
'name' => $db_alias
|
||||
);
|
||||
|
||||
return true;
|
||||
return PMA_exportOutputHandler(
|
||||
$this->encode($meta) . ',' . $crlf
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -169,6 +200,28 @@ class ExportJson extends ExportPlugin
|
||||
$table_alias = $table;
|
||||
$this->initAlias($aliases, $db_alias, $table_alias);
|
||||
|
||||
if (! $this->first) {
|
||||
if (!PMA_exportOutputHandler(',')) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$this->first = false;
|
||||
}
|
||||
|
||||
$buffer = $this->encode(
|
||||
array(
|
||||
'type' => 'table',
|
||||
'name' => $table_alias,
|
||||
'database' => $db_alias,
|
||||
'data' => "@@DATA@@"
|
||||
)
|
||||
);
|
||||
list($header, $footer) = explode('"@@DATA@@"', $buffer);
|
||||
|
||||
if (!PMA_exportOutputHandler($header . $crlf . '[' . $crlf)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = $GLOBALS['dbi']->query(
|
||||
$sql_query,
|
||||
null,
|
||||
@ -191,16 +244,10 @@ class ExportJson extends ExportPlugin
|
||||
$record_cnt++;
|
||||
|
||||
// Output table name as comment if this is the first record of the table
|
||||
if ($record_cnt == 1) {
|
||||
$buffer = $crlf . '// ' . $db_alias . '.' . $table_alias
|
||||
. $crlf . $crlf;
|
||||
$buffer .= '[';
|
||||
} else {
|
||||
$buffer = ', ';
|
||||
}
|
||||
|
||||
if (!PMA_exportOutputHandler($buffer)) {
|
||||
return false;
|
||||
if ($record_cnt > 1) {
|
||||
if (!PMA_exportOutputHandler(',' . $crlf)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$data = array();
|
||||
@ -209,23 +256,13 @@ class ExportJson extends ExportPlugin
|
||||
$data[$columns[$i]] = $record[$i];
|
||||
}
|
||||
|
||||
if (isset($GLOBALS['json_pretty_print'])
|
||||
&& $GLOBALS['json_pretty_print']
|
||||
) {
|
||||
$encoded = json_encode($data, JSON_PRETTY_PRINT);
|
||||
} else {
|
||||
$encoded = json_encode($data);
|
||||
}
|
||||
|
||||
if (!PMA_exportOutputHandler($encoded)) {
|
||||
if (!PMA_exportOutputHandler($this->encode($data))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($record_cnt) {
|
||||
if (!PMA_exportOutputHandler(']' . $crlf)) {
|
||||
return false;
|
||||
}
|
||||
if (!PMA_exportOutputHandler($crlf . ']' . $crlf . $footer . $crlf)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$GLOBALS['dbi']->freeResult($result);
|
||||
|
||||
@ -139,10 +139,10 @@ class ExportJsonTest extends PMATestCase
|
||||
$GLOBALS['crlf'] = "\n";
|
||||
|
||||
$this->expectOutputString(
|
||||
'/**' . "\n"
|
||||
. ' Export to JSON plugin for PHPMyAdmin' . "\n"
|
||||
. ' @version ' . PMA_VERSION . "\n"
|
||||
. ' */' . "\n" . "\n"
|
||||
"[\n"
|
||||
. '{"type":"header","version":"' . PMA_VERSION
|
||||
. '","comment":"Export to JSON plugin for PHPMyAdmin"},'
|
||||
. "\n"
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
@ -157,6 +157,10 @@ class ExportJsonTest extends PMATestCase
|
||||
*/
|
||||
public function testExportFooter()
|
||||
{
|
||||
$this->expectOutputString(
|
||||
']'
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$this->object->exportFooter()
|
||||
);
|
||||
@ -172,7 +176,7 @@ class ExportJsonTest extends PMATestCase
|
||||
$GLOBALS['crlf'] = "\n";
|
||||
|
||||
$this->expectOutputString(
|
||||
"// Database 'testDB'\n"
|
||||
'{"type":"database","name":"testDB"},' . "\n"
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
@ -243,8 +247,12 @@ class ExportJsonTest extends PMATestCase
|
||||
$GLOBALS['dbi'] = $dbi;
|
||||
|
||||
$this->expectOutputString(
|
||||
"\n// db.tbl\n\n" .
|
||||
"[{\"f1\":\"foo\"}, {\"f1\":\"bar\"}]\n"
|
||||
'{"type":"table","name":"tbl","database":"db","data":'
|
||||
. "\n[\n"
|
||||
. '{"f1":"foo"},'
|
||||
. "\n"
|
||||
. '{"f1":"bar"}'
|
||||
. "\n]\n}\n"
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user