Skip to content

Commit 42ebfb7

Browse files
authored
Merge pull request #198 from tableflowhq/feature/schemaless-data-types
Schemaless data types support
2 parents 9f0f80f + 0a8f344 commit 42ebfb7

35 files changed

+392
-149
lines changed

admin-server/docs/docs.go

Lines changed: 10 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

admin-server/docs/swagger.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@
321321
"schema": {
322322
"type": "object",
323323
"additionalProperties": {
324-
"type": "string"
324+
"$ref": "#/definitions/types.UploadColumnMapping"
325325
}
326326
}
327327
}
@@ -780,6 +780,15 @@
780780
}
781781
}
782782
},
783+
"types.UploadColumnMapping": {
784+
"type": "object",
785+
"properties": {
786+
"template_column_id": {
787+
"type": "string",
788+
"example": "a1ed136d-33ce-4b7e-a7a4-8a5ccfe54cd5"
789+
}
790+
}
791+
},
783792
"types.UploadHeaderRowSelection": {
784793
"type": "object",
785794
"properties": {

admin-server/docs/swagger.yaml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,12 @@ definitions:
260260
example: a1ed136d-33ce-4b7e-a7a4-8a5ccfe54cd5
261261
type: string
262262
type: object
263+
types.UploadColumnMapping:
264+
properties:
265+
template_column_id:
266+
example: a1ed136d-33ce-4b7e-a7a4-8a5ccfe54cd5
267+
type: string
268+
type: object
263269
types.UploadHeaderRowSelection:
264270
properties:
265271
index:
@@ -518,7 +524,7 @@ paths:
518524
required: true
519525
schema:
520526
additionalProperties:
521-
type: string
527+
$ref: '#/definitions/types.UploadColumnMapping'
522528
type: object
523529
responses:
524530
"200":

admin-server/go/pkg/types/importer.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ type UploadHeaderRowSelection struct {
7979
Index *int `json:"index" example:"0"`
8080
}
8181

82+
type UploadColumnMapping struct {
83+
TemplateColumnID string `json:"template_column_id" example:"a1ed136d-33ce-4b7e-a7a4-8a5ccfe54cd5"`
84+
}
85+
8286
type UploadRow struct {
8387
Index int `json:"index" example:"0"`
8488
Values map[int]string `json:"values"`

admin-server/go/pkg/web/file_import_routes.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -344,23 +344,28 @@ func importerSetHeaderRow(c *gin.Context) {
344344
// @Success 200 {object} types.Res
345345
// @Failure 400 {object} types.Res
346346
// @Router /file-import/v1/upload/{id}/set-column-mapping [post]
347-
// @Param id path string true "Upload ID"
348-
// @Param body body map[string]string true "Request body"
347+
// @Param id path string true "Upload ID"
348+
// @Param body body map[string]types.UploadColumnMapping true "Request body"
349349
func importerSetColumnMapping(c *gin.Context) {
350350
id := c.Param("id")
351351
if len(id) == 0 {
352352
c.AbortWithStatusJSON(http.StatusBadRequest, types.Res{Err: "No upload ID provided"})
353353
return
354354
}
355355

356-
// Non-schemaless: Upload column ID -> Template column ID
357-
// Schemaless: Upload column ID -> User-provided key (i.e. first_name) (only from the request, this will be updated to IDs after the template is generated)
358-
columnMapping := make(map[string]string)
359-
if err := c.ShouldBindJSON(&columnMapping); err != nil {
356+
columnMappingRequest := make(map[string]types.UploadColumnMapping)
357+
if err := c.ShouldBindJSON(&columnMappingRequest); err != nil {
360358
tf.Log.Warnw("Could not bind JSON", "error", err)
361359
c.AbortWithStatusJSON(http.StatusBadRequest, types.Res{Err: err.Error()})
362360
return
363361
}
362+
363+
// Non-schemaless: Upload column ID -> Template column ID
364+
// Schemaless: Upload column ID -> User-provided key (i.e. first_name) (only from the request, this will be updated to IDs after the template is generated)
365+
columnMapping := make(map[string]string)
366+
for k, mappingSelection := range columnMappingRequest {
367+
columnMapping[k] = mappingSelection.TemplateColumnID
368+
}
364369
if len(columnMapping) == 0 {
365370
c.AbortWithStatusJSON(http.StatusBadRequest, types.Res{Err: "Please select at least one destination column"})
366371
return

docs/api-reference/download-import.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@
22
title: "Download Import CSV"
33
openapi: "GET /import/{id}/download"
44
---
5+
6+
Retrieve an import as a CSV file.

docs/api-reference/get-import-rows.mdx

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,31 @@ title: "Get Import Rows"
33
openapi: "GET /import/{id}/rows"
44
---
55

6-
Retrieve the rows of an import as JSON. This endpoint supports pagination by using a limit/offset. If the limit and offset are not provided, it will return the first 1000 rows of the import.
6+
Retrieve the rows of an import as JSON. This endpoint supports pagination by using a limit/offset. If the limit and offset are not provided, it will return the first 1,000 rows of the import.
77

88
To use the limit/offset, start by setting the offset to 0 and the limit to 100 to get the first 100 rows of data. To get the next 100 rows, set the offset to 100 while keeping the limit the same. Continue increasing the offset by 100 until no more rows are returned.
99

10-
Note: the max limit is 1000.
10+
<Info>The maximum `limit` is 1000.</Info>
11+
12+
### Example Response
13+
14+
```json
15+
[
16+
{
17+
"index": 0,
18+
"values": {
19+
"age": 23,
20+
"email": "[email protected]",
21+
"first_name": "Maria"
22+
}
23+
},
24+
{
25+
"index": 1,
26+
"values": {
27+
"age": 32,
28+
"email": "[email protected]",
29+
"first_name": "Robert"
30+
}
31+
}
32+
]
33+
```

docs/api-reference/get-import.mdx

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,63 @@
11
---
2-
title: "Get Import Metadata"
2+
title: "Get Import"
33
openapi: "GET /import/{id}"
44
---
5+
6+
Retrieve the row data, column definitions, and other information about the import.
7+
8+
<Info>The number of rows included is limited to 10,000. If there are more than 10,000 rows, an `error` will be set and
9+
the data should be retrieved using the [/rows](/api-reference/get-import-rows) endpoint.</Info>
10+
11+
### Example Response
12+
13+
```json
14+
{
15+
"id": "da5554e3-6c87-41b2-9366-5449a2f15b53",
16+
"importer_id": "a0fadb1d-9888-4fcb-b185-25b984bcb227",
17+
"num_rows": 2,
18+
"num_columns": 3,
19+
"num_processed_values": 5,
20+
"metadata": {
21+
"user_id": 1234,
22+
"user_email": "[email protected]",
23+
"environment": "staging"
24+
},
25+
"created_at": 1698172312,
26+
"error": null,
27+
"columns": [
28+
{
29+
"data_type": "number",
30+
"key": "age",
31+
"name": "Age"
32+
},
33+
{
34+
"data_type": "string",
35+
"key": "email",
36+
"name": "Email"
37+
},
38+
{
39+
"data_type": "string",
40+
"key": "first_name",
41+
"name": "First Name"
42+
}
43+
],
44+
"rows": [
45+
{
46+
"index": 0,
47+
"values": {
48+
"age": 23,
49+
"email": "[email protected]",
50+
"first_name": "Maria"
51+
}
52+
},
53+
{
54+
"index": 1,
55+
"values": {
56+
"age": 32,
57+
"email": "[email protected]",
58+
"first_name": "Robert"
59+
}
60+
}
61+
]
62+
}
63+
```
Loading
Loading

0 commit comments

Comments
 (0)