Upload files
A client can upload arbitrary files to Machbase-Neo via HTTP multipart/form-data encoding. The attached files are stored in the specified directory, and the database keeps the metadata of the file as a JSON string in the column.
Post the column and value in multipart/form-data encoding,
where the name of each part should be the column name and the value should be a string representation of the data.
Attach the file to a JSON type column with the X-Store-Dir header to specify the directory
where the file should be stored.
If the specified directory in X-Store-Dir does not exist, the server will create it automatically.
The file content will be stored in the directory with a generated unique name in UUID format.
Upload file
This demo assumes the STASH table has already been created:
CREATE TAG TABLE STASH(
NAME VARCHAR(80) primary key,
TIME DATETIME basetime,
DATA JSON
)This example uses Visual Studio Code’s REST Client extension.
```http
POST http://127.0.0.1:5654/db/write/STASH
Content-Type: multipart/form-data; boundary=----Boundary7MA4YWxkTrZu0gW
------Boundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="NAME"
camera-1
------Boundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="TIME"
now
------Boundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="DATA"; filename="image_file.svg"
X-Store-Dir: /tmp/store
Content-Type: image/svg
<svg xmlns="http://w3.org" width="100" height="100" viewBox="0 0 100 100">
<rect width="100" height="100" fill="red" />
<circle cx="50" cy="50" r="40" fill="blue" />
</svg>
------Boundary7MA4YWxkTrZu0gW--
```X-Store-Dir
The uploaded file content is stored in the directory specified by the X-Store-Dir header,
and the file name is based on the ID of the response.
The X-Store-Dir header can be included in the part’s header, as shown in the example above,
or it can be specified as a top-level header.
${data}
You can use the ${data} variable in the X-Store-Dir path to represent the database home directory. This directory is specified by the --data flag when launching the machbase-neo process, or it defaults to the sub-directory machbase_home under the directory where the machbase-neo executable resides if the --data flag is not used. Please refer to the document about command line flags.
For example, if you set X-Store-Dir: ${data}/store, the uploaded file will be saved in some/path/to/machbase_home/store/file_name_is_ID_of_the_response.
Response Message
Once the file is successfully uploaded, the server responds with the stored file information as shown below.
- ID : Unique id assigned by the server
- FN : Original file name
- SZ : File size
- CT : Content-Type
- SD : Stored directory path in the server side
{
"success":true,
"reason":"success, 1 record(s) inserted",
"elapse":"10.611208ms",
"data":{
"files":{
"DATA":{
"ID":"1f174fd2-cbd9-6d0e-b8a7-23fa7e810e6d",
"FN":"image_file.svg",
"SZ":177,
"CT":"image/svg+xml",
"SD":"/tmp/store"
}
}
}
}Metadata
The DATA column in the above example can be accessed as a normal JSON format “string” data
which contains the meta information of the uploaded file.
SELECT DATA FROM STASH
WHERE NAME = 'camera-1';Or, use JSON path:
SELECT DATA FROM STASH
WHERE NAME = 'camera-1'
AND DATA->'$.FN' = 'image_file.svg';/db/query Query
The following is an example of running a SELECT query with the /db/query API:
```http
GET http://127.0.0.1:5654/db/query
?q=select DATA from STASH where NAME = 'camera-1'
```JSON Path Query: -> Notation
```http
GET http://127.0.0.1:5654/db/query
?q=select DATA from STASH where NAME = 'camera-1' and DATA->'$.FN' = 'image_file.svg'
```The DATA column contains the file information as shown below.
{
"data": {
"columns": [ "DATA" ],
"types": [ "string" ],
"rows": [
[
"{\"ID\":\"1ef8a87f-96bd-6576-9ff5-972fa7638db8\",\"FN\":\"image_file.svg\",\"SZ\":177,\"CT\":\"image/svg+xml\",\"SD\":\"/tmp/store\"}"
]
]
},
"success": true,
"reason": "success",
"elapse": "843.666µs"
}Use JSON path to extract specific fields from the JSON type column:
```http
GET http://127.0.0.1:5654/db/query
?format=ndjson
&q=SELECT NAME, TIME, DATA->'$.ID' as FID FROM STASH WHERE NAME = 'camera-1'
```{"NAME":"camera-1","TIME":1728950208158594000,"FID":"1ef8a87f-96bd-6576-9ff5-972fa7638db8"}
{"NAME":"camera-1","TIME":1728953137384133000,"FID":"1ef8a8ec-b602-6cac-8fb1-ac9c0c1b981b"}Read content of the file
The file content can be accessed by the query API:
http://{server_address}/db/query/file/{table}/{column}/{ID}
If the table is TAG table, set tag parameter to improve the server response time:
http://{server_address}/db/query/{tag_table}/{column}/{ID}?tag=camera-1
If the table is a LOG table, the ID is generated based on the time when the record is inserted. For a TAG table, the ID is derived from the base time column of the record.
Since the ID contains timestamp information, Machbase-Neo uses it in the TIME between A and B clause for TAG tables or _ARRIVAL_TIME between A and B for LOG tables to narrow the search range.
Note that the timestamp in the ID is NOT exactly the same as the base time or _ARRIVAL_TIME of a LOG table, it is still useful for improving search performance.
HTTP GET
```http
GET http://127.0.0.1:5654/db/query/file/STASH/DATA/1ef8a87f-96bd-6576-9ff5-972fa7638db8
```Use <img> in HTML
<html>
<body>
<img src="http://127.0.0.1:5654/db/query/file/STASH/DATA/1ef8a87f-96bd-6576-9ff5-972fa7638db8"/>
</body>
</html>If the table is a TAG table and the tag name is known, use the tag query parameter to improve query performance:
<html>
<body>
<img src="http://127.0.0.1:5654/db/query/file/STASH/DATA/1ef8a87f-96bd-6576-9ff5-972fa7638db8?tag=camera-1"/>
</body>
</html>Examples
Javascript
Uploading file in Javascript.
const request = require('request');
const fs = require('fs');
let req = {
method: 'POST',
url: 'http://127.0.0.1:5654/db/write/STASH',
headers: {"X-Store-Dir": "/tmp/store"},
formData: {
NAME: 'camera-1',
TIME: 'now',
DATA: fs.createReadStream('./image_file.svg'),
},
};
request(req, function(err, res, body){
if (err) { console.log(err);
} else { console.log(body); }
})Python
Uploading file in Python.
from pathlib import Path
import requests
url = "http://127.0.0.1:5654/db/write/STASH"
file_path = Path("./image_file.svg")
with file_path.open("rb") as image_file:
response = requests.post(
url,
headers={"X-Store-Dir": "/tmp/store"},
data={"NAME": "camera-1", "TIME": "now"},
files={"DATA": (file_path.name, image_file, "image/svg")},
)
response.raise_for_status()
print(response.text)