From 13467cc41e1c7bbc8b647bfffc3d0cc801c01664 Mon Sep 17 00:00:00 2001 From: Sho Iizuka Date: Mon, 15 Jun 2020 16:35:54 +0000 Subject: [PATCH 1/8] Fix incomplete error check in (*App).CreateCursor() --- app.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app.go b/app.go index 60007a9..50bfefb 100644 --- a/app.go +++ b/app.go @@ -1080,6 +1080,9 @@ func (app *App) CreateCursor(fields []string, query string, size uint64) (*Curso return nil, err } result, err := decodeCursor(body) + if err != nil { + return nil, err + } return result, nil } From 194a128c83dd9435ebb3e538ed3bf4870fcef2b1 Mon Sep 17 00:00:00 2001 From: itchyny Date: Mon, 17 Jan 2022 23:28:02 +0900 Subject: [PATCH 2/8] fix json tags in process struct types --- process.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/process.go b/process.go index 3ba27d1..91d924b 100644 --- a/process.go +++ b/process.go @@ -33,20 +33,20 @@ type ProcessAction struct { // ProcessAssignee represents a ProcessState assignee type ProcessAssignee struct { - Type string `json:type` - Entities []*ProcessEntity `json:entities` + Type string `json:"type"` + Entities []*ProcessEntity `json:"entities"` } // ProcessEntity represents a process assignee entity type ProcessEntity struct { - Entity *Entity `json:entity` - IncludeSubs bool `json:includeSubs` + Entity *Entity `json:"entity"` + IncludeSubs bool `json:"includeSubs"` } // Entity is the concrete representation of a process entity type Entity struct { - Type string `json:type` - Code string `json:code` + Type string `json:"type"` + Code string `json:"code"` } func DecodeProcess(b []byte) (p *Process, err error) { From eae22f2bbb13b0da745631e8e818a1bbae48ea8b Mon Sep 17 00:00:00 2001 From: itchyny Date: Mon, 17 Jan 2022 23:36:20 +0900 Subject: [PATCH 3/8] fix GetProcess to include lang field in request body --- app.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.go b/app.go index 60007a9..041bdbc 100644 --- a/app.go +++ b/app.go @@ -460,7 +460,7 @@ func isAllowedLang(allowedLangs []string, lang string) bool { func (app *App) GetProcess(lang string) (process *Process, err error) { type request_body struct { App uint64 `json:"app,string"` - lang string `json:"lang,string"` + Lang string `json:"lang,string"` } if app.User == "" || app.Password == "" { err = errors.New("This API only supports password authentication") From e6cad0b5267f42950ff1dc285c397b6a90e9ef83 Mon Sep 17 00:00:00 2001 From: itchyny Date: Mon, 17 Jan 2022 23:43:37 +0900 Subject: [PATCH 4/8] fix temporary file name prefix on file upload --- app.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.go b/app.go index 60007a9..0e2bbfd 100644 --- a/app.go +++ b/app.go @@ -552,7 +552,7 @@ func escapeQuotes(s string) string { // // If successfully uploaded, the key string of the uploaded file is returned. func (app *App) Upload(fileName, contentType string, data io.Reader) (key string, err error) { - f, err := ioutil.TempFile("", "hoge") + f, err := ioutil.TempFile("", "go-kintone-") if err != nil { return } From b2bad3112da31dfa800d49dde4a61ce1d3d2353f Mon Sep 17 00:00:00 2001 From: itchyny Date: Thu, 20 Jan 2022 09:53:49 +0900 Subject: [PATCH 5/8] fix initialization of structs in documents --- app.go | 4 ++-- doc.go | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app.go b/app.go index 60007a9..7eea867 100644 --- a/app.go +++ b/app.go @@ -89,7 +89,7 @@ func (f UpdateKey) MarshalJSON() ([]byte, error) { // // func handler(w http.ResponseWriter, r *http.Request) { // c := appengine.NewContext(r) -// app := &kintone.App{urlfetch.Client(c)} +// app := &kintone.App{Client: urlfetch.Client(c)} // ... // } // @@ -104,7 +104,7 @@ func (f UpdateKey) MarshalJSON() ([]byte, error) { // func main() { // proxyURL, _ := url.Parse("https://proxy.example.com") // transport := &http.Transport{Proxy: http.ProxyURL(proxyURL)} -// client := &http.Client(Transport: transport) +// client := &http.Client{Transport: transport} // app := &kintone.App{Client: client} // ... // } diff --git a/doc.go b/doc.go index 0ce41cc..b68210f 100644 --- a/doc.go +++ b/doc.go @@ -10,10 +10,10 @@ See https://developer.kintone.io for API specs. ) ... app := &kintone.App{ - "example.cybozu.com", - "user1", - "password", - 25, + Domain: "example.cybozu.com", + User: "user1", + Password: "password", + AppId: 25, } To retrieve 3 records from a kintone app (id=25): From 7f1a0af51a696c1bdd90cbf3f60ccc6ffca8148c Mon Sep 17 00:00:00 2001 From: itchyny Date: Thu, 20 Jan 2022 10:07:23 +0900 Subject: [PATCH 6/8] apply gofumpt to all code --- app.go | 21 +++--- app_test.go | 7 +- app_test_json.go | 7 +- cursor.go | 6 +- field.go | 165 +++++++++++++++++++++++++++++++---------------- field_test.go | 4 +- 6 files changed, 137 insertions(+), 73 deletions(-) diff --git a/app.go b/app.go index 60007a9..9af6aa0 100644 --- a/app.go +++ b/app.go @@ -57,6 +57,7 @@ func (e *AppError) Error() string { type UpdateKeyField interface { JSONValue() interface{} } + type UpdateKey struct { FieldCode string Field UpdateKeyField @@ -181,6 +182,7 @@ func (app *App) createUrl(api string, query string) url.URL { } return resultUrl } + func (app *App) setAuth(request *http.Request) { if app.basicAuth { request.SetBasicAuth(app.basicAuthUser, app.basicAuthPassword) @@ -196,7 +198,7 @@ func (app *App) setAuth(request *http.Request) { } } -//NewRequest create a request connect to kintone api. +// NewRequest create a request connect to kintone api. func (app *App) NewRequest(method, url string, body io.Reader) (*http.Request, error) { bodyData := io.Reader(nil) if body != nil { @@ -321,18 +323,18 @@ func parseResponse(resp *http.Response) ([]byte, error) { } } - //Get other than the Errors property + // Get other than the Errors property var ae AppError json.Unmarshal(body, &ae) ae.HttpStatus = resp.Status ae.HttpStatusCode = resp.StatusCode - //Get the Errors property + // Get the Errors property var errors interface{} json.Unmarshal(body, &errors) msg := errors.(map[string]interface{}) v, ok := msg["errors"] - //If the Errors property exists + // If the Errors property exists if ok { result, err := json.Marshal(v) if err != nil { @@ -1015,7 +1017,8 @@ func (fi *FieldInfo) UnmarshalJSON(data []byte) error { t.MaxValue, t.MinValue, t.MaxLength, t.MinLength, t.Default, t.DefaultTime, t.Options, t.Expression, (t.Separator == "true"), - t.Medium, t.Format, t.Fields} + t.Medium, t.Format, t.Fields, + } return nil } @@ -1049,14 +1052,14 @@ func (app *App) Fields() (map[string]*FieldInfo, error) { } ret := make(map[string]*FieldInfo) - for i, _ := range t.Properties { + for i := range t.Properties { fi := &(t.Properties[i]) ret[fi.Code] = fi } return ret, nil } -//CreateCursor return the meta data of the Cursor in this application +// CreateCursor return the meta data of the Cursor in this application func (app *App) CreateCursor(fields []string, query string, size uint64) (*Cursor, error) { type cursor struct { App uint64 `json:"app"` @@ -1112,8 +1115,8 @@ func (app *App) DeleteCursor(id string) error { return nil } -//Using Cursor Id to get all records -//GetRecordsByCursor return the meta data of the Record in this application +// Using Cursor Id to get all records +// GetRecordsByCursor return the meta data of the Record in this application func (app *App) GetRecordsByCursor(id string) (*GetRecordsCursorResponse, error) { url := app.createUrl("records/cursor", "id="+id) request, err := app.NewRequest("GET", url.String(), nil) diff --git a/app_test.go b/app_test.go index c1fe851..67574f5 100644 --- a/app_test.go +++ b/app_test.go @@ -39,7 +39,6 @@ const ( func createServerTest(mux *http.ServeMux) (*httptest.Server, error) { ts := httptest.NewUnstartedServer(mux) listen, err := net.Listen("tcp", KINTONE_DOMAIN) - if err != nil { return nil, err } @@ -207,6 +206,7 @@ func newApp() *App { AppId: KINTONE_APP_ID, } } + func newAppWithGuest() *App { return &App{ Domain: KINTONE_DOMAIN, @@ -216,6 +216,7 @@ func newAppWithGuest() *App { GuestSpaceId: KINTONE_GUEST_SPACE_ID, } } + func newAppWithToken() *App { return &App{ AppId: KINTONE_APP_ID, @@ -259,6 +260,7 @@ func TestAddRecord(t *testing.T) { t.Log(ids) } } + func TestGetRecord(t *testing.T) { testData := GetTestDataGetRecord() testDataRecords := GetTestDataGetRecords() @@ -298,8 +300,8 @@ func TestGetRecord(t *testing.T) { } else { t.Log(len(recs)) } - } + func TestUpdateRecord(t *testing.T) { testData := GetTestDataGetRecord() testDataRecords := GetTestDataGetRecords() @@ -359,7 +361,6 @@ func TestGetRecordsByCursor(t *testing.T) { if err != nil { t.Errorf("TestGetCursor is failed: %v", err) } - } func TestDeleteCursor(t *testing.T) { diff --git a/app_test_json.go b/app_test_json.go index f38d07d..39b2276 100644 --- a/app_test_json.go +++ b/app_test_json.go @@ -88,6 +88,7 @@ func GetTestDataDeleteRecords() *TestData { output: `{}`, } } + func GetTestDataGetRecord() *TestData { return &TestData{ input: []interface{}{1, true}, @@ -289,6 +290,7 @@ func GetDataTestDeleteRecordComment() *TestData { output: `{}`, } } + func GetTestDataAddRecord() *TestData { return &TestData{ output: `{ @@ -324,6 +326,7 @@ func GetDataTestAddRecord() *TestData { }`, } } + func getDataTestCreateCursor() *TestData { return &TestData{ output: ` @@ -332,10 +335,9 @@ func getDataTestCreateCursor() *TestData { "totalCount": 123456 }`, } - } -func GetDataTestGetRecordsByCursor() *TestData { +func GetDataTestGetRecordsByCursor() *TestData { return &TestData{ input: []interface{}{"9a9716fe-1394-4677-a1c7-2199a5d28215"}, output: ` @@ -384,6 +386,7 @@ func GetTestDataAddRecordComment() *TestData { output: `{"id": "4"}`, } } + func GetTestDataUpdateRecordByKey() *TestData { return &TestData{ input: []interface{}{2, "key", true}, diff --git a/cursor.go b/cursor.go index 9494987..c474796 100644 --- a/cursor.go +++ b/cursor.go @@ -4,17 +4,18 @@ import ( "encoding/json" ) -//Object Cursor structure +// Object Cursor structure type Cursor struct { Id string `json:"id"` TotalCount string `json:"totalCount"` } + type GetRecordsCursorResponse struct { Records []*Record `json:"records"` Next bool `json:"next"` } -//decodeCursor decodes JSON response for cursor api +// decodeCursor decodes JSON response for cursor api func decodeCursor(b []byte) (c *Cursor, err error) { err = json.Unmarshal(b, &c) if err != nil { @@ -22,6 +23,7 @@ func decodeCursor(b []byte) (c *Cursor, err error) { } return c, nil } + func DecodeGetRecordsCursorResponse(b []byte) (rc *GetRecordsCursorResponse, err error) { var t struct { Next bool `json:"next"` diff --git a/field.go b/field.go index 49dd248..05d1123 100644 --- a/field.go +++ b/field.go @@ -44,9 +44,11 @@ const ( // SingleLineTextField is a field type for single-line texts. type SingleLineTextField string -func (f SingleLineTextField) JSONValue() (interface{}) { - return string(f); + +func (f SingleLineTextField) JSONValue() interface{} { + return string(f) } + func (f SingleLineTextField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_SINGLE_LINE_TEXT, @@ -56,9 +58,11 @@ func (f SingleLineTextField) MarshalJSON() ([]byte, error) { // MultiLineTextField is a field type for multi-line texts. type MultiLineTextField string -func (f MultiLineTextField) JSONValue() (interface{}) { - return string(f); + +func (f MultiLineTextField) JSONValue() interface{} { + return string(f) } + func (f MultiLineTextField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_MULTI_LINE_TEXT, @@ -68,9 +72,11 @@ func (f MultiLineTextField) MarshalJSON() ([]byte, error) { // RichTextField is a field type for HTML rich texts. type RichTextField string -func (f RichTextField) JSONValue() (interface{}) { - return string(f); + +func (f RichTextField) JSONValue() interface{} { + return string(f) } + func (f RichTextField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_RICH_TEXT, @@ -80,9 +86,11 @@ func (f RichTextField) MarshalJSON() ([]byte, error) { // DecimalField is a field type for decimal numbers. type DecimalField string -func (f DecimalField) JSONValue() (interface{}) { - return string(f); + +func (f DecimalField) JSONValue() interface{} { + return string(f) } + func (f DecimalField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_DECIMAL, @@ -92,9 +100,11 @@ func (f DecimalField) MarshalJSON() ([]byte, error) { // CalcField is a field type for auto-calculated values. type CalcField string -func (f CalcField) JSONValue() (interface{}) { - return string(f); + +func (f CalcField) JSONValue() interface{} { + return string(f) } + func (f CalcField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_CALC, @@ -104,9 +114,11 @@ func (f CalcField) MarshalJSON() ([]byte, error) { // CheckBoxField is a field type for selected values in a check-box. type CheckBoxField []string -func (f CheckBoxField) JSONValue() (interface{}) { - return []string(f); + +func (f CheckBoxField) JSONValue() interface{} { + return []string(f) } + func (f CheckBoxField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_CHECK_BOX, @@ -116,9 +128,11 @@ func (f CheckBoxField) MarshalJSON() ([]byte, error) { // RadioButtonField is a field type for the selected value by a radio-button. type RadioButtonField string -func (f RadioButtonField) JSONValue() (interface{}) { - return string(f); + +func (f RadioButtonField) JSONValue() interface{} { + return string(f) } + func (f RadioButtonField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_RADIO, @@ -131,13 +145,15 @@ type SingleSelectField struct { String string // Selected value. Valid bool // If not selected, false. } -func (f SingleSelectField) JSONValue() (interface{}) { + +func (f SingleSelectField) JSONValue() interface{} { if f.Valid { return f.String } else { return nil } } + func (f SingleSelectField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_SINGLE_SELECT, @@ -147,9 +163,11 @@ func (f SingleSelectField) MarshalJSON() ([]byte, error) { // MultiSelectField is a field type for selected values in a selection box. type MultiSelectField []string -func (f MultiSelectField) JSONValue() (interface{}) { - return []string(f); + +func (f MultiSelectField) JSONValue() interface{} { + return []string(f) } + func (f MultiSelectField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_MULTI_SELECT, @@ -164,6 +182,7 @@ type File struct { Name string `json:"name"` // File name Size uint64 `json:"size,string"` // The file size } + func (f *File) MarshalJSON() ([]byte, error) { return json.Marshal( map[string]interface{}{ @@ -176,9 +195,11 @@ func (f *File) MarshalJSON() ([]byte, error) { // FileField is a field type for uploaded files. type FileField []File -func (f FileField) JSONValue() (interface{}) { - return []File(f); + +func (f FileField) JSONValue() interface{} { + return []File(f) } + func (f FileField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_FILE, @@ -188,9 +209,11 @@ func (f FileField) MarshalJSON() ([]byte, error) { // LinkField is a field type for hyper-links. type LinkField string -func (f LinkField) JSONValue() (interface{}) { - return string(f); + +func (f LinkField) JSONValue() interface{} { + return string(f) } + func (f LinkField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_LINK, @@ -211,13 +234,15 @@ func NewDateField(year int, month time.Month, day int) DateField { true, } } -func (f DateField) JSONValue() (interface{}) { + +func (f DateField) JSONValue() interface{} { if f.Valid { - return f.Date.Format("2006-01-02"); + return f.Date.Format("2006-01-02") } else { - return nil; + return nil } } + func (f DateField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_DATE, @@ -238,13 +263,15 @@ func NewTimeField(hour, min int) TimeField { true, } } -func (f TimeField) JSONValue() (interface{}) { + +func (f TimeField) JSONValue() interface{} { if f.Valid { - return f.Time.Format("15:04:05"); + return f.Time.Format("15:04:05") } else { - return nil; + return nil } } + func (f TimeField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_TIME, @@ -265,13 +292,15 @@ func NewDateTimeField(year int, month time.Month, day, hour, min int) DateTimeFi true, } } -func (f DateTimeField) JSONValue() (interface{}) { + +func (f DateTimeField) JSONValue() interface{} { if f.Valid { - return f.Time.Format(time.RFC3339); + return f.Time.Format(time.RFC3339) } else { - return nil; + return nil } } + func (f DateTimeField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_DATETIME, @@ -287,9 +316,11 @@ type User struct { // UserField is a field type for user entries. type UserField []User -func (f UserField) JSONValue() (interface{}) { - return []User(f); + +func (f UserField) JSONValue() interface{} { + return []User(f) } + func (f UserField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_USER, @@ -305,9 +336,11 @@ type Organization struct { // OrganizationField is a field type for department entries. type OrganizationField []Organization -func (f OrganizationField) JSONValue() (interface{}) { - return []Organization(f); + +func (f OrganizationField) JSONValue() interface{} { + return []Organization(f) } + func (f OrganizationField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_ORGANIZATION, @@ -323,9 +356,11 @@ type Group struct { // GroupField is a field type for group(or role) entries. type GroupField []Group -func (f GroupField) JSONValue() (interface{}) { - return []Group(f); + +func (f GroupField) JSONValue() interface{} { + return []Group(f) } + func (f GroupField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_GROUP, @@ -335,9 +370,11 @@ func (f GroupField) MarshalJSON() ([]byte, error) { // CategoryField is a list of category names. type CategoryField []string -func (f CategoryField) JSONValue() (interface{}) { - return []string(f); + +func (f CategoryField) JSONValue() interface{} { + return []string(f) } + func (f CategoryField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_CATEGORY, @@ -347,9 +384,11 @@ func (f CategoryField) MarshalJSON() ([]byte, error) { // StatusField is a string label of a record status. type StatusField string -func (f StatusField) JSONValue() (interface{}) { - return string(f); + +func (f StatusField) JSONValue() interface{} { + return string(f) } + func (f StatusField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_STATUS, @@ -359,9 +398,11 @@ func (f StatusField) MarshalJSON() ([]byte, error) { // AssigneeField is a list of user entries who are assigned to a record. type AssigneeField []User -func (f AssigneeField) JSONValue() (interface{}) { - return []User(f); + +func (f AssigneeField) JSONValue() interface{} { + return []User(f) } + func (f AssigneeField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_ASSIGNEE, @@ -371,9 +412,11 @@ func (f AssigneeField) MarshalJSON() ([]byte, error) { // RecordNumberField is a record number. type RecordNumberField string -func (f RecordNumberField) JSONValue() (interface{}) { - return string(f); + +func (f RecordNumberField) JSONValue() interface{} { + return string(f) } + func (f RecordNumberField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_RECNUM, @@ -383,9 +426,11 @@ func (f RecordNumberField) MarshalJSON() ([]byte, error) { // CreatorField is a user who created a record. type CreatorField User -func (f CreatorField) JSONValue() (interface{}) { - return User(f); + +func (f CreatorField) JSONValue() interface{} { + return User(f) } + func (f CreatorField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_CREATOR, @@ -395,9 +440,11 @@ func (f CreatorField) MarshalJSON() ([]byte, error) { // CreationTimeField is the time when a record is created. type CreationTimeField time.Time -func (t CreationTimeField) JSONValue() (interface{}) { - return time.Time(t).Format(time.RFC3339); + +func (t CreationTimeField) JSONValue() interface{} { + return time.Time(t).Format(time.RFC3339) } + func (t CreationTimeField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_CTIME, @@ -407,9 +454,11 @@ func (t CreationTimeField) MarshalJSON() ([]byte, error) { // ModifierField is a user who modified a record last. type ModifierField User -func (f ModifierField) JSONValue() (interface{}) { - return User(f); + +func (f ModifierField) JSONValue() interface{} { + return User(f) } + func (f ModifierField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_MODIFIER, @@ -419,9 +468,11 @@ func (f ModifierField) MarshalJSON() ([]byte, error) { // ModificationTimeField is the time when a record is last modified. type ModificationTimeField time.Time -func (t ModificationTimeField) JSONValue() (interface{}) { - return time.Time(t).Format(time.RFC3339); + +func (t ModificationTimeField) JSONValue() interface{} { + return time.Time(t).Format(time.RFC3339) } + func (t ModificationTimeField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_MTIME, @@ -437,24 +488,26 @@ type SubTableEntry struct { // SubTableField is a list of subtable entries. type SubTableField []*Record -func (f SubTableField) JSONValue() (interface{}) { + +func (f SubTableField) JSONValue() interface{} { type sub_record struct { Record *Record `json:"value"` } type sub_record_with_id struct { - Id uint64 `json:"id,string"` + Id uint64 `json:"id,string"` Record *Record `json:"value"` } recs := make([]interface{}, 0, len(f)) for _, rec := range f { - if (rec.id == 0) { + if rec.id == 0 { recs = append(recs, sub_record{rec}) } else { recs = append(recs, sub_record_with_id{rec.id, rec}) } } - return recs; + return recs } + func (f SubTableField) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "type": FT_SUBTABLE, diff --git a/field_test.go b/field_test.go index 899bdaf..b70c2b5 100644 --- a/field_test.go +++ b/field_test.go @@ -719,7 +719,9 @@ func TestSubTableField(t *testing.T) { s := []SubTableEntry{ {Id: "123", Value: map[string]interface{}{ - "abc": RecordNumberField("12345")}}} + "abc": RecordNumberField("12345"), + }}, + } if len(s) != 1 { t.Error("Invalid size") } From 7e16f584de1126f6b4d85399556fa8f160db8f36 Mon Sep 17 00:00:00 2001 From: Pham-Gia-Huong Date: Tue, 8 Mar 2022 17:32:21 +0700 Subject: [PATCH 7/8] SSR-2114: Add NewRecordWithIdAndRevision function --- record.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/record.go b/record.go index e2ec6c3..ac4c8dc 100644 --- a/record.go +++ b/record.go @@ -39,6 +39,12 @@ func NewRecordWithId(id uint64, fields map[string]interface{}) *Record { return &Record{id, -1, fields} } +// NewRecordWithIdAndRevision creates using an existing record id and revision. +func NewRecordWithIdAndRevision(id uint64, revision int64, fields map[string]interface{}) *Record { + return &Record{id, revision, fields} + +} + // MarshalJSON marshals field data of a record into JSON. func (rec Record) MarshalJSON() ([]byte, error) { return json.Marshal(rec.Fields) From 09923e18c14558394fb6786ea6179d00bce28270 Mon Sep 17 00:00:00 2001 From: Pham-Gia-Huong Date: Mon, 14 Mar 2022 15:28:56 +0700 Subject: [PATCH 8/8] SSR-2114: change "form" to "app/form/fields" api --- app.go | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 8 deletions(-) diff --git a/app.go b/app.go index 60007a9..14769f6 100644 --- a/app.go +++ b/app.go @@ -46,6 +46,10 @@ type AppError struct { Errors string `json:"errors"` // Error Description. } +type AppFormFields struct { + Properties interface{} `json:"properties"` +} + func (e *AppError) Error() string { if len(e.Message) == 0 { return "HTTP error: " + e.HttpStatus @@ -1019,6 +1023,75 @@ func (fi *FieldInfo) UnmarshalJSON(data []byte) error { return nil } +// Decode JSON from app/form/fields.json +func decodeFieldInfo(t AppFormFields, ret map[string]*FieldInfo) { + itemsMap := t.Properties.(map[string]interface{}) + for k, v := range itemsMap { + fi := FieldInfo{} + for l, w := range v.(map[string]interface{}) { + switch l { + case "label": + fi.Label = w.(string) + case "code": + fi.Code = w.(string) + case "type": + fi.Type = w.(string) + case "noLabel": + fi.NoLabel = w.(bool) + case "required": + fi.Required = w.(bool) + case "unique": + fi.Unique = w.(bool) + case "maxValue": + fi.MaxValue = w + case "minValue": + fi.MaxValue = w + case "maxLength": + fi.MaxLength = w + case "minLength": + fi.MinLength = w + case "defaultValue": + fi.Default = w + case "defaultNowValue": + fi.DefaultTime = w + case "options": + var sa []string + for _, x := range w.(map[string]interface{}) { + sa = append(sa, x.(map[string]interface{})["label"].(string)) + } + fi.Options = sa + case "expression": + fi.Expression = w.(string) + case "digit": + fi.Separator = w.(bool) + case "protocol": + fi.Medium = w.(string) + case "format": + fi.Format = w.(string) + case "fields": + ret := make(map[string]*FieldInfo) + var y AppFormFields + y.Properties = w + decodeFieldInfo(y, ret) + var sb []FieldInfo + for z, _ := range ret { + sb = append(sb, *ret[z]) + } + fi.Fields = sb + default: break; + } + } + switch fi.Type { + case "GROUP": + // Do not add to []FieldInfo + case "REFERENCE_TABLE": + // Do not add to []FieldInfo + default: + ret[k] = &fi + } + } +} + // Fields returns the meta data of the fields in this application. // // If successful, a mapping between field codes and FieldInfo is returned. @@ -1027,7 +1100,7 @@ func (app *App) Fields() (map[string]*FieldInfo, error) { App uint64 `json:"app,string"` } data, _ := json.Marshal(request_body{app.AppId}) - req, err := app.newRequest("GET", "form", bytes.NewReader(data)) + req, err := app.newRequest("GET", "app/form/fields", bytes.NewReader(data)) if err != nil { return nil, err } @@ -1040,19 +1113,15 @@ func (app *App) Fields() (map[string]*FieldInfo, error) { return nil, err } - var t struct { - Properties []FieldInfo `json:"properties"` - } + var t AppFormFields err = json.Unmarshal(body, &t) if err != nil { return nil, ErrInvalidResponse } ret := make(map[string]*FieldInfo) - for i, _ := range t.Properties { - fi := &(t.Properties[i]) - ret[fi.Code] = fi - } + decodeFieldInfo(t, ret) + return ret, nil }