Skip to content

Commit

Permalink
Merge pull request #44 from kintone-labs/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
Pham-Gia-Huong committed Mar 17, 2022
2 parents b83b0ff + 273ffde commit 27ae818
Show file tree
Hide file tree
Showing 9 changed files with 235 additions and 94 deletions.
114 changes: 94 additions & 20 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -57,6 +61,7 @@ func (e *AppError) Error() string {
type UpdateKeyField interface {
JSONValue() interface{}
}

type UpdateKey struct {
FieldCode string
Field UpdateKeyField
Expand Down Expand Up @@ -89,7 +94,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)}
// ...
// }
//
Expand All @@ -104,7 +109,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}
// ...
// }
Expand Down Expand Up @@ -181,6 +186,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)
Expand All @@ -196,7 +202,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 {
Expand Down Expand Up @@ -321,18 +327,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 {
Expand Down Expand Up @@ -460,7 +466,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")
Expand Down Expand Up @@ -552,7 +558,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
}
Expand Down Expand Up @@ -1015,10 +1021,80 @@ 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
}

// 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.
Expand All @@ -1027,7 +1103,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
}
Expand All @@ -1040,23 +1116,18 @@ 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
}

//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"`
Expand All @@ -1080,6 +1151,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
}

Expand Down Expand Up @@ -1112,8 +1186,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)
Expand Down
7 changes: 4 additions & 3 deletions app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -207,6 +206,7 @@ func newApp() *App {
AppId: KINTONE_APP_ID,
}
}

func newAppWithGuest() *App {
return &App{
Domain: KINTONE_DOMAIN,
Expand All @@ -216,6 +216,7 @@ func newAppWithGuest() *App {
GuestSpaceId: KINTONE_GUEST_SPACE_ID,
}
}

func newAppWithToken() *App {
return &App{
AppId: KINTONE_APP_ID,
Expand Down Expand Up @@ -259,6 +260,7 @@ func TestAddRecord(t *testing.T) {
t.Log(ids)
}
}

func TestGetRecord(t *testing.T) {
testData := GetTestDataGetRecord()
testDataRecords := GetTestDataGetRecords()
Expand Down Expand Up @@ -298,8 +300,8 @@ func TestGetRecord(t *testing.T) {
} else {
t.Log(len(recs))
}

}

func TestUpdateRecord(t *testing.T) {
testData := GetTestDataGetRecord()
testDataRecords := GetTestDataGetRecords()
Expand Down Expand Up @@ -359,7 +361,6 @@ func TestGetRecordsByCursor(t *testing.T) {
if err != nil {
t.Errorf("TestGetCursor is failed: %v", err)
}

}

func TestDeleteCursor(t *testing.T) {
Expand Down
7 changes: 5 additions & 2 deletions app_test_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ func GetTestDataDeleteRecords() *TestData {
output: `{}`,
}
}

func GetTestDataGetRecord() *TestData {
return &TestData{
input: []interface{}{1, true},
Expand Down Expand Up @@ -289,6 +290,7 @@ func GetDataTestDeleteRecordComment() *TestData {
output: `{}`,
}
}

func GetTestDataAddRecord() *TestData {
return &TestData{
output: `{
Expand Down Expand Up @@ -324,6 +326,7 @@ func GetDataTestAddRecord() *TestData {
}`,
}
}

func getDataTestCreateCursor() *TestData {
return &TestData{
output: `
Expand All @@ -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: `
Expand Down Expand Up @@ -384,6 +386,7 @@ func GetTestDataAddRecordComment() *TestData {
output: `{"id": "4"}`,
}
}

func GetTestDataUpdateRecordByKey() *TestData {
return &TestData{
input: []interface{}{2, "key", true},
Expand Down
6 changes: 4 additions & 2 deletions cursor.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,26 @@ 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 {
return nil, err
}
return c, nil
}

func DecodeGetRecordsCursorResponse(b []byte) (rc *GetRecordsCursorResponse, err error) {
var t struct {
Next bool `json:"next"`
Expand Down
8 changes: 4 additions & 4 deletions doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
Loading

0 comments on commit 27ae818

Please sign in to comment.