Skip to content

Commit 462cbb1

Browse files
author
Antoine Huret
authored
handle not found errors in odoo.go to not repeat in every model (#50)
* handle not found errors in odoo.go to not repeat in every model + added errors variables ErrNotFound and ErrPartiallyFound * updated generator and clarified usage
1 parent 18d3bc8 commit 462cbb1

File tree

6 files changed

+52
-68
lines changed

6 files changed

+52
-68
lines changed

README.md

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,31 +11,8 @@ An Odoo API client enabling Go programs to interact with Odoo in a simple and un
1111

1212
### Generate your models
1313

14-
**Note: Generating models require to follow instructions in GOPATH mode. Refactoring for go modules will come soon.**
15-
16-
Define the environment variables to be able to connect to your odoo instance :
17-
18-
(Don't set `ODOO_MODELS` if you want all your models to be generated)
19-
20-
```
21-
export ODOO_ADMIN=admin // ensure the user has sufficient permissions to generate models
22-
export ODOO_PASSWORD=password
23-
export ODOO_DATABASE=odoo
24-
export ODOO_URL=http://localhost:8069
25-
export ODOO_MODELS="crm.lead"
26-
```
27-
28-
`ODOO_REPO_PATH` is the path where the repository will be downloaded (by default its GOPATH):
29-
```
30-
export ODOO_REPO_PATH=$(echo $GOPATH | awk -F ':' '{ print $1 }')/src/github.com/skilld-labs/go-odoo
31-
```
32-
33-
Download library and generate models :
34-
```
35-
GO111MODULE="off" go get github.com/skilld-labs/go-odoo
36-
cd $ODOO_REPO_PATH
37-
ls | grep -v "conversion.go\|generator\|go.mod\|go-odoo-generator\|go.sum\|ir_model_fields.go\|ir_model.go\|LICENSE\|odoo.go\|README.md\|types.go\|version.go" // keep only go-odoo core files
38-
GO111MODULE="off" go generate
14+
```bash
15+
./generator/generator -u admin_name -p admin_password -d database_name -o /the/directory/you/want/the/files/to/be/generated/in --url http://localhost:8069 -t ./generator/cmd/tmpl/model.tmpl -m crm.lead,res.users
3916
```
4017

4118
That's it ! Your models have been generated !
@@ -67,9 +44,9 @@ import (
6744

6845
func main() {
6946
c, err := odoo.NewClient(&odoo.ClientConfig{
70-
Admin: "admin",
71-
Password: "password",
72-
Database: "odoo",
47+
Admin: "admin_name",
48+
Password: "admin_password",
49+
Database: "database_name",
7350
URL: "http://localhost:8069",
7451
})
7552
if err != nil {

generator/cmd/generator.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cmd
22

33
import (
4+
"errors"
45
"fmt"
56
"os"
67
"os/exec"
@@ -80,6 +81,9 @@ func (g *generator) getAllModelsName() ([]string, error) {
8081
func (g *generator) modelFieldsFromModel(model string) ([]*modelField, error) {
8182
imfs, err := g.odoo.FindIrModelFieldss(odoo.NewCriteria().Add("model", "=", model), nil)
8283
if err != nil {
84+
if errors.Is(err, odoo.ErrNotFound) {
85+
return nil, nil
86+
}
8387
return nil, err
8488
}
8589
return g.irModelFieldsToModelFields(imfs), nil

generator/cmd/root.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313

1414
var (
1515
rootCmd = &cobra.Command{
16-
Use: "./go-odoo -u admin -p admin -d odoo --url http://localhost:8069 --models crm.lead",
16+
Use: "./go-odoo -u admin -p admin -d odoo --url http://localhost:8069 --models crm.lead -t generator/cmd/tmpl/model.tmpl",
1717
Short: "Generates your odoo models for go-odoo golang library.",
1818
Long: `
1919
Generates your odoo models for go-odoo golang library.
@@ -29,16 +29,17 @@ You can provide models name as arguments to specify what models to generate. By
2929
}
3030
},
3131
}
32-
database string
33-
admin string
34-
password string
35-
url string
36-
noFmt bool
37-
destFolder string
38-
models string
39-
c *odoo.Client
40-
t *template.Template
41-
g *generator
32+
database string
33+
admin string
34+
password string
35+
url string
36+
noFmt bool
37+
destFolder string
38+
models string
39+
modelTemplate string
40+
c *odoo.Client
41+
t *template.Template
42+
g *generator
4243
)
4344

4445
// Execute executes the root command.
@@ -57,6 +58,7 @@ func init() {
5758
rootCmd.PersistentFlags().StringVar(&url, "url", "http://localhost:8069", "the url of your odoo instance")
5859
rootCmd.PersistentFlags().StringVarP(&destFolder, "dest", "o", "", "the destination of generated models")
5960
rootCmd.PersistentFlags().StringVarP(&models, "models", "m", "", "the models you want to generate, separated by commas, empty means generate all")
61+
rootCmd.PersistentFlags().StringVarP(&modelTemplate, "template", "t", "", "the model template location used to generate the models code")
6062
rootCmd.PersistentFlags().BoolVar(&noFmt, "no-fmt", false, "specify if you want to disable auto format of generated models")
6163
}
6264

@@ -78,7 +80,7 @@ func initOdoo() {
7880

7981
func initTemplate() {
8082
var err error
81-
if t, err = template.New("model.tmpl").ParseFiles("./generator/cmd/tmpl/model.tmpl"); err != nil {
83+
if t, err = template.New("model.tmpl").ParseFiles(modelTemplate); err != nil {
8284
handleError(err)
8385
}
8486
}

generator/cmd/tmpl/model.tmpl

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
package odoo
22

3-
import (
4-
"fmt"
5-
)
6-
73
// {{.StructName}} represents {{ .Name }} model.
84
type {{.StructName}} struct { {{range .Fields}}
95
{{.VarName}} {{.Type}} `xmlrpc:"{{.Name}},omptempty"`{{end }}
@@ -68,10 +64,7 @@ func (c *Client) Get{{.StructName}}(id int64) (*{{.StructName}}, error) {
6864
if err != nil {
6965
return nil, err
7066
}
71-
if {{.VarsName}} != nil && len(*{{.VarsName}}) > 0 {
72-
return &((*{{.VarsName}})[0]), nil
73-
}
74-
return nil, fmt.Errorf("id %v of {{.Name}} not found", id)
67+
return &((*{{.VarsName}})[0]), nil
7568
}
7669

7770
// Get{{.StructName}}s gets {{ .Name }} existing records.
@@ -89,10 +82,7 @@ func (c *Client) Find{{.StructName}}(criteria *Criteria) (*{{.StructName}}, erro
8982
if err := c.SearchRead({{.StructName}}Model, criteria, NewOptions().Limit(1), {{.VarsName}}); err != nil {
9083
return nil, err
9184
}
92-
if {{.VarsName}} != nil && len(*{{.VarsName}}) > 0 {
93-
return &((*{{.VarsName}})[0]), nil
94-
}
95-
return nil, fmt.Errorf("{{ .Name }} was not found with criteria %v", criteria)
85+
return &((*{{.VarsName}})[0]), nil
9686
}
9787

9888
// Find{{.StructName}}s finds {{ .Name }} records by querying it
@@ -108,11 +98,7 @@ func (c *Client) Find{{.StructName}}s(criteria *Criteria, options *Options) (*{{
10898
// Find{{.StructName}}Ids finds records ids by querying it
10999
// and filtering it with criteria and options.
110100
func (c *Client) Find{{.StructName}}Ids(criteria *Criteria, options *Options) ([]int64, error) {
111-
ids, err := c.Search({{.StructName}}Model, criteria, options)
112-
if err != nil {
113-
return []int64{}, err
114-
}
115-
return ids, nil
101+
return c.Search({{.StructName}}Model, criteria, options)
116102
}
117103

118104
// Find{{.StructName}}Id finds record id by querying it with criteria.
@@ -121,8 +107,5 @@ func (c *Client) Find{{.StructName}}Id(criteria *Criteria, options *Options) (in
121107
if err != nil {
122108
return -1, err
123109
}
124-
if len(ids) > 0 {
125-
return ids[0], nil
126-
}
127-
return -1, fmt.Errorf("{{ .Name }} was not found with criteria %v and options %v", criteria, options)
110+
return ids[0], nil
128111
}

generator/generator

680 KB
Binary file not shown.

odoo.go

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
//Package odoo contains client code of library
2-
//go:generate ./generator/generator -u $ODOO_ADMIN -p $ODOO_PASSWORD -d $ODOO_DATABASE --url $ODOO_URL -o $ODOO_REPO_PATH --models $ODOO_MODELS
2+
//go:generate ./generator/generator -u $ODOO_ADMIN -p $ODOO_PASSWORD -d $ODOO_DATABASE --url $ODOO_URL -o $ODOO_REPO_PATH --models $ODOO_MODELS -t generator/cmd/tmpl/model.tmpl
33
package odoo
44

55
import (
66
"errors"
7+
"fmt"
78
"log"
89

910
"github.com/kolo/xmlrpc"
1011
)
1112

1213
var (
13-
errClientConfigurationInvalid = errors.New("client configuration is invalid")
14-
errClientNotAuthenticate = errors.New("client is not authenticate")
15-
errClientAuthentication = errors.New("client authentication error: please verify client configuration")
14+
ErrClientConfigurationInvalid = errors.New("client configuration is invalid")
15+
ErrClientNotAuthenticate = errors.New("client is not authenticate")
16+
ErrClientAuthentication = errors.New("client authentication error: please verify client configuration")
17+
ErrNotFound = errors.New("not found")
18+
ErrPartiallyFound = errors.New("partially found")
1619
)
1720

1821
// ClientConfig is the configuration to create a new *Client by givin connection infomations.
@@ -42,7 +45,7 @@ type Client struct {
4245
// NewClient creates a new *Client.
4346
func NewClient(cfg *ClientConfig) (*Client, error) {
4447
if !cfg.valid() {
45-
return nil, errClientConfigurationInvalid
48+
return nil, ErrClientConfigurationInvalid
4649
}
4750
c := &Client{
4851
cfg: cfg,
@@ -279,6 +282,10 @@ func (c *Client) SearchRead(model string, criteria *Criteria, options *Options,
279282
if err != nil {
280283
return err
281284
}
285+
respLen := len(resp.([]interface{}))
286+
if respLen == 0 {
287+
return fmt.Errorf("%s model was %w with criteria %v and options %v", model, ErrNotFound, criteria, options)
288+
}
282289
if err := convertFromDynamicToStatic(resp, elem); err != nil {
283290
return err
284291
}
@@ -292,9 +299,16 @@ func (c *Client) Read(model string, ids []int64, options *Options, elem interfac
292299
if err != nil {
293300
return err
294301
}
302+
respLen := len(resp.([]interface{}))
303+
if respLen == 0 {
304+
return fmt.Errorf("%s ids %v was %w with options %v", model, ids, ErrNotFound, options)
305+
}
295306
if err := convertFromDynamicToStatic(resp, elem); err != nil {
296307
return err
297308
}
309+
if respLen != len(ids) {
310+
return fmt.Errorf("%s ids %v was %w with options %v", model, ids, ErrPartiallyFound, options)
311+
}
298312
return nil
299313
}
300314

@@ -315,6 +329,10 @@ func (c *Client) Search(model string, criteria *Criteria, options *Options) ([]i
315329
if err != nil {
316330
return []int64{}, err
317331
}
332+
respLen := len(resp.([]interface{}))
333+
if respLen == 0 {
334+
return []int64{}, fmt.Errorf("%s model was %w with criteria %v and options %v", model, ErrNotFound, criteria, options)
335+
}
318336
return sliceInterfaceToInt64Slice(resp.([]interface{})), nil
319337
}
320338

@@ -348,7 +366,7 @@ func (c *Client) authenticate() error {
348366
return err
349367
}
350368
if _, ok := resp.(bool); ok {
351-
return errClientAuthentication
369+
return ErrClientAuthentication
352370
}
353371
c.uid = resp.(int64)
354372
c.auth = true
@@ -407,7 +425,7 @@ func (c *Client) loadXmlrpcClient(x *xmlrpc.Client, path string) error {
407425

408426
func (c *Client) checkForAuthentication() error {
409427
if !c.isAuthenticate() {
410-
return errClientNotAuthenticate
428+
return ErrClientNotAuthenticate
411429
}
412430
return nil
413431
}

0 commit comments

Comments
 (0)