[FW][ADD] rpc: Go examples

Examples rely on `kolo/xmlrpc` as well as on the standard library package `log` to panic on error, matching snippets in other languages (which tend to raise exceptions).

As with other languages, only the RPC interaction is spelled out.

closes 

Forward-port-of: 
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
This commit is contained in:
Henrique Dias 2023-07-14 15:41:19 +02:00 committed by GitHub
parent d0a07fdb9a
commit 12a79168a7

View File

@ -72,6 +72,15 @@ If you already have an Odoo server installed, you can just use its parameters.
username = "admin", username = "admin",
password = <insert password for your admin user (default: admin)>; password = <insert password for your admin user (default: admin)>;
.. code-tab:: go
var (
url = <insert server URL>
db = <insert database name>
username = "admin"
password = <insert password for your admin user (default: admin)>
)
.. _api/external_api/keys: .. _api/external_api/keys:
API Keys API Keys
@ -180,6 +189,27 @@ database:
The examples do not include imports as these imports couldn't be The examples do not include imports as these imports couldn't be
pasted in the code. pasted in the code.
.. group-tab:: Go
.. code-block:: go
client, err := xmlrpc.NewClient("https://demo.odoo.com/start", nil)
if err != nil {
log.Fatal(err)
}
info := map[string]string{}
client.Call("start", nil, &info)
url = info["host"].(string)
db = info["database"].(string)
username = info["user"].(string)
password = info["password"].(string)
.. note::
These examples use the `github.com/kolo/xmlrpc library <https://github.com/kolo/xmlrpc>`_.
The examples do not include imports as these imports couldn't be
pasted in the code.
Logging in Logging in
---------- ----------
@ -217,6 +247,17 @@ the login.
common_config.setServerURL(new URL(String.format("%s/xmlrpc/2/common", url))); common_config.setServerURL(new URL(String.format("%s/xmlrpc/2/common", url)));
client.execute(common_config, "version", emptyList()); client.execute(common_config, "version", emptyList());
.. code-tab:: go
client, err := xmlrpc.NewClient(fmt.Sprintf("%s/xmlrpc/2/common", url), nil)
if err != nil {
log.Fatal(err)
}
common := map[string]any{}
if err := client.Call("version", nil, &common); err != nil {
log.Fatal(err)
}
Result: Result:
.. code-block:: json .. code-block:: json
@ -247,6 +288,16 @@ Result:
int uid = (int)client.execute(common_config, "authenticate", asList(db, username, password, emptyMap())); int uid = (int)client.execute(common_config, "authenticate", asList(db, username, password, emptyMap()));
.. code-tab:: go
var uid int64
if err := client.Call("authenticate", []any{
db, username, password,
map[string]any{},
}, &uid); err != nil {
log.Fatal(err)
}
.. _api/external_api/calling_methods: .. _api/external_api/calling_methods:
Calling methods Calling methods
@ -303,6 +354,22 @@ Each call to ``execute_kw`` takes the following parameters:
new HashMap() {{ put("raise_exception", false); }} new HashMap() {{ put("raise_exception", false); }}
)); ));
.. code-tab:: go
models, err := xmlrpc.NewClient(fmt.Sprintf("%s/xmlrpc/2/object", url), nil)
if err != nil {
log.Fatal(err)
}
var result bool
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "check_access_rights",
[]string{"read"},
map[string]bool{"raise_exception": false},
}, &result); err != nil {
log.Fatal(err)
}
Result: Result:
.. code-block:: json .. code-block:: json
@ -345,6 +412,19 @@ database identifiers of all records matching the filter.
asList("is_company", "=", true))) asList("is_company", "=", true)))
))); )));
.. code-tab:: go
var records []int64
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "search",
[]any{[]any{
[]any{"is_company", "=", true},
}},
}, &records); err != nil {
log.Fatal(err)
}
Result: Result:
.. code-block:: json .. code-block:: json
@ -384,6 +464,20 @@ available to only retrieve a subset of all matched records.
new HashMap() {{ put("offset", 10); put("limit", 5); }} new HashMap() {{ put("offset", 10); put("limit", 5); }}
))); )));
.. code-tab:: go
var records []int64
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "search",
[]any{[]any{
[]any{"is_company", "=", true},
}},
map[string]int64{"offset": 10, "limit": 5},
}, &records); err != nil {
log.Fatal(err)
}
Result: Result:
.. code-block:: json .. code-block:: json
@ -424,6 +518,19 @@ only the number of records matching the query. It takes the same
asList("is_company", "=", true))) asList("is_company", "=", true)))
)); ));
.. code-tab:: go
var counter int64
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "search_count",
[]any{[]any{
[]any{"is_company", "=", true},
}},
}, &counter); err != nil {
log.Fatal(err)
}
Result: Result:
.. code-block:: json .. code-block:: json
@ -488,6 +595,30 @@ which tends to be a huge amount.
// count the number of fields fetched by default // count the number of fields fetched by default
record.size(); record.size();
.. code-tab:: go
var ids []int64
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "search",
[]any{[]any{
[]any{"is_company", "=", true},
}},
map[string]int64{"limit": 1},
}, &ids); err != nil {
log.Fatal(err)
}
var records []any
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "read",
ids,
}, &records); err != nil {
log.Fatal(err)
}
// count the number of fields fetched by default
count := len(records)
Result: Result:
.. code-block:: json .. code-block:: json
@ -521,6 +652,20 @@ which tends to be a huge amount.
}} }}
))); )));
.. code-tab:: go
var recordFields []map[string]any
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "read",
ids,
map[string][]string{
"fields": {"name", "country_id", "comment"},
},
}, &recordFields); err != nil {
log.Fatal(err)
}
Result: Result:
.. code-block:: json .. code-block:: json
@ -569,6 +714,20 @@ updating a record).
}} }}
)); ));
.. code-tab:: go
recordFields := map[string]string{}
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "fields_get",
[]any{},
map[string][]string{
"attributes": {"string", "help", "type"},
},
}, &recordFields); err != nil {
log.Fatal(err)
}
Result: Result:
.. code-block:: json .. code-block:: json
@ -652,6 +811,23 @@ if that list is not provided it will fetch all fields of matched records).
}} }}
))); )));
.. code-tab:: go
var recordFields []map[string]any
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "search_read",
[]any{[]any{
[]any{"is_company", "=", true},
}},
map[string]any{
"fields": []string{"name", "country_id", "comment"},
"limit": 5,
},
}, &recordFields); err != nil {
log.Fatal(err)
}
Result: Result:
.. code-block:: json .. code-block:: json
@ -723,6 +899,19 @@ set through the mapping argument, the default value will be used.
asList(new HashMap() {{ put("name", "New Partner"); }}) asList(new HashMap() {{ put("name", "New Partner"); }})
)); ));
.. code-tab:: go
var id int64
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "create",
[]map[string]string{
{"name": "New Partner"},
},
}, &id); err != nil {
log.Fatal(err)
}
Result: Result:
.. code-block:: json .. code-block:: json
@ -792,6 +981,31 @@ a record).
asList(asList(id)) asList(asList(id))
))); )));
.. code-tab:: go
var result bool
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "write",
[]any{
[]int64{id},
map[string]string{"name": "Newer partner"},
},
}, &result); err != nil {
log.Fatal(err)
}
// get record name after having changed it
var record []any
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "name_get",
[]any{
[]int64{id},
},
}, &record); err != nil {
log.Fatal(err)
}
Result: Result:
.. code-block:: json .. code-block:: json
@ -841,6 +1055,30 @@ Records can be deleted in bulk by providing their ids to
asList(asList(asList("id", "=", 78))) asList(asList(asList("id", "=", 78)))
))); )));
.. code-tab:: go
var result bool
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "unlink",
[]any{
[]int64{id},
},
}, &result); err != nil {
log.Fatal(err)
}
// check if the deleted record is still in the database
var record []any
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "search",
[]any{[]any{
[]any{"id", "=", id},
}},
}, &record); err != nil {
log.Fatal(err)
}
Result: Result:
.. code-block:: json .. code-block:: json
@ -953,6 +1191,34 @@ Provides information about Odoo models via its various fields.
}} }}
)); ));
.. code-tab:: go
var id int64
if err := models.Call("execute_kw", []any{
db, uid, password,
"ir.model", "create",
[]map[string]string{
{
"name": "Custom Model",
"model": "x_custom_model",
"state": "manual",
},
},
}, &id); err != nil {
log.Fatal(err)
}
recordFields := map[string]string{}
if err := models.Call("execute_kw", []any{
db, uid, password,
"x_custom_model", "fields_get",
[]any{},
map[string][]string{
"attributes": {"string", "help", "type"},
},
}, &recordFields); err != nil {
log.Fatal(err)
}
Result: Result:
.. code-block:: json .. code-block:: json
@ -1118,6 +1384,57 @@ custom fields without using Python code.
asList(asList(record_id)) asList(asList(record_id))
)); ));
.. code-tab:: go
var id int64
if err := models.Call("execute_kw", []any{
db, uid, password,
"ir.model", "create",
[]map[string]string{
{
"name": "Custom Model",
"model": "x_custom",
"state": "manual",
},
},
}, &id); err != nil {
log.Fatal(err)
}
var fieldId int64
if err := models.Call("execute_kw", []any{
db, uid, password,
"ir.model.fields", "create",
[]map[string]any{
{
"model_id": id,
"name": "x_name",
"ttype": "char",
"state": "manual",
"required": true,
},
},
}, &fieldId); err != nil {
log.Fatal(err)
}
var recordId int64
if err := models.Call("execute_kw", []any{
db, uid, password,
"x_custom", "create",
[]map[string]string{
{"x_name": "test record"},
},
}, &recordId); err != nil {
log.Fatal(err)
}
var recordFields []map[string]any
if err := models.Call("execute_kw", []any{
db, uid, password,
"x_custom", "read",
[][]int64{{recordId}},
}, recordFields); err != nil {
log.Fatal(err)
}
Result: Result:
.. code-block:: json .. code-block:: json