https://github.com/Aaron2963/json_schema_sql_builder
https://github.com/Aaron2963/json_schema_sql_builder
Last synced: 5 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/Aaron2963/json_schema_sql_builder
- Owner: Aaron2963
- Created: 2023-06-09T08:31:31.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2024-11-14T08:42:29.000Z (5 months ago)
- Last Synced: 2024-11-14T09:33:35.701Z (5 months ago)
- Language: PHP
- Size: 35.2 KB
- Stars: 4
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- jimsghstars - Aaron2963/json_schema_sql_builder - (PHP)
README
# JSON Schema SQL Builder
This is a simple tool to generate SQL DDL statements from a JSON Schema.
## Install
```bash
$ composer require aaron-lin/json-schema-sql-builder
```## Usage
### Build SELECT Statement from JSON Schema
For example, the JSON schema is as following:
```json
{
"$schema": "http://json-schema.org/draft-06/schema#",
"@table": "products",
"@id": "id",
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"_type_name": {
"type": "string"
},
"_weight": {
"type": "object",
"properties": {
"weight": {
"type": "number"
},
"weight_unit": {
"type": "string",
"enum": [
"g",
"kg"
]
}
}
},
"_bids": {
"type": "array",
"@table": "bids",
"@joinId": "product_id",
"@id": "id",
"@orderBy": "time DESC",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"price": {
"type": "number"
},
"time": {
"type": "string",
"format": "date-time"
}
}
}
}
}
}
```Use the following code to run the SQL SELECT query:
```php
use Lin\JsonSchemaSqlBuilder\Storage;
use Lin\JsonSchemaSqlBuilder\SelectSQLBuilder;$SchemaURI = 'path/to/schema.json#';
$DSN = 'mysql:host=db;dbname=test;charset=utf8mb4';
$DB = new \PDO($DSN, 'test', 'test');try {
Storage::SetSchemaFromURI($SchemaURI);
} catch (\Exception $e) {
echo $e->getMessage();
exit;
}
Storage::AddSelectExpression($SchemaURI . '#/properties/_type_name', '(SELECT name FROM product_types WHERE product_types.id = products.type_id LIMIT 1)');
Storage::AddSelectExpression($SchemaURI . '#/properties/_weight/properties/weight', 'products.weight');
Storage::AddSelectExpression($SchemaURI . '#/properties/_weight/properties/weight_unit', 'products.weight_unit');
$Builder = new SelectSQLBuilder($SchemaURI, $DB);
$Builder->SetSelectExpressions()
->AddWhere("products.keywords like :keywords", ['keywords' => '%apple%'])
->AddOrderBy('products.price', 'DESC')
->SetLimit(10)
->SetOffset(0);
$Result = $Builder->Execute();
echo json_encode($Result, JSON_PRETTY_PRINT);
// [
// {
// "id": "1",
// "name": "Apple",
// "_type_name": "Fruit",
// "_weight": {
// "weight": "100.00",
// "weight_unit": "g"
// },
// "_bids": [
// {
// "id": "7",
// "price": "400",
// "time": "2018-01-04 00:00:00"
// },
// {
// "id": "5",
// "price": "300",
// "time": "2018-01-03 00:00:00"
// },
// {
// "id": "3",
// "price": "200",
// "time": "2018-01-02 00:00:00"
// },
// {
// "id": "1",
// "price": "100",
// "time": "2018-01-01 00:00:00"
// }
// ]
// }
// ]
```As you can see, after initializing JSON schema storage, you can add select expressions to indirect corresponding properties (direct properties are automatically added to select expressions as `table_name.property_key`). Then you can build the SQL SELECT statement with `SelectSQLBuilder::Build` method. For more information, please refer to [the test script](test/select-sql-builder.php), you can also find database schema and data in [the test directory](test/).
### Build INSERT/UPDATE Statement from JSON Schema
For example, the JSON schema is as following:
```json
{
"$schema": "http://json-schema.org/draft-06/schema#",
"@table": "products",
"@id": "id",
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"_type_name": {
"type": "string",
"readonly": true
},
"_weight": {
"type": "object",
"properties": {
"weight": {
"type": "number"
},
"weight_unit": {
"type": "string",
"enum": [
"g",
"kg"
]
}
}
},
"_bids": {
"type": "array",
"@table": "bids",
"@joinId": "product_id",
"@id": "id",
"@orderBy": "time DESC",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"price": {
"type": "number"
},
"time": {
"type": "string",
"format": "date-time"
}
}
}
}
}
}
```And the data is as following:
```json
{
"id": "1",
"name": "Apple",
"_type_name": "Fruit",
"_weight": {
"weight": "100.00",
"weight_unit": "g"
},
"_bids": [
{
"id": "7",
"price": "400",
"time": "2018-01-04 00:00:00"
},
{
"id": "5",
"price": "300",
"time": "2018-01-03 00:00:00"
},
{
"id": "3",
"price": "200",
"time": "2018-01-02 00:00:00"
},
{
"id": "1",
"price": "100",
"time": "2018-01-01 00:00:00"
}
]
}
```Use the following code to run the SQL INSERT/UPDATE query:
```php
use Lin\JsonSchemaSqlBuilder\Storage;
use Lin\JsonSchemaSqlBuilder\UpsertSQLBuilder;$SchemaURI = __DIR__ . '/schema.json#';
$DSN = 'mysql:host=db;dbname=test;charset=utf8mb4';
$DB = new \PDO($DSN, 'test', 'test');try {
Storage::SetSchemaFromURI($SchemaURI);
} catch (\Exception $e) {
echo $e->getMessage();
exit;
}Storage::AddSelectExpression($SchemaURI . '#/properties/_weight/properties/weight', 'products.weight');
Storage::AddSelectExpression($SchemaURI . '#/properties/_weight/properties/weight_unit', 'products.weight_unit');
$Builder = new UpsertSQLBuilder($SchemaURI, $DB, $Data);
$Builder->SetAssignmentList();
$ResultCount = $Builder->Execute();
echo $ResultCount;
// for every new rows added, the return value is 1,
// for every existing rows updated, the return value is 2.
// data contains 1 row in products, 4 rows in bids,
// therefore, if data are all new rows, the return value is 5,
// or data are all existing rows, the return value is 10
```For every new rows added, the return value of `UpsertSQLBuilder::Execute` is `1`, for every existing rows updated, the return value is `2`. For more information, please refer to [the test script](test/upsert-sql-builder.php), you can also find database schema and data in [the test directory](test/).