| Server IP : 185.208.173.17 / Your IP : 87.236.161.98 Web Server : Microsoft-IIS/10.0 System : Windows NT SRV8576125506 10.0 build 26100 (Windows Server 2016) AMD64 User : IUSR ( 0) PHP Version : 7.4.13 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : C:/Program Files/MySQL/MySQL Workbench 8.0/swb/shell/lib/mysqlsh/plugins/mrs_plugin/docs/ |
Upload File : |
<!DOCTYPE html>
<html lang="en" dir="ltr">
<!-- Copyright (c) 2022, 2026, Oracle and/or its affiliates.-->
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>MySQL REST Service - SDK Reference</title>
<link rel="shortcut icon" href="images/favicon.png" type="image/x-icon">
<link rel="stylesheet" href="style/style.css">
<!-- cSpell:ignore pagetitle -->
<title>MySQL REST Service - SDK Reference</title>
<style type="text/css">
code {
white-space: pre;
}
</style>
<script>
window.addEventListener('DOMContentLoaded', () => {
window.visibleItems = [];
window.lastVisible = null;
const observer = new IntersectionObserver((entries) => {
// Add active css class to first match
entries.forEach((entry) => {
const id = entry.target.getAttribute('id');
const querySel = document.querySelector(`nav li a[href="#` + id + `"]`);
if (querySel) {
const el = querySel.parentElement;
if (entry.isIntersecting) {
if (!window.visibleItems.includes(el)) {
if (window.visibleItems.length === 0 && window.lastVisible !== null) {
window.lastVisible.classList.remove('active');
window.lastVisible = el;
}
if (window.lastVisible === null) {
window.lastVisible = el;
}
window.visibleItems.push(el);
}
if (!el.classList.contains('active')) {
el.classList.add('active');
}
history.pushState({}, "", "#" + id);
} else {
if (window.visibleItems.includes(el)) {
if (window.visibleItems.length === 1) {
window.lastVisible = el;
} else {
el.classList.remove('active');
}
const index = window.visibleItems.indexOf(el);
if (index > -1) {
window.visibleItems.splice(index, 1);
}
if (window.lastVisible === el && window.visibleItems.length > 0) {
window.lastVisible === window.visibleItems[0];
}
}
}
}
});
}/*, { threshold: 0.1, rootMargin: '0px 0px -100% 0px', root: document.body }*/);
// Track all h that have an `id` applied
document.querySelectorAll('.content h1[id],h2[id]').forEach((section) => {
observer.observe(section);
});
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
document.querySelector(this.getAttribute('href')).scrollIntoView({
behavior: 'smooth'
});
});
});
if (typeof acquireVsCodeApi === "function") {
document.vscode = acquireVsCodeApi();
const addVsCodeDecorations = () => {
const addVsActionBtn = (e, command, caption) => {
const d = document.createElement("button");
d.innerHTML = '<i class="arrow right"></i><p>' + caption + '</p>';
d.onclick = () => {
document.vscode.postMessage({ command, path: e.innerHTML });
}
e.parentNode.insertBefore(d, e.nextSibling)
}
document.querySelectorAll("code").forEach((e) => {
if (e.innerHTML.endsWith(".sql")) {
addVsActionBtn(e, "openSqlFile", "Open in MySQL Shell");
} else if (e.innerHTML.endsWith(".mrs.json")) {
addVsActionBtn(e, "loadMrsDump", "Load MRS Dump");
} else if (e.innerHTML.startsWith("VSCodeProject:") > 0) {
e.innerHTML = e.innerHTML.slice("VSCodeProject:".length);
addVsActionBtn(e, "saveProject", "Save Project");
}
});
}
addVsCodeDecorations();
} else {
document.querySelectorAll("code").forEach((e) => {
if (e.innerHTML.startsWith("VSCodeProject:") > 0) {
e.innerHTML = e.innerHTML.slice("VSCodeProject:".length);
}
});
}
});
// Handle the message inside the webview
window.addEventListener('message', event => {
const message = event.data; // The JSON data our extension sent
switch (message.command) {
case 'goToId':
if (message.id) {
window.location = "#" + message.id;
}
break;
}
});
</script>
</head>
<body>
<div class="page">
<div class="sidebar">
<div class="bookOverview">
<h1>MySQL REST Service</h1>
<h2>
<div class="icon bookIcon"></div> <a href="index.html#document-top">Reference Manual</a>
</h2>
<h2>
<div class="icon bookIcon"></div> <a href="quickstart.html#document-top">Quickstart Guide</a>
</h2>
<h2>
<div class="icon bookIcon"></div> <a href="sql.html#document-top">SQL Reference</a>
</h2>
<h2>
<div class="icon bookIcon"></div> <a href="restApi.html#document-top">Core REST APIs</a>
</h2>
<h2>
<div class="icon bookIcon"></div> <a href="sdk.html#document-top">SDK Reference</a>
</h2>
</div>
<div class="sidebarContent">
<nav class="section-nav">
<div class="bookToc">
<br>
<h3>MySQL REST Service - SDK
Reference 2026.3.0+9.6.1</h3>
<ul>
<li><a
href="#introduction-to-the-mysql-rest-service-client-sdk"
id="toc-introduction-to-the-mysql-rest-service-client-sdk"><span
class="toc-section-number">1</span>
Introduction to the
MySQL REST Service
Client SDK</a>
<ul>
<li><a
href="#sdk-cheat-sheet"
id="toc-sdk-cheat-sheet"><span
class="toc-section-number">1.1</span>
SDK Cheat Sheet</a></li>
<li><a
href="#generation-of-sdk-files"
id="toc-generation-of-sdk-files"><span
class="toc-section-number">1.2</span>
Generation of SDK
Files</a></li>
</ul></li>
<li><a
href="#working-with-rest-services"
id="toc-working-with-rest-services"><span
class="toc-section-number">2</span>
Working with REST
Services</a>
<ul>
<li><a
href="#authentication"
id="toc-authentication"><span
class="toc-section-number">2.1</span>
Authentication</a></li>
</ul></li>
<li><a
href="#working-with-rest-views"
id="toc-working-with-rest-views"><span
class="toc-section-number">3</span>
Working with REST
Views</a>
<ul>
<li><a
href="#create-a-new-document"
id="toc-create-a-new-document"><span
class="toc-section-number">3.1</span>
Create a New
Document</a></li>
<li><a
href="#read-documents"
id="toc-read-documents"><span
class="toc-section-number">3.2</span>
Read Documents</a></li>
<li><a
href="#updating-a-document"
id="toc-updating-a-document"><span
class="toc-section-number">3.3</span>
Updating A
Document</a></li>
<li><a
href="#deleting-a-document"
id="toc-deleting-a-document"><span
class="toc-section-number">3.4</span>
Deleting A
Document</a></li>
<li><a
href="#read-your-writes-consistency"
id="toc-read-your-writes-consistency"><span
class="toc-section-number">3.5</span>
Read Your Writes
Consistency</a></li>
</ul></li>
<li><a
href="#working-with-rest-routines"
id="toc-working-with-rest-routines"><span
class="toc-section-number">4</span>
Working with REST
Routines</a>
<ul>
<li><a
href="#async-task-support"
id="toc-async-task-support"><span
class="toc-section-number">4.1</span>
Async Task
Support</a></li>
</ul></li>
<li><a
href="#typescript-client-api-reference"
id="toc-typescript-client-api-reference"><span
class="toc-section-number">5</span>
TypeScript Client API
Reference</a>
<ul>
<li><a
href="#getmetadata-ts"
id="toc-getmetadata-ts"><span
class="toc-section-number">5.1</span>
getMetadata
</a></li>
<li><a
href="#service-getauthapps-ts"
id="toc-service-getauthapps-ts"><span
class="toc-section-number">5.2</span>
Service.getAuthApps
</a></li>
<li><a
href="#service-authenticate-ts"
id="toc-service-authenticate-ts"><span
class="toc-section-number">5.3</span>
Service.authenticate
</a></li>
<li><a
href="#service-deauthenticate-ts"
id="toc-service-deauthenticate-ts"><span
class="toc-section-number">5.4</span>
Service.deauthenticate
</a></li>
<li><a
href="#view-create-ts"
id="toc-view-create-ts"><span
class="toc-section-number">5.5</span>
View.create
</a></li>
<li><a
href="#view-createmany-ts"
id="toc-view-createmany-ts"><span
class="toc-section-number">5.6</span>
View.createMany
</a></li>
<li><a
href="#view-find-ts"
id="toc-view-find-ts"><span
class="toc-section-number">5.7</span>
View.find </a></li>
<li><a
href="#view-findfirst-ts"
id="toc-view-findfirst-ts"><span
class="toc-section-number">5.8</span>
View.findFirst
</a></li>
<li><a
href="#view-findunique-ts"
id="toc-view-findunique-ts"><span
class="toc-section-number">5.9</span>
View.findUnique
</a></li>
<li><a
href="#view-finduniqueorthrow-ts"
id="toc-view-finduniqueorthrow-ts"><span
class="toc-section-number">5.10</span>
View.findUniqueOrThrow
</a></li>
<li><a
href="#view-delete-ts"
id="toc-view-delete-ts"><span
class="toc-section-number">5.11</span>
View.delete
</a></li>
<li><a
href="#view-deletemany-ts"
id="toc-view-deletemany-ts"><span
class="toc-section-number">5.12</span>
View.deleteMany
</a></li>
<li><a
href="#view-update-ts"
id="toc-view-update-ts"><span
class="toc-section-number">5.13</span>
View.update
</a></li>
<li><a
href="#view-updatemany-ts"
id="toc-view-updatemany-ts"><span
class="toc-section-number">5.14</span>
View.updateMany
</a></li>
<li><a
href="#document-update-ts"
id="toc-document-update-ts"><span
class="toc-section-number">5.15</span>
Document.update
</a></li>
<li><a
href="#document-delete-ts"
id="toc-document-delete-ts"><span
class="toc-section-number">5.16</span>
Document.delete
</a></li>
<li><a
href="#function-call-ts"
id="toc-function-call-ts"><span
class="toc-section-number">5.17</span>
Function.call
</a></li>
<li><a
href="#function-start-ts"
id="toc-function-start-ts"><span
class="toc-section-number">5.18</span>
Function.start
</a></li>
<li><a
href="#procedure-call-ts"
id="toc-procedure-call-ts"><span
class="toc-section-number">5.19</span>
Procedure.call
</a></li>
<li><a
href="#procedure-start-ts"
id="toc-procedure-start-ts"><span
class="toc-section-number">5.20</span>
Procedure.start
</a></li>
<li><a
href="#task-watch-ts"
id="toc-task-watch-ts"><span
class="toc-section-number">5.21</span>
Task.watch </a></li>
<li><a
href="#task-kill-ts"
id="toc-task-kill-ts"><span
class="toc-section-number">5.22</span>
Task.kill </a></li>
</ul></li>
<li><a
href="#python-client-api-reference"
id="toc-python-client-api-reference"><span
class="toc-section-number">6</span>
Python Client API
Reference</a>
<ul>
<li><a
href="#rest-resources"
id="toc-rest-resources"><span
class="toc-section-number">6.1</span>
REST Resources</a></li>
<li><a
href="#rest-services"
id="toc-rest-services"><span
class="toc-section-number">6.2</span>
REST Services</a></li>
<li><a
href="#rest-schemas"
id="toc-rest-schemas"><span
class="toc-section-number">6.3</span>
REST Schemas</a></li>
<li><a
href="#rest-views"
id="toc-rest-views"><span
class="toc-section-number">6.4</span>
REST Views</a></li>
<li><a
href="#rest-documents"
id="toc-rest-documents"><span
class="toc-section-number">6.5</span>
REST Documents</a></li>
<li><a
href="#rest-routines"
id="toc-rest-routines"><span
class="toc-section-number">6.6</span>
REST Routines</a></li>
<li><a
href="#async-tasks"
id="toc-async-tasks"><span
class="toc-section-number">6.7</span>
Async Tasks</a></li>
</ul></li>
<li><a
href="#checking-for-null-column-values"
id="toc-checking-for-null-column-values"><span
class="toc-section-number">7</span>
Checking for NULL Column
Values</a></li>
<li><a
href="#working-with-data-types"
id="toc-working-with-data-types"><span
class="toc-section-number">8</span>
Working with Data
Types</a>
<ul>
<li><a
href="#spatial-data-types"
id="toc-spatial-data-types"><span
class="toc-section-number">8.1</span>
Spatial Data
Types</a></li>
<li><a
href="#working-with-date-and-time-data-types"
id="toc-working-with-date-and-time-data-types"><span
class="toc-section-number">8.2</span>
Working with Date and
Time Data Types</a></li>
<li><a
href="#working-with-vector-data-types"
id="toc-working-with-vector-data-types"><span
class="toc-section-number">8.3</span>
Working with Vector Data
Types</a></li>
<li><a
href="#working-with-lossy-numbers"
id="toc-working-with-lossy-numbers"><span
class="toc-section-number">8.4</span>
Working with lossy
numbers</a></li>
</ul></li>
<li><a
href="#application-metadata"
id="toc-application-metadata"><span
class="toc-section-number">9</span>
Application Metadata</a>
<ul>
<li><a
href="#rest-services"
id="toc-rest-services"><span
class="toc-section-number">9.1</span>
REST Services</a></li>
<li><a
href="#rest-schemas"
id="toc-rest-schemas"><span
class="toc-section-number">9.2</span>
REST Schemas</a></li>
<li><a
href="#rest-objects"
id="toc-rest-objects"><span
class="toc-section-number">9.3</span>
REST Objects</a></li>
</ul></li>
</ul>
</div>
</nav>
</div>
</div>
<div class="content">
<div class="header" id="document-top">
<h1>
<div class="iconBig bookIcon"></div> MySQL REST
Service - SDK Reference
</h1>
</div>
<div class="main">
<p>This document explains how to work with the MRS
Software Development Kit and discusses the Client
API.</p>
<hr />
<p>Please also see</p>
<ul>
<li><strong><a href="index.html">MySQL REST Service -
Developer’s Guide</a></strong> - This book explains how
to install and configure the MySQL REST Service (MRS) as
well as how to access the data through REST calls.</li>
<li><strong><a href="quickstart.html">MySQL REST Service
- Quickstart Guide</a></strong> - This book provides a
hands-on approach to learning how to use the MySQL REST
service.</li>
<li><strong><a href="restApi.html">MySQL REST Service -
Core REST APIs</a></strong> - This book provides
examples of using the MySQL REST Service queries and
other operations against tables and views after you have
REST-enabled them.</li>
<li><strong><a href="sql.html">MySQL REST Service - SQL
Reference</a></strong> - This book discusses the MySQL
REST Service SQL Extension.</li>
</ul>
<hr />
<!-- Copyright (c) 2022, 2026, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2.0,
as published by the Free Software Foundation.
This program is designed to work with certain software (including
but not limited to OpenSSL) that is licensed under separate terms, as
designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have either included with
the program or referenced in the documentation.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
the GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -->
<h1 data-number="1"
id="introduction-to-the-mysql-rest-service-client-sdk"><span
class="header-section-number">1</span> Introduction to
the MySQL REST Service Client SDK</h1>
<p>The MySQL REST Service offers a Software Development
Kit (SDK) that makes it easier to write client
applications and interact with the REST service.</p>
<p>The SDK features a Client API that is specifically
generated for each REST Service. This makes it possible
to provide the best possible support for each REST
project.</p>
<p>The SDK is generated for a specific development
language. Right now, TypeScript and Python are
supported. Support for other languages is planned. Each
language-specific SDK has its own individual and
independent version number. Versioning follows the rules
specified by <a href="https://semver.org/">Semantic
Versioning 2.0.0</a>.</p>
<p>Most of the examples in this guide are written in
TypeScript. If you want more details about the SDK for a
different language, check the API reference docs.</p>
<h2 data-number="1.1" id="sdk-cheat-sheet"><span
class="header-section-number">1.1</span> SDK Cheat
Sheet</h2>
<table style="width:100%;">
<caption>SDK Cheat Sheet</caption>
<colgroup>
<col style="width: 9%" />
<col style="width: 16%" />
<col style="width: 16%" />
<col style="width: 57%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: right;">Scope</th>
<th style="text-align: left;">TypeScript</th>
<th style="text-align: left;">Python</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;">All</td>
<td style="text-align: left;"><a
href="#getmetadata-ts">getMetadata</a></td>
<td style="text-align: left;"><a
href="#get_metadata-py">get_metadata</a></td>
<td>Returns the metadata of a REST service, schema,
view, function or procedure.</td>
</tr>
<tr class="even">
<td style="text-align: right;">Service</td>
<td style="text-align: left;"><a
href="#service-getauthapps-ts">getAuthApps</a></td>
<td style="text-align: left;"><a
href="#service-get_auth_apps-py">get_auth_apps</a></td>
<td>Used to authenticate with the REST service.</td>
</tr>
<tr class="odd">
<td style="text-align: right;"></td>
<td style="text-align: left;"><a
href="#service-deauthenticate-ts">authenticate</a></td>
<td style="text-align: left;"><a
href="#service-authenticate-py">authenticate</a></td>
<td>Used to authenticate with the REST service.</td>
</tr>
<tr class="even">
<td style="text-align: right;"></td>
<td style="text-align: left;"><a
href="#service-deauthenticate-ts">deauthenticate</a></td>
<td style="text-align: left;"><a
href="#service-deauthenticate-py">deauthenticate</a></td>
<td>Used to close an authenticated session to the REST
service.</td>
</tr>
<tr class="odd">
<td style="text-align: right;">View</td>
<td style="text-align: left;"><a
href="#view-create-ts">create</a></td>
<td style="text-align: left;"><a
href="#view-create-py">create</a></td>
<td>Creates a new document on a given REST view
endpoint.</td>
</tr>
<tr class="even">
<td style="text-align: right;"></td>
<td style="text-align: left;"><a
href="#view-createmany-ts">createMany</a></td>
<td style="text-align: left;"><a
href="#view-create_many-py">create_many</a></td>
<td>Creates a list of document on a given REST view
endpoint.</td>
</tr>
<tr class="odd">
<td style="text-align: right;"></td>
<td style="text-align: left;"><a
href="#view-find-ts">find</a></td>
<td style="text-align: left;"><a
href="#view-find-py">find</a></td>
<td>Reads the first page of documents of a search
request and returns an iterator.</td>
</tr>
<tr class="even">
<td style="text-align: right;"></td>
<td style="text-align: left;"><a
href="#view-findfirst-ts">findFirst</a></td>
<td style="text-align: left;"><a
href="#view-find_first-py">find_first</a></td>
<td>Reads the first matching document of a search
request.</td>
</tr>
<tr class="odd">
<td style="text-align: right;"></td>
<td style="text-align: left;"><a
href="#view-findfirst-ts">findFirstOrThrow</a></td>
<td style="text-align: left;"><a
href="#view-find_first-py">find_first</a></td>
<td>Reads the first matching document of a search
request and throws an error if not found.</td>
</tr>
<tr class="even">
<td style="text-align: right;"></td>
<td style="text-align: left;"><a
href="#view-findunique-ts">findUnique</a></td>
<td style="text-align: left;"><a
href="#view-find_first-py">find_unique</a></td>
<td>Reads the first matching document of a primary key
lookup.</td>
</tr>
<tr class="odd">
<td style="text-align: right;"></td>
<td style="text-align: left;"><a
href="#view-finduniqueorthrow-ts">findUniqueOrThrow</a></td>
<td style="text-align: left;"><a
href="#view-find_unique_or_throw-py">find_unique_or_throw</a></td>
<td>Reads the first matching document of a primary key
lookup and throws if not found.</td>
</tr>
<tr class="even">
<td style="text-align: right;"></td>
<td style="text-align: left;"><a
href="#view-delete-ts">delete</a></td>
<td style="text-align: left;"><a
href="#view-delete-py">delete</a></td>
<td>Deletes a given document from a REST view
endpoint.</td>
</tr>
<tr class="odd">
<td style="text-align: right;"></td>
<td style="text-align: left;"><a
href="#view-deletemany-ts">deleteMany</a></td>
<td style="text-align: left;"><a
href="#view-delete_many-py">delete_many</a></td>
<td>Deletes several documents from a REST view
endpoint.</td>
</tr>
<tr class="even">
<td style="text-align: right;"></td>
<td style="text-align: left;"><a
href="#view-update-ts">update</a></td>
<td style="text-align: left;"><a
href="#view-update-py">update</a></td>
<td>Updates a given document on a REST view
endpoint.</td>
</tr>
<tr class="odd">
<td style="text-align: right;"></td>
<td style="text-align: left;"><a
href="#view-updatemany-ts">updateMany</a></td>
<td style="text-align: left;"><a
href="#view-update_many-py">update_many</a></td>
<td>Updates several documents on a REST view
endpoint.</td>
</tr>
<tr class="even">
<td style="text-align: right;">Document</td>
<td style="text-align: left;"><a
href="#document-update-ts">update</a></td>
<td style="text-align: left;"><a
href="#document-update-py">update</a></td>
<td>Updates a REST document that was fetched
before.</td>
</tr>
<tr class="odd">
<td style="text-align: right;"></td>
<td style="text-align: left;"><a
href="#document-delete-ts">delete</a></td>
<td style="text-align: left;"><a
href="#document-delete-py">delete</a></td>
<td>Deletes a REST document that was fetched
before.</td>
</tr>
<tr class="even">
<td style="text-align: right;">Function</td>
<td style="text-align: left;"><a
href="#function-call-ts">call</a></td>
<td style="text-align: left;"><a
href="#function-call-py">call</a></td>
<td>Calls a REST function.</td>
</tr>
<tr class="odd">
<td style="text-align: right;"></td>
<td style="text-align: left;"><a
href="#function-start-ts">start</a></td>
<td style="text-align: left;"><a
href="#function-start-py">start</a></td>
<td>Calls an async REST function and returns a
task.</td>
</tr>
<tr class="even">
<td style="text-align: right;">Procedure</td>
<td style="text-align: left;"><a
href="#procedure-call-ts">call</a></td>
<td style="text-align: left;"><a
href="#procedure-call-py">call</a></td>
<td>Calls a REST procedure.</td>
</tr>
<tr class="odd">
<td style="text-align: right;"></td>
<td style="text-align: left;"><a
href="#procedure-start-ts">start</a></td>
<td style="text-align: left;"><a
href="#procedure-start-py">start</a></td>
<td>Calls an async REST procedure and returns a
task.</td>
</tr>
<tr class="even">
<td style="text-align: right;">Task</td>
<td style="text-align: left;"><a
href="#task-watch-ts">watch</a></td>
<td style="text-align: left;"><a
href="#task-watch-py">watch</a></td>
<td>Watches a Task for progress and result.</td>
</tr>
<tr class="odd">
<td style="text-align: right;"></td>
<td style="text-align: left;"><a
href="#task-kill-ts">kill</a></td>
<td style="text-align: left;"><a
href="#task-kill-py">kill</a></td>
<td>Terminates an async REST function or REST procedure
call.</td>
</tr>
</tbody>
</table>
<h2 data-number="1.2" id="generation-of-sdk-files"><span
class="header-section-number">1.2</span> Generation of
SDK Files</h2>
<p>Once a REST service has been defined, the
corresponding SDK can be generated in the required
development language.</p>
<p>Several different methods can be used to perform the
actual generation process.</p>
<ul>
<li>Generating the SDK files from MySQL Shell for VS
Code
<ul>
<li>When using <a
href="https://code.visualstudio.com/">VS Code</a> or <a
href="https://vscodium.com/">VSCodium</a> and the <a
href="https://marketplace.visualstudio.com/items?itemName=Oracle.mysql-shell-for-vs-code">MySQL
Shell for VS Code extension</a>, the SDK for a given
REST service can be generated directly from the UI.</li>
<li>While using the MySQL Shell for VS Code extension,
the SDK will be generated on the fly when using a DB
Notebook to enabled instant prototyping of the SDK API
calls.</li>
</ul></li>
<li>Generating the SDK Files from the Command Line
<ul>
<li>To integrate the SDK generation into an existing
development process, it is possible to use the MySQL
Shell on the command line to generate the SDK
files.</li>
</ul></li>
</ul>
<p>An constructor/initializer for the client-side REST
service instance is generated based on the conventions
established for the selected programming language. It
allows to optionally specify the base URL of that REST
service, has deployed in the MySQL Router instance used
by the MRS installation. This would override the base
URL specified when the SDK is generated in the first
place, using the MySQL Shell.</p>
<h3 data-number="1.2.1"
id="generating-the-sdk-files-from-mysql-shell-for-vs-code"><span
class="header-section-number">1.2.1</span> Generating
the SDK Files from MySQL Shell for VS Code</h3>
<p>To generate the SDK files for a development project,
right click on the MRS Service and select
<code>Dump to Disk > Dump REST Client SDK Files ...</code>.
This will allow you to select a destination folder
inside your development project the files will be placed
in.</p>
<p>The following files will be placed in the selected
folder.</p>
<h3 data-number="1.2.2"
id="on-the-fly-generation-of-typescript-sdk-in-vs-code"><span
class="header-section-number">1.2.2</span> On the Fly
Generation of TypeScript SDK in VS Code</h3>
<p>The MySQL Shell for VS Code extension allows
interactive execution of TypeScript code inside a DB
Notebook. To make working with the MySQL REST Service
easier, the TypeScript SDK for the current REST Service
is made available directly within the DB Notebooks.</p>
<p>Whenever a REST DB Object has being edited, the
TypeScript SDK is updated to allow instant prototyping
of REST queries using the Client API.</p>
<p>This allows for adjusting and fine tuning the REST
views and routines till they exactly meet the
developer’s requirements and to prototype Client API
calls for a development project.</p>
<h3 data-number="1.2.3"
id="generating-the-sdk-files-from-the-command-line"><span
class="header-section-number">1.2.3</span> Generating
the SDK Files from the Command Line</h3>
<p>To generate the SDK files on the command line, the
MySQL Shell needs to be <a
href="https://dev.mysql.com/downloads/shell/">downloaded</a>
and installed.</p>
<blockquote>
<p>When using the MySQL Shell for VS Code extension, the
MySQL Shell executable is made available at
<code>~/.mysqlsh-gui/mysqlsh</code> and a dedicated
installation of the MySQL Shell is not required.</p>
</blockquote>
<p>The following template shows how to call the
<code>mrs.dump.sdk_service_files</code> plugin function
to perform the SDK generation.</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">mysqlsh</span> dba@localhost <span class="at">--py</span> <span class="at">-e</span> <span class="st">'mrs.dump.sdk_service_files(directory="/path/to/project/sdk", options={"sdk_language": "TypeScript", "service_url":"https://example.com/myService"})'</span></span></code></pre></div>
<p>The full list of parameters include the
following.</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode txt"><code class="sourceCode default"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>\? mrs.dump.sdk_service_files</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>NAME</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a> sdk_service_files - Dumps the SDK service files for a REST Service</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>SYNTAX</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a> mrs.dump.sdk_service_files([kwargs])</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>WHERE</span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a> kwargs: Dictionary - Options to determine what should be generated.</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>DESCRIPTION</span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a> Returns:</span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a> True on success</span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a> The kwargs parameter accepts the following options:</span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true" tabindex="-1"></a> - directory: String - The directory to store the .mrs.sdk folder with the</span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true" tabindex="-1"></a> files.</span>
<span id="cb2-20"><a href="#cb2-20" aria-hidden="true" tabindex="-1"></a> - options: Dictionary - Several options how the SDK should be created.</span>
<span id="cb2-21"><a href="#cb2-21" aria-hidden="true" tabindex="-1"></a> - session: Object - The database session to use.</span>
<span id="cb2-22"><a href="#cb2-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-23"><a href="#cb2-23" aria-hidden="true" tabindex="-1"></a> The options option accepts the following options:</span>
<span id="cb2-24"><a href="#cb2-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-25"><a href="#cb2-25" aria-hidden="true" tabindex="-1"></a> - service_id: String - The ID of the service the SDK should be generated</span>
<span id="cb2-26"><a href="#cb2-26" aria-hidden="true" tabindex="-1"></a> for. If not specified, the default service is used.</span>
<span id="cb2-27"><a href="#cb2-27" aria-hidden="true" tabindex="-1"></a> - db_connection_uri: String - The dbConnectionUri that was used to export</span>
<span id="cb2-28"><a href="#cb2-28" aria-hidden="true" tabindex="-1"></a> the SDK files.</span>
<span id="cb2-29"><a href="#cb2-29" aria-hidden="true" tabindex="-1"></a> - sdk_language: String - The SDK language to generate.</span>
<span id="cb2-30"><a href="#cb2-30" aria-hidden="true" tabindex="-1"></a> - add_app_base_class: String - The additional AppBaseClass file name.</span>
<span id="cb2-31"><a href="#cb2-31" aria-hidden="true" tabindex="-1"></a> - service_url: String - The url of the service.</span>
<span id="cb2-32"><a href="#cb2-32" aria-hidden="true" tabindex="-1"></a> - version: Integer - The version of the generated files.</span>
<span id="cb2-33"><a href="#cb2-33" aria-hidden="true" tabindex="-1"></a> - generationDate: String - The generation date of the SDK files.</span>
<span id="cb2-34"><a href="#cb2-34" aria-hidden="true" tabindex="-1"></a> - header: String - The header to use for the SDK files.</span></code></pre></div>
<h3 data-number="1.2.4" id="important-notes"><span
class="header-section-number">1.2.4</span> Important
Notes</h3>
<p>The identifiers used to name each corresponding REST
resource (services, schemas and/or objects) in the SDK
are based on their corresponding request path
segment.</p>
<p>These are generated using the most common convention
for each language - TypeScript and Python - which means
that the identifier generated for a request path such as
<code>/myRequestPath</code> would be equivalent to the
one generated for <code>/my_request_path</code>. To
avoid a naming conflict in this case, the code generator
keeps track of potential conflicts and appends a suffix
to duplicate identifiers which corresponds to an
increasing number based on the current total of
duplicates. Following the sorting rules by omission in
MySQL, under these circumstances, the snake_case version
takes precedence over the camelCase version.</p>
<table>
<colgroup>
<col style="width: 20%" />
<col style="width: 18%" />
<col style="width: 18%" />
<col style="width: 20%" />
<col style="width: 20%" />
</colgroup>
<thead>
<tr class="header">
<th>Request Path</th>
<th>TypeScript Class</th>
<th>Python Class</th>
<th>TypeScript Property</th>
<th>Python Property</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>/my_request_path</code></td>
<td><code>MyRequestPath</code></td>
<td><code>MyRequestPath</code></td>
<td><code>myRequestPath</code></td>
<td><code>my_request_path</code></td>
</tr>
<tr class="even">
<td><code>/myRequestPath</code></td>
<td><code>MyRequestPath1</code></td>
<td><code>MyRequestPath1</code></td>
<td><code>myRequestPath1</code></td>
<td><code>my_request_path1</code></td>
</tr>
</tbody>
</table>
<p>Naming conflicts can also happen with the static
identifiers used the native SDK functions available at
each REST resource level (service, schema and/or
object), examples can be as follows (depending on the
level):</p>
<ul>
<li><code>authenticate</code></li>
<li><code>deauthenticate</code></li>
<li><code>getMetadata</code>/<code>get_metadata</code></li>
<li><code>getAuthApps</code>/<code>get_auth_apps</code></li>
</ul>
<p>In this case, the non static identifiers used for
schema or object names will contain the corresponding
suffix.</p>
<p>Additionally, request paths with a leading numeric
character are also perfectly valid, but without special
handling, the resulting identifiers would lead to syntax
errors in both languages. In this case, following the
common convention, the generated identifier contains an
extra leading <code>_</code>.</p>
<!-- Copyright (c) 2022, 2026, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2.0,
as published by the Free Software Foundation.
This program is designed to work with certain software (including
but not limited to OpenSSL) that is licensed under separate terms, as
designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have either included with
the program or referenced in the documentation.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
the GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -->
<h1 data-number="2"
id="working-with-rest-services"><span
class="header-section-number">2</span> Working with REST
Services</h1>
<p>The initializer returns an objects that implements
the interface described in the <a
href="#client-api-reference">API reference docs</a>.</p>
<p>For a REST service available under the root path
<code>/myService</code>, the corresponding client-side
object can be created, on TypeScript, as follows:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">'./myService.mrs.sdk/myService'</span><span class="op">;</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()<span class="op">;</span></span></code></pre></div>
<p>or, using a custom base URL:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">'./myService.mrs.sdk/myService'</span><span class="op">;</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>(<span class="st">"https://localhost:8443/myService"</span>)<span class="op">;</span></span></code></pre></div>
<p>Similarly, on Python, the client-side object can be
created as follows:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.my_service <span class="im">import</span> <span class="op">*</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span></code></pre></div>
<p>or, using a custom base URL:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.my_service <span class="im">import</span> <span class="op">*</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService(base_url<span class="op">=</span><span class="st">"https://localhost:8443/myService"</span>)</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="co"># or just</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService(<span class="st">"https://localhost:8443/myService"</span>)</span></code></pre></div>
<h2 data-number="2.1" id="authentication"><span
class="header-section-number">2.1</span>
Authentication</h2>
<p>When a REST object requires authentication,
applications using the SDK should authenticate in the
scope of the corresponding REST service beforehand. A
client can be authenticated using an existing
authentication app, providing a valid username and
password (and optionally, a vendor id).</p>
<p>If a vendor id is not specified, the SDK
automatically looks up the appropriate vendor id for the
corresponding authentication app (which results in an
extra round-trip to the MRS backend).</p>
<p>Currently, the MRS SDK (both for TypeScript and
Python) only supports MRS Native and MySQL Internal
Authentication apps (more details <a
href="../devGuide/Auth.md">here</a>).</p>
<h3 data-number="2.1.1"
id="mrs-native-authentication"><span
class="header-section-number">2.1.1</span> MRS Native
Authentication</h3>
<p>With an authentication app created as follows:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> REST AUTH APP baz <span class="kw">ON</span> SERVICE <span class="op">/</span>myService VENDOR MRS;</span></code></pre></div>
<p>and a REST user created as follows:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> REST <span class="fu">USER</span> <span class="ot">"foo"</span>@<span class="ot">"baz"</span> <span class="kw">IDENTIFIED</span> <span class="kw">BY</span> <span class="ot">"bar"</span>;</span></code></pre></div>
<p><strong><em>TypeScript</em></strong></p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="fu">authenticate</span>({ username<span class="op">:</span> <span class="st">"foo"</span><span class="op">,</span> password<span class="op">:</span> <span class="st">"bar"</span><span class="op">,</span> app<span class="op">:</span> <span class="st">"baz"</span> })</span></code></pre></div>
<p><strong><em>Python</em></strong></p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>my_service.authenticate(username<span class="op">=</span><span class="st">"foo"</span>, password<span class="op">=</span><span class="st">"bar"</span>, app<span class="op">=</span><span class="st">"baz"</span>)</span></code></pre></div>
<h3 data-number="2.1.2"
id="mysql-internal-authentication"><span
class="header-section-number">2.1.2</span> MySQL
Internal Authentication</h3>
<p>In the same way, with an authentication app created
as follows:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> REST AUTH APP qux <span class="kw">ON</span> SERVICE <span class="op">/</span>myService VENDOR MYSQL;</span></code></pre></div>
<p>and, this time, an actual MySQL server account
created as follows:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> <span class="fu">USER</span> foo <span class="kw">IDENTIFIED</span> <span class="kw">BY</span> <span class="ot">"bar"</span>;</span></code></pre></div>
<p>the API is used in the exact same way.</p>
<p><strong><em>TypeScript</em></strong></p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="fu">authenticate</span>({ username<span class="op">:</span> <span class="st">"foo"</span><span class="op">,</span> password<span class="op">:</span> <span class="st">"bar"</span><span class="op">,</span> app<span class="op">:</span> <span class="st">"qux"</span> })</span></code></pre></div>
<p><strong><em>Python</em></strong></p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>my_service.authenticate(username<span class="op">=</span><span class="st">"foo"</span>, password<span class="op">=</span><span class="st">"bar"</span>, app<span class="op">=</span><span class="st">"baz"</span>)</span></code></pre></div>
<p>After the authentication succeeds, every valid SDK
command that executes on top of a REST object that
requires authentication, should also succeed.</p>
<h3 data-number="2.1.3" id="authentication-errors"><span
class="header-section-number">2.1.3</span>
Authentication Errors</h3>
<p>In the case where a vendor id is not specified when
calling the command, the client performs a vendor lookup
in the backend using the name of the authentication app.
If the authentication app does not exist, the command
yields an error.</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="cf">try</span> {</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a> <span class="cf">await</span> myService<span class="op">.</span><span class="fu">authenticate</span>({ username<span class="op">:</span> <span class="st">"foo"</span><span class="op">,</span> password<span class="op">:</span> <span class="st">"bar"</span><span class="op">,</span> app<span class="op">:</span> <span class="st">"<non_existing>"</span> })</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>} <span class="cf">catch</span> (err) {</span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(err<span class="op">.</span><span class="at">message</span>) <span class="co">// "Authentication failed. The authentication app does not exist."</span></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>In the case where a vendor id is specified when
calling the command, the client does not perform any
additional vendor lookup, which means that it assumes
the command was provided with the name of an
authentication app of that same vendor and simplify
attempts to authenticate using the appropriate
authentication mechanism. Ultimately the authentication
will fail and the command will return an error.</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> result <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="fu">authenticate</span>({</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a> username<span class="op">:</span> <span class="st">"foo"</span><span class="op">,</span></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a> password<span class="op">:</span> <span class="st">"bar"</span><span class="op">,</span></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a> app<span class="op">:</span> <span class="st">"<app_from_different_vendor>"</span><span class="op">,</span></span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a> vendor<span class="op">:</span> <span class="st">"<vendor_id>"</span></span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a>})</span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(result<span class="op">.</span><span class="at">errorMessage</span>) <span class="co">// Authentication failed. The authentication app is of a different vendor.</span></span></code></pre></div>
<p>Additionally, the command will, as expected, also
yield an error when the password does not match the
given username.</p>
<h3 data-number="2.1.4" id="deauthentication"><span
class="header-section-number">2.1.4</span>
Deauthentication</h3>
<p>Once a user is authenticated, it can logout from a
given service, by calling the
<code>deauthenticate</code> command as follows:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="fu">deauthenticate</span>()</span></code></pre></div>
<p>If no user is authenticated, calling the command
yields an error as follows:</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="cf">try</span> {</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a> <span class="cf">await</span> myService<span class="op">.</span><span class="fu">deauthenticate</span>()</span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>} <span class="cf">catch</span> (err) {</span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(err<span class="op">.</span><span class="at">message</span>) <span class="co">// No user is currently authenticated.</span></span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<!-- Copyright (c) 2023, 2026, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2.0,
as published by the Free Software Foundation.
This program is designed to work with certain software (including
but not limited to OpenSSL) that is licensed under separate terms, as
designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have either included with
the program or referenced in the documentation.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
the GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -->
<h1 data-number="3" id="working-with-rest-views"><span
class="header-section-number">3</span> Working with REST
Views</h1>
<h2 data-number="3.1" id="create-a-new-document"><span
class="header-section-number">3.1</span> Create a New
Document</h2>
<p>To insert a new document on a REST view, the
<code>create</code> API method is used.</p>
<h3 data-number="3.1.1"
id="example-of-inserting-a-new-document"><span
class="header-section-number">3.1.1</span> Example of
Inserting a New Document</h3>
<p>Given the REST view <code>/actor</code> defined as
follows, this example shows how to insert a new
document.</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> REST SERVICE <span class="cf">IF</span> <span class="kw">NOT</span> <span class="kw">EXISTS</span> <span class="op">/</span>myService;</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> REST <span class="kw">SCHEMA</span> <span class="cf">IF</span> <span class="kw">NOT</span> <span class="kw">EXISTS</span> <span class="op">/</span>sakila <span class="kw">ON</span> SERVICE <span class="op">/</span>myService <span class="kw">FROM</span> sakila;</span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> <span class="kw">OR</span> <span class="kw">REPLACE</span> REST <span class="kw">VIEW</span> <span class="op">/</span>actor</span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a> <span class="kw">ON</span> SERVICE <span class="op">/</span>myService <span class="kw">SCHEMA</span> <span class="op">/</span>sakila</span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a> <span class="kw">AS</span> sakila.actor <span class="kw">CLASS</span> MyServiceSakilaActor @INSERT @UPDATE @DELETE {</span>
<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a> actorId: actor_id @SORTABLE @KEY,</span>
<span id="cb19-9"><a href="#cb19-9" aria-hidden="true" tabindex="-1"></a> firstName: first_name,</span>
<span id="cb19-10"><a href="#cb19-10" aria-hidden="true" tabindex="-1"></a> lastName: last_name,</span>
<span id="cb19-11"><a href="#cb19-11" aria-hidden="true" tabindex="-1"></a> lastUpdate: last_update</span>
<span id="cb19-12"><a href="#cb19-12" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb19-13"><a href="#cb19-13" aria-hidden="true" tabindex="-1"></a> AUTHENTICATION REQUIRED;</span></code></pre></div>
<blockquote>
<p>Inserting a new document in the <code>actor</code>
table does not require either the <code>actorId</code>
field or the <code>lastUpdate</code> field because the
former is an auto-generated primary key
(<code>AUTO_INCREMENT</code>) whereas the latter maps to
a column with a default value
<code>CURRENT_TIMESTAMP()</code>.</p>
</blockquote>
<p><strong><em>TypeScript</em></strong></p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">actor</span><span class="op">.</span><span class="fu">create</span>({ data<span class="op">:</span> { firstName<span class="op">:</span> <span class="st">"FOO"</span><span class="op">,</span> lastName<span class="op">:</span> <span class="st">"BAR"</span> } })</span></code></pre></div>
<p><strong><em>Python</em></strong></p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a>my_service.sakila.actor.create(data<span class="op">=</span>{<span class="st">"first_name"</span>: <span class="st">"FOO"</span>, <span class="st">"last_name"</span>: <span class="st">"BAR"</span>})</span></code></pre></div>
<h2 data-number="3.2" id="read-documents"><span
class="header-section-number">3.2</span> Read
Documents</h2>
<p>To fetch documents from a REST view the family of
<code>find</code> API commands is used. Each of these
commands covers a specific use case when looking for
documents.</p>
<table>
<caption>Family of <code>find</code> API
Commands</caption>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<thead>
<tr class="header">
<th>API Command</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>find()</td>
<td>Fetches a page of the list of documents that were
found.</td>
</tr>
<tr class="even">
<td>findFirst()</td>
<td>Fetches the first document that was found.</td>
</tr>
<tr class="odd">
<td>findFirstOrThrow()</td>
<td>Same as findFirst() but throws when there was no
document found.</td>
</tr>
<tr class="even">
<td>findUnique()</td>
<td>Fetches the first document that matches a unique key
lookup.</td>
</tr>
<tr class="odd">
<td>findUniqueOrThrow()</td>
<td>Same as findUnique() but throws when there was no
document found.</td>
</tr>
</tbody>
</table>
<blockquote>
<p>Please not that exact spelling of the API commands
depends on the actual SDK language used, as its specific
naming conventions (e.g. snake_case for Python) are
honored.</p>
</blockquote>
<h3 data-number="3.2.1"
id="querying-data-in-multiple-pages"><span
class="header-section-number">3.2.1</span> Querying Data
in Multiple Pages</h3>
<p>When a query for a REST View produces multiple
documents, those are sent to the client organized in a
set of pages that can be requested on demand. Each page
contains, by default, 25 documents at most. The page
size can be customized at the REST object level or by
using the <code>take</code> option in the
<code>find()</code> command. The command works by
fetching the first page of documents, and provides
additional infrastructure to keep consuming more
matching documents whilst they exist.</p>
<p>For example, retrieving the first 50 documents with
the default page size can be done as follows:</p>
<div class="sourceCode" id="cb22"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> countries <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">country</span><span class="op">.</span><span class="fu">find</span>()<span class="op">;</span></span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a><span class="fu">print</span>(countries)</span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> (countries<span class="op">.</span><span class="at">hasMore</span>) {</span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a> countries <span class="op">=</span> <span class="cf">await</span> countries<span class="op">.</span><span class="fu">next</span>()<span class="op">;</span></span>
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a> <span class="fu">print</span>(countries)</span>
<span id="cb22-6"><a href="#cb22-6" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb22-7"><a href="#cb22-7" aria-hidden="true" tabindex="-1"></a>[</span>
<span id="cb22-8"><a href="#cb22-8" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb22-9"><a href="#cb22-9" aria-hidden="true" tabindex="-1"></a> <span class="st">"country"</span><span class="op">:</span> <span class="st">"Afghanistan"</span><span class="op">,</span></span>
<span id="cb22-10"><a href="#cb22-10" aria-hidden="true" tabindex="-1"></a> <span class="st">"countryId"</span><span class="op">:</span> <span class="dv">1</span><span class="op">,</span></span>
<span id="cb22-11"><a href="#cb22-11" aria-hidden="true" tabindex="-1"></a> <span class="st">"lastUpdate"</span><span class="op">:</span> <span class="st">"2006-02-15 04:44:00.000000"</span><span class="op">,</span></span>
<span id="cb22-12"><a href="#cb22-12" aria-hidden="true" tabindex="-1"></a> }<span class="op">,</span></span>
<span id="cb22-13"><a href="#cb22-13" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb22-14"><a href="#cb22-14" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb22-15"><a href="#cb22-15" aria-hidden="true" tabindex="-1"></a> <span class="st">"country"</span><span class="op">:</span> <span class="st">"Congo, The Democratic Republic of the"</span><span class="op">,</span></span>
<span id="cb22-16"><a href="#cb22-16" aria-hidden="true" tabindex="-1"></a> <span class="st">"countryId"</span><span class="op">:</span> <span class="dv">25</span><span class="op">,</span></span>
<span id="cb22-17"><a href="#cb22-17" aria-hidden="true" tabindex="-1"></a> <span class="st">"lastUpdate"</span><span class="op">:</span> <span class="st">"2006-02-15 04:44:00.000000"</span><span class="op">,</span></span>
<span id="cb22-18"><a href="#cb22-18" aria-hidden="true" tabindex="-1"></a> }<span class="op">,</span></span>
<span id="cb22-19"><a href="#cb22-19" aria-hidden="true" tabindex="-1"></a>]</span>
<span id="cb22-20"><a href="#cb22-20" aria-hidden="true" tabindex="-1"></a>[</span>
<span id="cb22-21"><a href="#cb22-21" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb22-22"><a href="#cb22-22" aria-hidden="true" tabindex="-1"></a> <span class="st">"country"</span><span class="op">:</span> <span class="st">"Czech Republic"</span><span class="op">,</span></span>
<span id="cb22-23"><a href="#cb22-23" aria-hidden="true" tabindex="-1"></a> <span class="st">"countryId"</span><span class="op">:</span> <span class="dv">26</span><span class="op">,</span></span>
<span id="cb22-24"><a href="#cb22-24" aria-hidden="true" tabindex="-1"></a> <span class="st">"lastUpdate"</span><span class="op">:</span> <span class="st">"2006-02-15 04:44:00.000000"</span><span class="op">,</span></span>
<span id="cb22-25"><a href="#cb22-25" aria-hidden="true" tabindex="-1"></a> }<span class="op">,</span></span>
<span id="cb22-26"><a href="#cb22-26" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb22-27"><a href="#cb22-27" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb22-28"><a href="#cb22-28" aria-hidden="true" tabindex="-1"></a> <span class="st">"country"</span><span class="op">:</span> <span class="st">"Japan"</span><span class="op">,</span></span>
<span id="cb22-29"><a href="#cb22-29" aria-hidden="true" tabindex="-1"></a> <span class="st">"countryId"</span><span class="op">:</span> <span class="dv">50</span><span class="op">,</span></span>
<span id="cb22-30"><a href="#cb22-30" aria-hidden="true" tabindex="-1"></a> <span class="st">"lastUpdate"</span><span class="op">:</span> <span class="st">"2006-02-15 04:44:00.000000"</span><span class="op">,</span></span>
<span id="cb22-31"><a href="#cb22-31" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb22-32"><a href="#cb22-32" aria-hidden="true" tabindex="-1"></a>]</span></code></pre></div>
<p>Retrieving all documents under a given filter, whilst
skipping an initial number of them and lowering the page
size can be done as follows:</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> countries <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">country</span><span class="op">.</span><span class="fu">find</span>({ where<span class="op">:</span> { country<span class="op">:</span> { $like<span class="op">:</span> <span class="st">"C%"</span> } }<span class="op">,</span> take<span class="op">:</span> <span class="dv">3</span><span class="op">,</span> skip<span class="op">:</span> <span class="dv">2</span> })<span class="op">;</span></span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a><span class="fu">print</span>(countries)</span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a><span class="cf">while</span> (countries<span class="op">.</span><span class="at">hasMore</span>) {</span>
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a> countries <span class="op">=</span> <span class="cf">await</span> countries<span class="op">.</span><span class="fu">next</span>()<span class="op">;</span></span>
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a> <span class="fu">print</span>(countries)</span>
<span id="cb23-6"><a href="#cb23-6" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb23-7"><a href="#cb23-7" aria-hidden="true" tabindex="-1"></a>[</span>
<span id="cb23-8"><a href="#cb23-8" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb23-9"><a href="#cb23-9" aria-hidden="true" tabindex="-1"></a> <span class="st">"country"</span><span class="op">:</span> <span class="st">"Canada"</span><span class="op">,</span></span>
<span id="cb23-10"><a href="#cb23-10" aria-hidden="true" tabindex="-1"></a> <span class="st">"countryId"</span><span class="op">:</span> <span class="dv">20</span><span class="op">,</span></span>
<span id="cb23-11"><a href="#cb23-11" aria-hidden="true" tabindex="-1"></a> <span class="st">"lastUpdate"</span><span class="op">:</span> <span class="st">"2006-02-15 04:44:00.000000"</span><span class="op">,</span></span>
<span id="cb23-12"><a href="#cb23-12" aria-hidden="true" tabindex="-1"></a> }<span class="op">,</span></span>
<span id="cb23-13"><a href="#cb23-13" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb23-14"><a href="#cb23-14" aria-hidden="true" tabindex="-1"></a> <span class="st">"country"</span><span class="op">:</span> <span class="st">"Chad"</span><span class="op">,</span></span>
<span id="cb23-15"><a href="#cb23-15" aria-hidden="true" tabindex="-1"></a> <span class="st">"countryId"</span><span class="op">:</span> <span class="dv">21</span><span class="op">,</span></span>
<span id="cb23-16"><a href="#cb23-16" aria-hidden="true" tabindex="-1"></a> <span class="st">"lastUpdate"</span><span class="op">:</span> <span class="st">"2006-02-15 04:44:00.000000"</span><span class="op">,</span></span>
<span id="cb23-17"><a href="#cb23-17" aria-hidden="true" tabindex="-1"></a> }<span class="op">,</span></span>
<span id="cb23-18"><a href="#cb23-18" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb23-19"><a href="#cb23-19" aria-hidden="true" tabindex="-1"></a> <span class="st">"country"</span><span class="op">:</span> <span class="st">"Chile"</span><span class="op">,</span></span>
<span id="cb23-20"><a href="#cb23-20" aria-hidden="true" tabindex="-1"></a> <span class="st">"countryId"</span><span class="op">:</span> <span class="dv">22</span><span class="op">,</span></span>
<span id="cb23-21"><a href="#cb23-21" aria-hidden="true" tabindex="-1"></a> <span class="st">"lastUpdate"</span><span class="op">:</span> <span class="st">"2006-02-15 04:44:00.000000"</span><span class="op">,</span></span>
<span id="cb23-22"><a href="#cb23-22" aria-hidden="true" tabindex="-1"></a> }<span class="op">,</span></span>
<span id="cb23-23"><a href="#cb23-23" aria-hidden="true" tabindex="-1"></a>]</span>
<span id="cb23-24"><a href="#cb23-24" aria-hidden="true" tabindex="-1"></a><span class="co">// ...</span></span>
<span id="cb23-25"><a href="#cb23-25" aria-hidden="true" tabindex="-1"></a>[</span>
<span id="cb23-26"><a href="#cb23-26" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb23-27"><a href="#cb23-27" aria-hidden="true" tabindex="-1"></a> <span class="st">"country"</span><span class="op">:</span> <span class="st">"Czech Republic"</span><span class="op">,</span></span>
<span id="cb23-28"><a href="#cb23-28" aria-hidden="true" tabindex="-1"></a> <span class="st">"countryId"</span><span class="op">:</span> <span class="dv">26</span><span class="op">,</span></span>
<span id="cb23-29"><a href="#cb23-29" aria-hidden="true" tabindex="-1"></a> <span class="st">"lastUpdate"</span><span class="op">:</span> <span class="st">"2006-02-15 04:44:00.000000"</span><span class="op">,</span></span>
<span id="cb23-30"><a href="#cb23-30" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb23-31"><a href="#cb23-31" aria-hidden="true" tabindex="-1"></a>]</span></code></pre></div>
<h3 data-number="3.2.2"
id="querying-data-across-relational-tables"><span
class="header-section-number">3.2.2</span> Querying Data
Across Relational Tables</h3>
<p>MySQL supports foreign keys, which permit
cross-referencing related data across tables, and
foreign key constraints to help keep the related data
consistent.</p>
<p>A foreign key relationship involves a parent table
that holds the initial column values, and a child table
with column values that reference the parent column
values. A foreign key constraint is defined on the child
table. Foreign keys enable establishing one-to-one,
one-to-many or many-to-many relationships between rows
in those tables.</p>
<p>With the MySQL REST Service, these relationships can
be expanded to include related data from different
tables embedded in the same result set with the REST
data mapping view feature available for each MRS
database object. The client can then select which
columns should be expanded using a specific HTTP query
syntax to specify and navigate along the nesting path of
columns on other tables that are referenced by a root
column in the main (or parent) table.</p>
<p>A key feature of the MRS SDK is the ability to query
these relations between two database objects and include
or exclude specific columns from the query response.</p>
<p>This feature is available using the
<code>select</code> option in the following API
commands:</p>
<ul>
<li><code>findFirst()</code></li>
<li><code>find()</code></li>
<li><code>findUnique()</code></li>
</ul>
<p>By default, all the object fields (expanded or not)
and their values are returned in the query response.
Specific fields can be excluded from the query response
using a plain object format in which the properties are
the names of the fields to exclude and each value is
<code>false</code>.</p>
<p>With a setup using the <a
href="https://dev.mysql.com/doc/sakila/en/">Sakila
Sample Database</a> where the schema is available under
a REST service called <code>myService</code> and the
relationship between the city and country tables
(one-to-one) is expanded via the REST data mapping view
feature, the <code>lastUpdate</code> and
<code>country.lastUpdate</code> fields can be excluded
as follows:</p>
<div class="sourceCode" id="cb24"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">city</span><span class="op">.</span><span class="fu">findFirst</span>({ select<span class="op">:</span> { lastUpdate<span class="op">:</span> <span class="kw">false</span><span class="op">,</span> country<span class="op">:</span> { lastUpdate<span class="op">:</span> <span class="kw">false</span> } } })</span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a>{</span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a> <span class="st">"city"</span><span class="op">:</span> <span class="st">"A Coruña (La Coruña)"</span><span class="op">,</span></span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a> <span class="st">"cityId"</span><span class="op">:</span> <span class="dv">1</span><span class="op">,</span></span>
<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a> <span class="st">"country"</span><span class="op">:</span> {</span>
<span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a> <span class="st">"country"</span><span class="op">:</span> <span class="st">"Spain"</span><span class="op">,</span></span>
<span id="cb24-7"><a href="#cb24-7" aria-hidden="true" tabindex="-1"></a> <span class="st">"countryId"</span><span class="op">:</span> <span class="dv">87</span></span>
<span id="cb24-8"><a href="#cb24-8" aria-hidden="true" tabindex="-1"></a> }<span class="op">,</span></span>
<span id="cb24-9"><a href="#cb24-9" aria-hidden="true" tabindex="-1"></a> <span class="st">"countryId"</span><span class="op">:</span> <span class="dv">87</span></span>
<span id="cb24-10"><a href="#cb24-10" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>In the same way, if the relationship between the
<code>actor</code> and <code>film</code> tables
(many-to-many) is expanded, the following command
excludes the identifiers on each nested object:</p>
<div class="sourceCode" id="cb25"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">actor</span><span class="op">.</span><span class="fu">findFirst</span>({ select<span class="op">:</span> { filmActor<span class="op">:</span> { actorId<span class="op">:</span> <span class="kw">false</span><span class="op">,</span> film<span class="op">:</span> { filmId<span class="op">:</span> <span class="kw">false</span><span class="op">,</span> languageId<span class="op">:</span> <span class="kw">false</span><span class="op">,</span> originalLanguageId<span class="op">:</span> <span class="kw">false</span> } } } })</span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>{</span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a> <span class="st">"actorId"</span><span class="op">:</span> <span class="dv">58</span><span class="op">,</span></span>
<span id="cb25-5"><a href="#cb25-5" aria-hidden="true" tabindex="-1"></a> <span class="st">"lastName"</span><span class="op">:</span> <span class="st">"AKROYD"</span><span class="op">,</span></span>
<span id="cb25-6"><a href="#cb25-6" aria-hidden="true" tabindex="-1"></a> <span class="st">"filmActor"</span><span class="op">:</span> [</span>
<span id="cb25-7"><a href="#cb25-7" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb25-8"><a href="#cb25-8" aria-hidden="true" tabindex="-1"></a> <span class="st">"film"</span><span class="op">:</span> {</span>
<span id="cb25-9"><a href="#cb25-9" aria-hidden="true" tabindex="-1"></a> <span class="st">"title"</span><span class="op">:</span> <span class="st">"BACKLASH UNDEFEATED"</span><span class="op">,</span></span>
<span id="cb25-10"><a href="#cb25-10" aria-hidden="true" tabindex="-1"></a> <span class="st">"length"</span><span class="op">:</span> <span class="dv">118</span><span class="op">,</span></span>
<span id="cb25-11"><a href="#cb25-11" aria-hidden="true" tabindex="-1"></a> <span class="st">"rating"</span><span class="op">:</span> <span class="st">"PG-13"</span><span class="op">,</span></span>
<span id="cb25-12"><a href="#cb25-12" aria-hidden="true" tabindex="-1"></a> <span class="st">"lastUpdate"</span><span class="op">:</span> <span class="st">"2006-02-15 05:03:42.000000"</span><span class="op">,</span></span>
<span id="cb25-13"><a href="#cb25-13" aria-hidden="true" tabindex="-1"></a> <span class="st">"rentalRate"</span><span class="op">:</span> <span class="fl">4.99</span><span class="op">,</span></span>
<span id="cb25-14"><a href="#cb25-14" aria-hidden="true" tabindex="-1"></a> <span class="st">"description"</span><span class="op">:</span> <span class="st">"A Stunning Character Study of a Mad Scientist And a Mad Cow who must Kill a Car in A Monastery"</span><span class="op">,</span></span>
<span id="cb25-15"><a href="#cb25-15" aria-hidden="true" tabindex="-1"></a> <span class="st">"releaseYear"</span><span class="op">:</span> <span class="dv">2006</span><span class="op">,</span></span>
<span id="cb25-16"><a href="#cb25-16" aria-hidden="true" tabindex="-1"></a> <span class="st">"rentalDuration"</span><span class="op">:</span> <span class="dv">3</span><span class="op">,</span></span>
<span id="cb25-17"><a href="#cb25-17" aria-hidden="true" tabindex="-1"></a> <span class="st">"replacementCost"</span><span class="op">:</span> <span class="fl">24.99</span><span class="op">,</span></span>
<span id="cb25-18"><a href="#cb25-18" aria-hidden="true" tabindex="-1"></a> <span class="st">"specialFeatures"</span><span class="op">:</span> <span class="st">"Trailers,Behind the Scenes"</span></span>
<span id="cb25-19"><a href="#cb25-19" aria-hidden="true" tabindex="-1"></a> }<span class="op">,</span></span>
<span id="cb25-20"><a href="#cb25-20" aria-hidden="true" tabindex="-1"></a> <span class="st">"filmId"</span><span class="op">:</span> <span class="dv">48</span><span class="op">,</span></span>
<span id="cb25-21"><a href="#cb25-21" aria-hidden="true" tabindex="-1"></a> <span class="st">"lastUpdate"</span><span class="op">:</span> <span class="st">"2006-02-15 05:05:03.000000"</span></span>
<span id="cb25-22"><a href="#cb25-22" aria-hidden="true" tabindex="-1"></a> }<span class="op">,</span></span>
<span id="cb25-23"><a href="#cb25-23" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb25-24"><a href="#cb25-24" aria-hidden="true" tabindex="-1"></a> ]<span class="op">,</span></span>
<span id="cb25-25"><a href="#cb25-25" aria-hidden="true" tabindex="-1"></a> <span class="st">"firstName"</span><span class="op">:</span> <span class="st">"CHRISTIAN"</span><span class="op">,</span></span>
<span id="cb25-26"><a href="#cb25-26" aria-hidden="true" tabindex="-1"></a> <span class="st">"lastUpdate"</span><span class="op">:</span> <span class="st">"2006-02-15 04:34:33.000000"</span></span>
<span id="cb25-27"><a href="#cb25-27" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>On the other hand, fields can be cherry-picked and
included in the query response by using either the same
object format and setting the value to
<code>true</code>, or alternatively, using a list of
field names to include.</p>
<p>In the same way, this is possible for one-to-one
relationships:</p>
<div class="sourceCode" id="cb26"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">city</span><span class="op">.</span><span class="fu">findFirst</span>({ select<span class="op">:</span> { city<span class="op">:</span> <span class="kw">true</span><span class="op">,</span> country<span class="op">:</span> { country<span class="op">:</span> <span class="kw">true</span> } } })</span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a>{</span>
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a> <span class="st">"city"</span><span class="op">:</span> <span class="st">"A Coruña (La Coruña)"</span><span class="op">,</span></span>
<span id="cb26-4"><a href="#cb26-4" aria-hidden="true" tabindex="-1"></a> <span class="st">"country"</span><span class="op">:</span> {</span>
<span id="cb26-5"><a href="#cb26-5" aria-hidden="true" tabindex="-1"></a> <span class="st">"country"</span><span class="op">:</span> <span class="st">"Spain"</span><span class="op">,</span></span>
<span id="cb26-6"><a href="#cb26-6" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb26-7"><a href="#cb26-7" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>And also for many-to-many relationships:</p>
<div class="sourceCode" id="cb27"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">actor</span><span class="op">.</span><span class="fu">findFirst</span>({ select<span class="op">:</span> [<span class="st">'filmActor.film.title'</span>] })</span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a>{</span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a> <span class="st">"filmActor"</span><span class="op">:</span> [</span>
<span id="cb27-4"><a href="#cb27-4" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb27-5"><a href="#cb27-5" aria-hidden="true" tabindex="-1"></a> <span class="st">"film"</span><span class="op">:</span> {</span>
<span id="cb27-6"><a href="#cb27-6" aria-hidden="true" tabindex="-1"></a> <span class="st">"title"</span><span class="op">:</span> <span class="st">"BACKLASH UNDEFEATED"</span></span>
<span id="cb27-7"><a href="#cb27-7" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb27-8"><a href="#cb27-8" aria-hidden="true" tabindex="-1"></a> }<span class="op">,</span></span>
<span id="cb27-9"><a href="#cb27-9" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb27-10"><a href="#cb27-10" aria-hidden="true" tabindex="-1"></a> <span class="st">"film"</span><span class="op">:</span> {</span>
<span id="cb27-11"><a href="#cb27-11" aria-hidden="true" tabindex="-1"></a> <span class="st">"title"</span><span class="op">:</span> <span class="st">"BETRAYED REAR"</span></span>
<span id="cb27-12"><a href="#cb27-12" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb27-13"><a href="#cb27-13" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb27-14"><a href="#cb27-14" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb27-15"><a href="#cb27-15" aria-hidden="true" tabindex="-1"></a> ]</span>
<span id="cb27-16"><a href="#cb27-16" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h2 data-number="3.3" id="updating-a-document"><span
class="header-section-number">3.3</span> Updating A
Document</h2>
<p>The SDK offers two different methods of how to update
an existing document on a REST view.</p>
<ol type="1">
<li>Using the REST view <code>update</code> method.
<ul>
<li>REST view class exposes an <code>update</code> API
method that can be called with the new document data. In
this case, all fields, including the primary key fields
need to be specified explicitly.</li>
</ul></li>
<li>Using the Document API.
<ul>
<li>When a MRS document has been fetched before using
the <code>find</code> API methods, the updates can be
applied directly to the fields of that document. After
all changes have been performed, the <code>update</code>
method of the document object can be called. Please see
the <a
href="#document-api-for-updates-and-deletes">Document
API</a> section for more details.</li>
</ul></li>
</ol>
<h3 data-number="3.3.1"
id="updating-a-document-using-the-rest-view-update-method"><span
class="header-section-number">3.3.1</span> Updating a
Document Using the REST View update Method</h3>
<p>Updating a document on the REST view requires all
fields to be specified if they are not nullable.</p>
<p>In the following example, neither
<code>firstName</code> nor <code>lastName</code> are
nullable and have to be specified. On the other hand,
the <code>description</code> column in the
<code>film_text</code> table is nullable.</p>
<p><strong><em>TypeScript</em></strong></p>
<div class="sourceCode" id="cb28"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">actor</span><span class="op">.</span><span class="fu">update</span>({ data<span class="op">:</span> { id<span class="op">:</span> <span class="dv">1</span><span class="op">,</span> firstName<span class="op">:</span> <span class="st">"PENELOPE"</span><span class="op">,</span> lastName<span class="op">:</span> <span class="st">"CRUZ"</span> } }) <span class="co">// Property 'lastUpdate' is missing in type '{ actorId: number; lastName: string; firstName: string; }' but required in type 'IUpdateMyServiceSakilaActor'.</span></span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">filmText</span><span class="op">.</span><span class="fu">update</span>({ data<span class="op">:</span> { film_id<span class="op">:</span> <span class="dv">1</span><span class="op">,</span> title<span class="op">:</span> <span class="st">"FOO"</span> } })</span></code></pre></div>
<p><strong><em>Python</em></strong></p>
<div class="sourceCode" id="cb29"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a>my_service.sakila.actor.update(data<span class="op">=</span>{<span class="st">"id"</span>: <span class="dv">1</span>, <span class="st">"first_name"</span>: <span class="st">"PENELOPE"</span>, <span class="st">"last_name"</span>: <span class="st">"CRUZ"</span>}) <span class="co"># Missing key "last_update" for TypedDict "IUpdateMyServiceSakilaActor"</span></span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a>my_service.sakila.film_text.update(data<span class="op">=</span>{<span class="st">"film_id"</span>: <span class="dv">1</span>, <span class="st">"title"</span>: <span class="st">"FOO"</span>})</span></code></pre></div>
<h3 data-number="3.3.2"
id="updating-a-document-using-the-document-api"><span
class="header-section-number">3.3.2</span> Updating a
Document using the Document API</h3>
<p>When fetching documents from REST view endpoints, the
SDK offers a convenient API to work with those objects
in a object-oriented way, by using <code>update</code>
and <code>delete</code> methods that can be directly
called on the document.</p>
<p>The <code>update</code> and <code>delete</code>
methods are only available if the corresponding REST
View enables the “UPDATE” and/or “DELETE” CRUD
operations, respectively and specifies the appropriate
identifier fields (mapping to underlying database
primary keys).</p>
<blockquote>
<p>In the TypeScript SDK, the identifier fields that are
part of a REST Document are read-only. This is currently
not the case on the Python SDK.</p>
</blockquote>
<p><strong><em>TypeScript</em></strong></p>
<div class="sourceCode" id="cb30"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> actor <span class="op">=</span> <span class="cf">await</span> my_service<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">actor</span><span class="op">.</span><span class="fu">find_first</span>()</span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> (actor) {</span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(actor<span class="op">.</span><span class="at">actorId</span>) <span class="co">// 1</span></span>
<span id="cb30-4"><a href="#cb30-4" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(actor<span class="op">.</span><span class="at">lastName</span>) <span class="co">// "GUINESS"</span></span>
<span id="cb30-5"><a href="#cb30-5" aria-hidden="true" tabindex="-1"></a> actor<span class="op">.</span><span class="at">lastName</span> <span class="op">=</span> <span class="st">"NOGUINESS"</span></span>
<span id="cb30-6"><a href="#cb30-6" aria-hidden="true" tabindex="-1"></a> <span class="cf">await</span> actor<span class="op">.</span><span class="fu">update</span>()</span>
<span id="cb30-7"><a href="#cb30-7" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb30-8"><a href="#cb30-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-9"><a href="#cb30-9" aria-hidden="true" tabindex="-1"></a>actor <span class="op">=</span> <span class="cf">await</span> my_service<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">actor</span><span class="op">.</span><span class="fu">find_first</span>()</span>
<span id="cb30-10"><a href="#cb30-10" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> (actor) {</span>
<span id="cb30-11"><a href="#cb30-11" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(actor<span class="op">.</span><span class="at">lastName</span>) <span class="co">// "NOGUINESS"</span></span>
<span id="cb30-12"><a href="#cb30-12" aria-hidden="true" tabindex="-1"></a> <span class="cf">await</span> actor<span class="op">.</span><span class="fu">delete</span>()</span>
<span id="cb30-13"><a href="#cb30-13" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb30-14"><a href="#cb30-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-15"><a href="#cb30-15" aria-hidden="true" tabindex="-1"></a>actor <span class="op">=</span> <span class="cf">await</span> my_service<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">actor</span><span class="op">.</span><span class="fu">find_first</span>()</span>
<span id="cb30-16"><a href="#cb30-16" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> (actor) {</span>
<span id="cb30-17"><a href="#cb30-17" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(actor<span class="op">.</span><span class="at">actorId</span>) <span class="co">// 2</span></span>
<span id="cb30-18"><a href="#cb30-18" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p><strong><em>Python</em></strong></p>
<div class="sourceCode" id="cb31"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a>actor <span class="op">=</span> <span class="cf">await</span> my_service.sakila.actor.find_first()</span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> actor:</span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(actor.actor_id) <span class="co"># 1</span></span>
<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(actor.last_name) <span class="co"># "GUINESS"</span></span>
<span id="cb31-5"><a href="#cb31-5" aria-hidden="true" tabindex="-1"></a> actor.last_name <span class="op">=</span> <span class="st">"NOGUINESS"</span></span>
<span id="cb31-6"><a href="#cb31-6" aria-hidden="true" tabindex="-1"></a> <span class="cf">await</span> actor.update()</span>
<span id="cb31-7"><a href="#cb31-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb31-8"><a href="#cb31-8" aria-hidden="true" tabindex="-1"></a>actor <span class="op">=</span> <span class="cf">await</span> my_service.sakila.actor.find_first()</span>
<span id="cb31-9"><a href="#cb31-9" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> actor:</span>
<span id="cb31-10"><a href="#cb31-10" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(actor.last_name) <span class="co"># "NOGUINESS"</span></span>
<span id="cb31-11"><a href="#cb31-11" aria-hidden="true" tabindex="-1"></a> <span class="cf">await</span> actor.delete()</span>
<span id="cb31-12"><a href="#cb31-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb31-13"><a href="#cb31-13" aria-hidden="true" tabindex="-1"></a>actor <span class="op">=</span> <span class="cf">await</span> my_service.sakila.actor.find_first()</span>
<span id="cb31-14"><a href="#cb31-14" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> actor:</span>
<span id="cb31-15"><a href="#cb31-15" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(actor.actor_id) <span class="co"># 2</span></span></code></pre></div>
<h3 data-number="3.3.3"
id="language-specific-implementation-details"><span
class="header-section-number">3.3.3</span> Language
Specific Implementation Details</h3>
<p>All MRS SDK commands that return back to the
application one or more instances of REST documents
perform some internal plumbing to simplify the
client-side data structure, by ensuring that
SDK-specific details such as protocol resource metadata
(which includes things like ETags and GTIDs) or
HATEOAS-specific properties (such as links and
pagination control fields) are not exposed but are still
able to be tracked at runtime. This is important
because, even though those details are not supposed to
be handled by an application, they can still determine
specific behaviors when the application executes an SDK
command.</p>
<p>For instance, when updating a REST document, the
corresponding <a
href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/ETag">ETag</a>
must be sent to the MySQL Router, in order to detect <a
href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/ETag#avoiding_mid-air_collisions">mid-air
collisions</a> and make sure that changes happened in
the document, after it was retrieved by the application
in the first place, are not overridden. In the same way,
a command executed by the application that can write
data (<code>INSERT</code> or <code>UPDATE</code>) will
spawn a server-side transaction that can generate a <a
href="https://dev.mysql.com/doc/refman/8.4/en/replication-gtids.html">GTID</a>
which must also be sent to the MySQL Router if the
application requires <a
href="#read-your-writes-consistency">read
consistency</a> in a setup consisting of multiple server
instances.</p>
<p>Hiding and locking these details involves either
wrapping the actual data responses sent by the MySQL
Router or applying specific access control constraints
on top of the details available on those responses. In
TypeScript, this is done by wrapping a client-side
instance in a <a
href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy"><code>Proxy</code></a>
object. In Python, this is done by wrapping it in a <a
href="https://docs.python.org/3/library/dataclasses.html"><code>dataclass</code></a>.</p>
<p>This results in something as follows:</p>
<div class="sourceCode" id="cb32"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> actor <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">actor</span><span class="op">.</span><span class="fu">findFirst</span>()</span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a><span class="cf">try</span> {</span>
<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a> <span class="kw">delete</span> actor<span class="op">.</span><span class="at">_metadata</span></span>
<span id="cb32-5"><a href="#cb32-5" aria-hidden="true" tabindex="-1"></a>} <span class="cf">catch</span> (err) {</span>
<span id="cb32-6"><a href="#cb32-6" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(err<span class="op">.</span><span class="at">message</span>) <span class="co">// The "_metadata" property cannot be deleted.</span></span>
<span id="cb32-7"><a href="#cb32-7" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb32-8"><a href="#cb32-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-9"><a href="#cb32-9" aria-hidden="true" tabindex="-1"></a><span class="cf">try</span> {</span>
<span id="cb32-10"><a href="#cb32-10" aria-hidden="true" tabindex="-1"></a> actor<span class="op">.</span><span class="at">_metadata</span> <span class="op">=</span> { foo<span class="op">:</span> <span class="st">"bar"</span> }</span>
<span id="cb32-11"><a href="#cb32-11" aria-hidden="true" tabindex="-1"></a>} <span class="cf">catch</span> (err) {</span>
<span id="cb32-12"><a href="#cb32-12" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(err<span class="op">.</span><span class="at">message</span>) <span class="co">// The "_metadata" property cannot be changed.</span></span>
<span id="cb32-13"><a href="#cb32-13" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>Additionally, these wrappers allow to augment the
object representation of a REST Document with a small
contextual API which contains utility commands
(<code>update()</code> and <code>delete()</code>, names
are self-describing) that operate directly in the scope
of each particular document.</p>
<h3 data-number="3.3.4"
id="contextual-fields-and-parameters"><span
class="header-section-number">3.3.4</span> Contextual
fields and parameters</h3>
<p>There are different requirements at play when
inserting a new document or when updating an existing
document in a Table or View using the MySQL REST
Service. For starters, since there is currently no
support for partial updates, this means that every time
an application wants to update a row, it needs to
provide a complete representation of the row as it will
become. That representation can still determine
potential columns which will be “unset” notwithstanding,
at least for those cases where the columns do not impose
a constraint that prevents such an action (this is in
line with what happens on <a
href="https://docs.oracle.com/en/database/oracle/oracle-rest-data-services/24.2/orddg/developing-REST-applications.html#GUID-A323AA4F-32BE-47B7-9CC2-C0F4C8F4DFBE">ORDS</a>).
On the other hand, even though there is no specific
limitation for inserting new rows, an application should
still be aware of the underlying column constraints to
reduce the friction by requiring the minimum possible
set of fields or alternatively, provide better user
feedback (e.g. using the type checker) when it comes to
missing fields required to perform the operation.</p>
<p>From the MRS SDK standpoint this means that the type
definitions used to insert and update rows must be
capable of making the distinction between required and
optional fields. In practice, a field should always be
required unless there is some specific circumstance that
allows it to be optional such as the fact that it maps
to an auto-generated primary key column, a foreign key
column, a nullable column or a column with a default
value. Whilst inserting a value, all of these
circumstances are valid and should be accounted for,
whereas whilst updating a value, due to the limitations
described above, it only makes sense for a field to be
optional when it maps to a nullable column or column
with row ownership.</p>
<h2 data-number="3.4" id="deleting-a-document"><span
class="header-section-number">3.4</span> Deleting A
Document</h2>
<p>Similar to updating a document, deleting a document
can be done using either the REST view
<code>delete</code> method or the Document API
<code>delete</code> method called directly on the
object.</p>
<p>Please see above to learn how to delete a document
via the Document API.</p>
<h2 data-number="3.5"
id="read-your-writes-consistency"><span
class="header-section-number">3.5</span> Read Your
Writes Consistency</h2>
<p>With multiple MySQL server instances running as an
InnoDB Cluster/ClusterSet, data read from one instance
might be dependent on data written on a different
instance, which might not have been yet replicated to
the server where the data is being read from. This is a
classical concern on distributed systems which alludes
to the consistency of the data and the problem has been
formalized as a concept called <a
href="https://jepsen.io/consistency/models/read-your-writes">Read
Your Writes</a>.</p>
<p>To solve this issue, and ensure an application is
always able to read its own writes, MySQL uses a Global
Transaction ID (GTID), whose definition, according to
the official <a
href="https://dev.mysql.com/doc/refman/8.4/en/replication-gtids-concepts.html">documentation</a>,
is:</p>
<p>A global transaction identifier (GTID) is a unique
identifier created and associated with each transaction
committed on the server of origin (the source). This
identifier is unique not only to the server on which it
originated, but is unique across all servers in a given
replication topology.</p>
<p>It is, in essence, and in layman’s terms, an
identifier that is provided to a client for each “write”
operation, which the client can then provide back to the
MySQL server cluster which can use it to ensure any
subsequent read accounts for all the data written up
until the operation that generated that GTID. This
usually carries a cost, and for that reason, is a
behavior that needs to be explicitly enabled by the end
user depending on what kind of topology an application
is using.</p>
<p>In the MySQL REST Service, it is possible to ensure
an application is able to read its own writes
consistently in a cluster of MySQL instances only when
retrieving resources or deleting resources. Using the
TypeScript SDK, this can be done with the
<code>readOwnWrites</code> option available for the
following commands:</p>
<ul>
<li><code>find()</code></li>
<li><code>findFirst()</code></li>
<li><code>findFirstOrThrow()</code></li>
<li><code>findUnique()</code></li>
<li><code>findUniqueOrThrow()</code></li>
<li><code>delete()</code></li>
<li><code>deleteMany()</code></li>
</ul>
<div class="sourceCode" id="cb33"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">actor</span><span class="op">.</span><span class="fu">findFirst</span>({ readOwnWrites<span class="op">:</span> <span class="kw">true</span> })</span></code></pre></div>
<p>This option is only relevant when the application is
running on top of a MySQL instance cluster where the
GTID infrastructure is specifically configured and
enabled, otherwise the option will be ignored.</p>
<!-- Copyright (c) 2022, 2026, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2.0,
as published by the Free Software Foundation.
This program is designed to work with certain software (including
but not limited to OpenSSL) that is licensed under separate terms, as
designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have either included with
the program or referenced in the documentation.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
the GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -->
<h1 data-number="4"
id="working-with-rest-routines"><span
class="header-section-number">4</span> Working with REST
Routines</h1>
<p>In its most basic form, a REST Function or Procedure
can be executed with the MRS SDK using the
<code>call()</code> command. The command must receive,
as input, the SET of <code>IN</code> and/or
<code>INOUT</code> parameters (and corresponding values)
allowed by the database routine.</p>
<p>The examples assume a setup using the <a
href="https://dev.mysql.com/doc/sakila/en/">Sakila
Sample Database</a> where the schema and the
corresponding tables and routines are available under a
REST service called <code>myService</code>.</p>
<p>Consider the following REST Function based on the
<code>inventory_in_stock</code> function available in
the <a
href="https://dev.mysql.com/doc/sakila/en/">Sakila
Sample Database</a>.</p>
<div class="sourceCode" id="cb34"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb34-1"><a href="#cb34-1" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> <span class="kw">OR</span> <span class="kw">REPLACE</span> REST <span class="kw">FUNCTION</span> <span class="op">/</span>inventoryInStock</span>
<span id="cb34-2"><a href="#cb34-2" aria-hidden="true" tabindex="-1"></a> <span class="kw">ON</span> SERVICE <span class="op">/</span>myService <span class="kw">SCHEMA</span> <span class="op">/</span>sakila</span>
<span id="cb34-3"><a href="#cb34-3" aria-hidden="true" tabindex="-1"></a> <span class="kw">AS</span> sakila.inventory_in_stock</span>
<span id="cb34-4"><a href="#cb34-4" aria-hidden="true" tabindex="-1"></a> <span class="kw">PARAMETERS</span> MyServiceSakilaInventoryInStockParams {</span>
<span id="cb34-5"><a href="#cb34-5" aria-hidden="true" tabindex="-1"></a> pInventoryId: p_inventory_id @IN</span>
<span id="cb34-6"><a href="#cb34-6" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb34-7"><a href="#cb34-7" aria-hidden="true" tabindex="-1"></a> RESULT MyServiceSakilaInventoryInStockResult {</span>
<span id="cb34-8"><a href="#cb34-8" aria-hidden="true" tabindex="-1"></a> result: result @DATATYPE(<span class="ot">"bit(1)"</span>)</span>
<span id="cb34-9"><a href="#cb34-9" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb34-10"><a href="#cb34-10" aria-hidden="true" tabindex="-1"></a> AUTHENTICATION <span class="kw">NOT</span> REQUIRED;</span></code></pre></div>
<p><strong><em>TypeScript</em></strong></p>
<p>In the TypeScript SDK, the command accepts, as its
first parameter, an object containing the set of
<code>IN</code> and/or <code>INOUT</code> parameters
(and corresponding values).</p>
<div class="sourceCode" id="cb35"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb35-1"><a href="#cb35-1" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">inventoryInStock</span><span class="op">.</span><span class="fu">call</span>({ pInventoryId<span class="op">:</span> <span class="dv">1</span> })<span class="op">;</span></span>
<span id="cb35-2"><a href="#cb35-2" aria-hidden="true" tabindex="-1"></a><span class="co">// true</span></span></code></pre></div>
<p><strong><em>Python</em></strong></p>
<p>In the Python SDK, the command accepts the same set
of parameters and values as keyword arguments:</p>
<div class="sourceCode" id="cb36"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb36-1"><a href="#cb36-1" aria-hidden="true" tabindex="-1"></a>my_service.sakila.inventory_in_stock.call(p_inventory_id<span class="op">=</span><span class="dv">1</span>)</span>
<span id="cb36-2"><a href="#cb36-2" aria-hidden="true" tabindex="-1"></a><span class="co"># true</span></span></code></pre></div>
<p>For Functions or Procedures, all fields (or input
parameters in this case) should be considered optional
because they cannot have <code>NOT NULL</code>
constraints, which always makes them nullable by nature.
Thus, an optional parameter is just a parameter where
the value can be <code>NULL</code>.</p>
<p>Calling a function or procedure does not require any
field to be specified because input parameters are
nullable by nature (there is no syntax to add
<code>NOT NULL</code> constraints). It is expected that
functions and procedures handle <code>NULL</code> values
at runtime accordingly. For example, with a MySQL
<code>FUNCTION</code> as follows:</p>
<div class="sourceCode" id="cb37"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb37-1"><a href="#cb37-1" aria-hidden="true" tabindex="-1"></a>DELIMITER <span class="op">//</span></span>
<span id="cb37-2"><a href="#cb37-2" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> <span class="kw">FUNCTION</span> my_db.my_func (x <span class="dt">INT</span>, y <span class="dt">INT</span>)</span>
<span id="cb37-3"><a href="#cb37-3" aria-hidden="true" tabindex="-1"></a>RETURNS BIGINT DETERMINISTIC</span>
<span id="cb37-4"><a href="#cb37-4" aria-hidden="true" tabindex="-1"></a><span class="cf">BEGIN</span></span>
<span id="cb37-5"><a href="#cb37-5" aria-hidden="true" tabindex="-1"></a> <span class="kw">DECLARE</span> sum_result BIGINT <span class="kw">DEFAULT</span> <span class="dv">0</span>;</span>
<span id="cb37-6"><a href="#cb37-6" aria-hidden="true" tabindex="-1"></a> <span class="cf">IF</span> y <span class="kw">is</span> <span class="kw">NULL</span> <span class="cf">THEN</span></span>
<span id="cb37-7"><a href="#cb37-7" aria-hidden="true" tabindex="-1"></a> <span class="kw">SET</span> sum_result <span class="op">=</span> x;</span>
<span id="cb37-8"><a href="#cb37-8" aria-hidden="true" tabindex="-1"></a> <span class="cf">ELSE</span></span>
<span id="cb37-9"><a href="#cb37-9" aria-hidden="true" tabindex="-1"></a> <span class="kw">SET</span> sum_result <span class="op">=</span> x <span class="op">+</span> y;</span>
<span id="cb37-10"><a href="#cb37-10" aria-hidden="true" tabindex="-1"></a> <span class="cf">END</span> <span class="cf">IF</span>;</span>
<span id="cb37-11"><a href="#cb37-11" aria-hidden="true" tabindex="-1"></a> <span class="kw">RETURN</span> sum_result;</span>
<span id="cb37-12"><a href="#cb37-12" aria-hidden="true" tabindex="-1"></a><span class="cf">END</span> <span class="op">//</span></span>
<span id="cb37-13"><a href="#cb37-13" aria-hidden="true" tabindex="-1"></a>DELIMITER ;</span></code></pre></div>
<p>where the corresponding REST object is created as
follows:</p>
<div class="sourceCode" id="cb38"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb38-1"><a href="#cb38-1" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> <span class="kw">OR</span> <span class="kw">REPLACE</span> REST <span class="kw">FUNCTION</span> <span class="op">/</span>myFunc <span class="kw">ON</span> SERVICE <span class="op">/</span>myService <span class="kw">SCHEMA</span> <span class="op">/</span>myDb <span class="kw">AS</span> my_db.my_func</span>
<span id="cb38-2"><a href="#cb38-2" aria-hidden="true" tabindex="-1"></a> <span class="kw">PARAMETERS</span> IMyServiceMyDbMyFuncParams {</span>
<span id="cb38-3"><a href="#cb38-3" aria-hidden="true" tabindex="-1"></a> x: x @IN,</span>
<span id="cb38-4"><a href="#cb38-4" aria-hidden="true" tabindex="-1"></a> y: y @IN</span>
<span id="cb38-5"><a href="#cb38-5" aria-hidden="true" tabindex="-1"></a> }</span></code></pre></div>
<p><strong><em>TypeScript</em></strong></p>
<div class="sourceCode" id="cb39"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb39-1"><a href="#cb39-1" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">myDb</span><span class="op">.</span><span class="at">myFunc</span><span class="op">.</span><span class="fu">call</span>() <span class="co">// null</span></span>
<span id="cb39-2"><a href="#cb39-2" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">myDb</span><span class="op">.</span><span class="at">myFunc</span><span class="op">.</span><span class="fu">call</span>({ x<span class="op">:</span> <span class="dv">3</span> }) <span class="co">// 3</span></span>
<span id="cb39-3"><a href="#cb39-3" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">myDb</span><span class="op">.</span><span class="at">myFunc</span><span class="op">.</span><span class="fu">call</span>({ x<span class="op">:</span> <span class="dv">3</span><span class="op">,</span> y<span class="op">:</span> <span class="dv">2</span> }) <span class="co">// 5</span></span></code></pre></div>
<p><strong><em>Python</em></strong></p>
<div class="sourceCode" id="cb40"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb40-1"><a href="#cb40-1" aria-hidden="true" tabindex="-1"></a>my_service.my_db.myFunc() <span class="co"># None</span></span>
<span id="cb40-2"><a href="#cb40-2" aria-hidden="true" tabindex="-1"></a>my_service.my_db.myFunc(x<span class="op">=</span><span class="dv">3</span>) <span class="co"># 3</span></span>
<span id="cb40-3"><a href="#cb40-3" aria-hidden="true" tabindex="-1"></a>my_service.my_db.myFunc(x<span class="op">=</span><span class="dv">3</span>, y<span class="op">=</span><span class="dv">2</span>) <span class="co"># 5</span></span></code></pre></div>
<p>Procedures can produce output either via result sets
ou <code>OUT</code>/<code>INOUT</code> parameters. For
example, with a MySQL <code>PROCEDURE</code> as
follows:</p>
<div class="sourceCode" id="cb41"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb41-1"><a href="#cb41-1" aria-hidden="true" tabindex="-1"></a>DELIMITER <span class="op">//</span></span>
<span id="cb41-2"><a href="#cb41-2" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> <span class="kw">PROCEDURE</span> my_db.my_proc (<span class="kw">IN</span> x <span class="dt">INT</span>, <span class="kw">IN</span> y <span class="dt">INT</span>, <span class="kw">OUT</span> z <span class="dt">INT</span>)</span>
<span id="cb41-3"><a href="#cb41-3" aria-hidden="true" tabindex="-1"></a><span class="cf">BEGIN</span></span>
<span id="cb41-4"><a href="#cb41-4" aria-hidden="true" tabindex="-1"></a> <span class="kw">DECLARE</span> sum_result BIGINT <span class="kw">DEFAULT</span> <span class="dv">0</span>;</span>
<span id="cb41-5"><a href="#cb41-5" aria-hidden="true" tabindex="-1"></a> <span class="cf">IF</span> y <span class="kw">is</span> <span class="kw">NULL</span> <span class="cf">THEN</span></span>
<span id="cb41-6"><a href="#cb41-6" aria-hidden="true" tabindex="-1"></a> <span class="kw">SET</span> sum_result <span class="op">=</span> x;</span>
<span id="cb41-7"><a href="#cb41-7" aria-hidden="true" tabindex="-1"></a> <span class="cf">ELSE</span></span>
<span id="cb41-8"><a href="#cb41-8" aria-hidden="true" tabindex="-1"></a> <span class="kw">SET</span> sum_result <span class="op">=</span> x <span class="op">+</span> y;</span>
<span id="cb41-9"><a href="#cb41-9" aria-hidden="true" tabindex="-1"></a> <span class="cf">END</span> <span class="cf">IF</span>;</span>
<span id="cb41-10"><a href="#cb41-10" aria-hidden="true" tabindex="-1"></a> <span class="kw">SELECT</span> sum_result <span class="kw">INTO</span> z;</span>
<span id="cb41-11"><a href="#cb41-11" aria-hidden="true" tabindex="-1"></a> <span class="kw">SELECT</span> sum_result <span class="kw">AS</span> sum_result;</span>
<span id="cb41-12"><a href="#cb41-12" aria-hidden="true" tabindex="-1"></a><span class="cf">END</span> <span class="op">//</span></span>
<span id="cb41-13"><a href="#cb41-13" aria-hidden="true" tabindex="-1"></a>DELIMITER ;</span></code></pre></div>
<p>where the corresponding REST object is created as
follows:</p>
<div class="sourceCode" id="cb42"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb42-1"><a href="#cb42-1" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> <span class="kw">OR</span> <span class="kw">REPLACE</span> REST <span class="kw">PROCEDURE</span> <span class="op">/</span>myProc <span class="kw">ON</span> SERVICE <span class="op">/</span>myService <span class="kw">SCHEMA</span> <span class="op">/</span>myDb <span class="kw">AS</span> my_db.my_proc</span>
<span id="cb42-2"><a href="#cb42-2" aria-hidden="true" tabindex="-1"></a> <span class="kw">PARAMETERS</span> IMyServiceMyDbMyProcParams {</span>
<span id="cb42-3"><a href="#cb42-3" aria-hidden="true" tabindex="-1"></a> x: x @IN,</span>
<span id="cb42-4"><a href="#cb42-4" aria-hidden="true" tabindex="-1"></a> y: y @IN,</span>
<span id="cb42-5"><a href="#cb42-5" aria-hidden="true" tabindex="-1"></a> x: z @OUT</span>
<span id="cb42-6"><a href="#cb42-6" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb42-7"><a href="#cb42-7" aria-hidden="true" tabindex="-1"></a> RESULT MyServiceMyDbMyProcResult {</span>
<span id="cb42-8"><a href="#cb42-8" aria-hidden="true" tabindex="-1"></a> sum_result: sum_result @DATATYPE(<span class="ot">"INT"</span>)</span>
<span id="cb42-9"><a href="#cb42-9" aria-hidden="true" tabindex="-1"></a> }</span></code></pre></div>
<p><strong><em>TypeScript</em></strong></p>
<div class="sourceCode" id="cb43"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb43-1"><a href="#cb43-1" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">myDb</span><span class="op">.</span><span class="at">myProc</span><span class="op">.</span><span class="fu">call</span>() <span class="co">// { resultSets: [{ type: "MyServiceMyDbMySumResult", items: [{ sum_result: null }] }], outParameters: { z: null } }</span></span>
<span id="cb43-2"><a href="#cb43-2" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">myDb</span><span class="op">.</span><span class="at">myProc</span><span class="op">.</span><span class="fu">call</span>({ x<span class="op">:</span> <span class="dv">3</span> }) <span class="co">// { resultSets: [{ type: "MyServiceMyDbMySumResult", items: [{ sum_result: 3 }] }], outParameters: { z: 3 } }</span></span>
<span id="cb43-3"><a href="#cb43-3" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">myDb</span><span class="op">.</span><span class="at">myProc</span><span class="op">.</span><span class="fu">call</span>({ x<span class="op">:</span> <span class="dv">3</span><span class="op">,</span> y<span class="op">:</span> <span class="dv">2</span> }) <span class="co">// { resultSets: [{ type: "MyServiceMyDbMySumResult", items: [{ sum_result: 5 }] }], outParameters: { z: 5 } }</span></span></code></pre></div>
<p><strong><em>Python</em></strong></p>
<div class="sourceCode" id="cb44"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb44-1"><a href="#cb44-1" aria-hidden="true" tabindex="-1"></a>my_service.my_db.myProc() <span class="co"># IMrsProcedureResponse(result_sets=[MrsProcedureResultSet(type='MyServiceMyDbMySumResult', items=[{'sum_result': None}])], out_parameters={'z': None}</span></span>
<span id="cb44-2"><a href="#cb44-2" aria-hidden="true" tabindex="-1"></a>my_service.my_db.myProc(x<span class="op">=</span><span class="dv">3</span>) <span class="co"># IMrsProcedureResponse(result_sets=[MrsProcedureResultSet(type='MyServiceMyDbMySumResult', items=[{'sum_result': 3}])], out_parameters={'z': 3}</span></span>
<span id="cb44-3"><a href="#cb44-3" aria-hidden="true" tabindex="-1"></a>my_service.my_db.myProc(x<span class="op">=</span><span class="dv">3</span>, y<span class="op">=</span><span class="dv">2</span>) <span class="co"># IMrsProcedureResponse(result_sets=[MrsProcedureResultSet(type='MyServiceMyDbMySumResult', items=[{'sum_result': 5}])], out_parameters={'z': 5}</span></span></code></pre></div>
<h2 data-number="4.1" id="async-task-support"><span
class="header-section-number">4.1</span> Async Task
Support</h2>
<p>Long-running REST Functions/Procedures can use the
MySQL Async Task framework to spawn a monitoring task
which can be asynchronously checked for updates by the
client, in order to avoid directly executing the routine
and hit any existing HTTP request or MySQL Router
handling timeouts.</p>
<p>Using the MRS TypeScript SDK, applications can either
manually monitor tasks spawned for a given REST routine,
or simply execute the routine without having to worry
about those issues.</p>
<p>In this case, for REST routine with an associated
Async Task, the SDK will produce the same compatible
<code>call()</code> command, with support for an
additional object that allows to specify a set of
execution options, namely:</p>
<ul>
<li><code>refreshRate</code> specifies the interval (ms)
between each status update check</li>
<li><code>progress</code> specifies an asynchronous
callback that is executed with the details of each
status update report</li>
<li><code>timeout</code> specifies the maximum time (ms)
to wait for the execution to complete if this threshold
is reached, the ongoing task is killed</li>
</ul>
<p>As an example, consider the REST Function depicted
above has an associated Async Task. Executing the task,
whilst obtaining the status update reports generated by
that task can be done, in TypeScript, as follows:</p>
<div class="sourceCode" id="cb45"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb45-1"><a href="#cb45-1" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">inventoryInStock</span><span class="op">.</span><span class="fu">call</span>({ pInventoryId<span class="op">:</span> <span class="dv">1</span> }<span class="op">,</span> { progress<span class="op">:</span> (r) <span class="kw">=></span> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(r) })<span class="op">;</span></span></code></pre></div>
<p>Additionally, the SDK produces a <code>start()</code>
command, which starts the task and allows to manually
watch for status updates and/or kill the task
(cancelling the execution of the actual routine). The
command accepts, as its first an only argument, the same
set of <code>IN</code> and/or <code>INOUT</code>
parameters (and corresponding values) and returns back a
<code>Task</code> object which provides the API for
task-level actions (check the reference <a
href="ClientAPITypeScript.md#task">API docs</a> for more
details).</p>
<p>Starting the task and cancelling it if takes longer
than a specified amount of time to finish can be done,
in TypeScript, as follows:</p>
<div class="sourceCode" id="cb46"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb46-1"><a href="#cb46-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> task <span class="op">=</span> myService<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">inventoryInStock</span><span class="op">.</span><span class="fu">start</span>({ pInventoryId<span class="op">:</span> <span class="dv">1</span> }<span class="op">,</span> { timeout<span class="op">:</span> <span class="dv">10000</span> })<span class="op">;</span></span>
<span id="cb46-2"><a href="#cb46-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb46-3"><a href="#cb46-3" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="cf">await</span> (<span class="kw">const</span> report <span class="kw">of</span> task<span class="op">.</span><span class="fu">watch</span>()) {</span>
<span id="cb46-4"><a href="#cb46-4" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> (report<span class="op">.</span><span class="at">status</span> <span class="op">===</span> <span class="st">"TIMEOUT"</span>) {</span>
<span id="cb46-5"><a href="#cb46-5" aria-hidden="true" tabindex="-1"></a> <span class="cf">await</span> task<span class="op">.</span><span class="fu">kill</span>()<span class="op">;</span></span>
<span id="cb46-6"><a href="#cb46-6" aria-hidden="true" tabindex="-1"></a> } <span class="cf">else</span> <span class="cf">if</span> (report<span class="op">.</span><span class="at">status</span> <span class="op">===</span> <span class="st">"CANCELLED"</span>) {</span>
<span id="cb46-7"><a href="#cb46-7" aria-hidden="true" tabindex="-1"></a> <span class="co">// this block is executed after the task is killed</span></span>
<span id="cb46-8"><a href="#cb46-8" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(report<span class="op">.</span><span class="at">message</span>)<span class="op">;</span></span>
<span id="cb46-9"><a href="#cb46-9" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb46-10"><a href="#cb46-10" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>Getting the actual result produced by the REST
routine can be done as follows:</p>
<div class="sourceCode" id="cb47"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb47-1"><a href="#cb47-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> task <span class="op">=</span> myService<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">inventoryInStock</span><span class="op">.</span><span class="fu">start</span>({ pInventoryId<span class="op">:</span> <span class="dv">1</span> })<span class="op">;</span></span>
<span id="cb47-2"><a href="#cb47-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb47-3"><a href="#cb47-3" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="cf">await</span> (<span class="kw">const</span> report <span class="kw">of</span> task<span class="op">.</span><span class="fu">watch</span>()) {</span>
<span id="cb47-4"><a href="#cb47-4" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> (report<span class="op">.</span><span class="at">status</span> <span class="op">===</span> <span class="st">"COMPLETED"</span>) {</span>
<span id="cb47-5"><a href="#cb47-5" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(report<span class="op">.</span><span class="at">data</span><span class="op">.</span><span class="at">result</span>)<span class="op">;</span> <span class="co">// true</span></span>
<span id="cb47-6"><a href="#cb47-6" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb47-7"><a href="#cb47-7" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<!-- Copyright (c) 2022, 2026, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2.0,
as published by the Free Software Foundation.
This program is designed to work with certain software (including
but not limited to OpenSSL) that is licensed under separate terms, as
designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have either included with
the program or referenced in the documentation.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
the GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -->
<h1 data-number="5"
id="typescript-client-api-reference"><span
class="header-section-number">5</span> TypeScript Client
API Reference</h1>
<p>The MRS TypeScript SDK requires TypeScript
5.3.3+.</p>
<h2 data-number="5.1" id="getmetadata-ts"><span
class="header-section-number">5.1</span> getMetadata
</h2>
<p><code>getMetadata</code> is used to retrieve
application-specific metadata attached to an MRS
resource (REST Service, Schema and/or Object).</p>
<h3 data-number="5.1.1"
id="return-type-getmetadata"><span
class="header-section-number">5.1.1</span> Return Type
(getMetadata)</h3>
<p>A JSON object containing the application-specific
metadata attached to the resource.</p>
<h3 data-number="5.1.2" id="example-getmetadata"><span
class="header-section-number">5.1.2</span> Example
(getMetadata)</h3>
<div class="sourceCode" id="cb48"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb48-1"><a href="#cb48-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">'./myService.mrs.sdk/myService'</span><span class="op">;</span></span>
<span id="cb48-2"><a href="#cb48-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb48-3"><a href="#cb48-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()<span class="op">;</span></span>
<span id="cb48-4"><a href="#cb48-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb48-5"><a href="#cb48-5" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="fu">getMetadata</span>()<span class="op">;</span></span>
<span id="cb48-6"><a href="#cb48-6" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="fu">getMetadata</span>()<span class="op">;</span></span>
<span id="cb48-7"><a href="#cb48-7" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">getMetadata</span>()<span class="op">;</span></span></code></pre></div>
<h2 data-number="5.2" id="service-getauthapps-ts"><span
class="header-section-number">5.2</span>
Service.getAuthApps</h2>
<p>Use <code>getAuthApps</code> to get a list of
available REST authentication apps for the given REST
service. A REST service may be linked to several REST
auth apps and therefore it is necessary to choose the
right one for authentication.</p>
<p>The name of the REST auth apps needs to be passed to
the <code>Service.authenticate</code> method when
performing the authentication process.</p>
<h2 data-number="5.3" id="service-authenticate-ts"><span
class="header-section-number">5.3</span>
Service.authenticate</h2>
<p>Use <code>authenticate</code> to authenticate in a
given REST service using a given authentication app.</p>
<h3 data-number="5.3.1" id="options-authenticate"><span
class="header-section-number">5.3.1</span> Options
(authenticate)</h3>
<table>
<caption>REST Service Options for
Authentication</caption>
<colgroup>
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 70%" />
</colgroup>
<thead>
<tr class="header">
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>username</td>
<td>string</td>
<td>Yes</td>
<td>Username in the scope of the authentication
app.</td>
</tr>
<tr class="even">
<td>password</td>
<td>string</td>
<td>No</td>
<td>Password in the scope of the authentication
app.</td>
</tr>
<tr class="odd">
<td>authApp</td>
<td>string</td>
<td>Yes</td>
<td>Name of the authentication app.</td>
</tr>
</tbody>
</table>
<h3 data-number="5.3.2"
id="return-type-authenticate"><span
class="header-section-number">5.3.2</span> Return Type
(authenticate)</h3>
<p>Nothing (void).</p>
<h3 data-number="5.3.3"
id="reference-authenticate"><span
class="header-section-number">5.3.3</span> Reference
(authenticate)</h3>
<div class="sourceCode" id="cb49"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb49-1"><a href="#cb49-1" aria-hidden="true" tabindex="-1"></a><span class="kw">async</span> <span class="kw">function</span> <span class="fu">authenticate</span> (IAuthenticateOptions)<span class="op">:</span> <span class="bu">Promise</span><span class="op"><</span>IMrsLoginResult<span class="op">></span> {</span>
<span id="cb49-2"><a href="#cb49-2" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb49-3"><a href="#cb49-3" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb49-4"><a href="#cb49-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb49-5"><a href="#cb49-5" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IAuthenticateOptions {</span>
<span id="cb49-6"><a href="#cb49-6" aria-hidden="true" tabindex="-1"></a> username<span class="op">:</span> <span class="dt">string</span></span>
<span id="cb49-7"><a href="#cb49-7" aria-hidden="true" tabindex="-1"></a> password<span class="op">:</span> <span class="dt">string</span></span>
<span id="cb49-8"><a href="#cb49-8" aria-hidden="true" tabindex="-1"></a> app<span class="op">:</span> <span class="dt">string</span></span>
<span id="cb49-9"><a href="#cb49-9" aria-hidden="true" tabindex="-1"></a> vendor<span class="op">?:</span> <span class="dt">string</span></span>
<span id="cb49-10"><a href="#cb49-10" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb49-11"><a href="#cb49-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb49-12"><a href="#cb49-12" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IMrsLoginResult {</span>
<span id="cb49-13"><a href="#cb49-13" aria-hidden="true" tabindex="-1"></a> authApp<span class="op">?:</span> <span class="dt">string</span></span>
<span id="cb49-14"><a href="#cb49-14" aria-hidden="true" tabindex="-1"></a> jwt<span class="op">?:</span> <span class="dt">string</span></span>
<span id="cb49-15"><a href="#cb49-15" aria-hidden="true" tabindex="-1"></a> errorCode<span class="op">?:</span> <span class="dt">number</span></span>
<span id="cb49-16"><a href="#cb49-16" aria-hidden="true" tabindex="-1"></a> errorMessage<span class="op">?:</span> <span class="dt">string</span></span>
<span id="cb49-17"><a href="#cb49-17" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h3 data-number="5.3.4" id="example-authenticate"><span
class="header-section-number">5.3.4</span> Example
(authenticate)</h3>
<div class="sourceCode" id="cb50"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb50-1"><a href="#cb50-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">'./myService.mrs.sdk/myService'</span><span class="op">;</span></span>
<span id="cb50-2"><a href="#cb50-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb50-3"><a href="#cb50-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()<span class="op">;</span></span>
<span id="cb50-4"><a href="#cb50-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb50-5"><a href="#cb50-5" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="fu">authenticate</span>({ username<span class="op">:</span> <span class="st">'foo'</span><span class="op">,</span> password<span class="op">:</span> <span class="st">'bar'</span><span class="op">,</span> app<span class="op">:</span> <span class="st">'baz'</span> })<span class="op">;</span></span>
<span id="cb50-6"><a href="#cb50-6" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="fu">authenticate</span>({ username<span class="op">:</span> <span class="st">'foo'</span><span class="op">,</span> password<span class="op">:</span> <span class="st">'bar'</span><span class="op">,</span> app<span class="op">:</span> <span class="st">'baz'</span><span class="op">,</span> vendor<span class="op">:</span> <span class="st">"0x30000000000000000000000000000000"</span> })<span class="op">;</span></span></code></pre></div>
<h2 data-number="5.4"
id="service-deauthenticate-ts"><span
class="header-section-number">5.4</span>
Service.deauthenticate</h2>
<p><code>deauthenticate</code> is used for logging out a
user from a given REST service.</p>
<h3 data-number="5.4.1"
id="return-type-deauthenticate"><span
class="header-section-number">5.4.1</span> Return Type
(deauthenticate)</h3>
<p>Nothing (void).</p>
<h4 data-number="5.4.1.1"
id="reference-deauthenticate"><span
class="header-section-number">5.4.1.1</span> Reference
(deauthenticate)</h4>
<div class="sourceCode" id="cb51"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb51-1"><a href="#cb51-1" aria-hidden="true" tabindex="-1"></a><span class="kw">async</span> <span class="kw">function</span> <span class="fu">deauthenticate</span> ()<span class="op">:</span> <span class="bu">Promise</span><span class="op"><</span><span class="dt">void</span><span class="op">></span> {</span>
<span id="cb51-2"><a href="#cb51-2" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb51-3"><a href="#cb51-3" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h3 data-number="5.4.2"
id="example-deauthenticate"><span
class="header-section-number">5.4.2</span> Example
(deauthenticate)</h3>
<div class="sourceCode" id="cb52"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb52-1"><a href="#cb52-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">'./myService.mrs.sdk/myService'</span><span class="op">;</span></span>
<span id="cb52-2"><a href="#cb52-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb52-3"><a href="#cb52-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()<span class="op">;</span></span>
<span id="cb52-4"><a href="#cb52-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb52-5"><a href="#cb52-5" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="fu">deauthenticate</span>()<span class="op">;</span></span></code></pre></div>
<h2 data-number="5.5" id="view-create-ts"><span
class="header-section-number">5.5</span> View.create
</h2>
<p><code>create</code> is used to add a REST Document to
a given REST View. The document is represented as a
plain TypeScript/JavaScript object or, alternatively, as
an instance of a particular class that encapsulates the
data required to create a new document. To insert
multiple documents, see
<code>createMany</code>[#createmany].</p>
<h3 data-number="5.5.1" id="options-create"><span
class="header-section-number">5.5.1</span> Options
(create)</h3>
<table>
<caption>REST View Options (create)</caption>
<colgroup>
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 70%" />
</colgroup>
<thead>
<tr class="header">
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>data</td>
<td>object</td>
<td>Yes</td>
<td>Object containing the mapping between column names
and values for the REST Document to be created.</td>
</tr>
</tbody>
</table>
<h3 data-number="5.5.2" id="return-type-create"><span
class="header-section-number">5.5.2</span> Return Type
(create)</h3>
<p>A JSON object representing the created REST
Documents.</p>
<h3 data-number="5.5.3" id="reference-create"><span
class="header-section-number">5.5.3</span> Reference
(create)</h3>
<div class="sourceCode" id="cb53"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb53-1"><a href="#cb53-1" aria-hidden="true" tabindex="-1"></a><span class="kw">async</span> <span class="kw">function</span> <span class="fu">create</span> (args<span class="op">:</span> ICreateOptions<span class="op"><</span>Type<span class="op">></span>)<span class="op">:</span> <span class="bu">Promise</span><span class="op"><</span>Type<span class="op">></span> {</span>
<span id="cb53-2"><a href="#cb53-2" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb53-3"><a href="#cb53-3" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb53-4"><a href="#cb53-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb53-5"><a href="#cb53-5" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> ICreateOptions<span class="op"><</span>Type<span class="op">></span> {</span>
<span id="cb53-6"><a href="#cb53-6" aria-hidden="true" tabindex="-1"></a> data<span class="op">:</span> Type</span>
<span id="cb53-7"><a href="#cb53-7" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h3 data-number="5.5.4" id="example-create"><span
class="header-section-number">5.5.4</span> Example
(create)</h3>
<div class="sourceCode" id="cb54"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb54-1"><a href="#cb54-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> <span class="im">type</span> { IMyServiceMrsNotesNote } <span class="im">from</span> <span class="st">'/path/to/sdk/myService'</span><span class="op">;</span></span>
<span id="cb54-2"><a href="#cb54-2" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">'./myService.mrs.sdk/myService'</span><span class="op">;</span></span>
<span id="cb54-3"><a href="#cb54-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb54-4"><a href="#cb54-4" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()<span class="op">;</span></span>
<span id="cb54-5"><a href="#cb54-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb54-6"><a href="#cb54-6" aria-hidden="true" tabindex="-1"></a><span class="co">// using a plain object</span></span>
<span id="cb54-7"><a href="#cb54-7" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">create</span>({ data<span class="op">:</span> { title<span class="op">:</span> <span class="st">'foo'</span> } })<span class="op">;</span></span>
<span id="cb54-8"><a href="#cb54-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb54-9"><a href="#cb54-9" aria-hidden="true" tabindex="-1"></a><span class="co">// using a custom class instance</span></span>
<span id="cb54-10"><a href="#cb54-10" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Note <span class="kw">implements</span> IMyServiceMrsNotesNote {</span>
<span id="cb54-11"><a href="#cb54-11" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb54-12"><a href="#cb54-12" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb54-13"><a href="#cb54-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb54-14"><a href="#cb54-14" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> note <span class="op">=</span> <span class="kw">new</span> <span class="fu">Note</span>()<span class="op">;</span></span>
<span id="cb54-15"><a href="#cb54-15" aria-hidden="true" tabindex="-1"></a>note<span class="op">.</span><span class="at">title</span> <span class="op">=</span> <span class="st">'foo'</span><span class="op">;</span></span>
<span id="cb54-16"><a href="#cb54-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb54-17"><a href="#cb54-17" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">create</span>({ data<span class="op">:</span> note })<span class="op">;</span></span></code></pre></div>
<h2 data-number="5.6" id="view-createmany-ts"><span
class="header-section-number">5.6</span> View.createMany
</h2>
<p><code>createMany</code> adds one or more REST
Documents to a given REST View. The documents are
represented as plain TypeScript/JavaScript objects, or
alternatively, as instances of a particular class that
encapsulates the data required to create them.</p>
<h3 data-number="5.6.1" id="options-createmany"><span
class="header-section-number">5.6.1</span> Options
(createMany)</h3>
<table>
<caption>REST View Options (createMany)</caption>
<colgroup>
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 70%" />
</colgroup>
<thead>
<tr class="header">
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>data</td>
<td>object</td>
<td>Yes</td>
<td>Array of objects containing the mapping between
column names and values for the REST Documents to be
created.</td>
</tr>
</tbody>
</table>
<h3 data-number="5.6.2"
id="return-type-createmany"><span
class="header-section-number">5.6.2</span> Return Type
(createMany)</h3>
<p>An array of JSON objects representing the created
REST Documents.</p>
<h3 data-number="5.6.3" id="reference-createmany"><span
class="header-section-number">5.6.3</span> Reference
(createMany)</h3>
<div class="sourceCode" id="cb55"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb55-1"><a href="#cb55-1" aria-hidden="true" tabindex="-1"></a><span class="kw">async</span> <span class="kw">function</span> <span class="fu">createMany</span> (args<span class="op">:</span> ICreateOptions<span class="op"><</span>Type[]<span class="op">></span>)<span class="op">:</span> <span class="bu">Promise</span><span class="op"><</span>Type[]<span class="op">></span> {</span>
<span id="cb55-2"><a href="#cb55-2" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb55-3"><a href="#cb55-3" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb55-4"><a href="#cb55-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb55-5"><a href="#cb55-5" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> ICreateOptions<span class="op"><</span>Type<span class="op">></span> {</span>
<span id="cb55-6"><a href="#cb55-6" aria-hidden="true" tabindex="-1"></a> data<span class="op">:</span> Type</span>
<span id="cb55-7"><a href="#cb55-7" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h3 data-number="5.6.4" id="example-createmany"><span
class="header-section-number">5.6.4</span> Example
(createMany)</h3>
<div class="sourceCode" id="cb56"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb56-1"><a href="#cb56-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> <span class="im">type</span> { IMyServiceMrsNotesNote } <span class="im">from</span> <span class="st">'/path/to/sdk/myService'</span><span class="op">;</span></span>
<span id="cb56-2"><a href="#cb56-2" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">'./myService.mrs.sdk/myService'</span><span class="op">;</span></span>
<span id="cb56-3"><a href="#cb56-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb56-4"><a href="#cb56-4" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()<span class="op">;</span></span>
<span id="cb56-5"><a href="#cb56-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb56-6"><a href="#cb56-6" aria-hidden="true" tabindex="-1"></a><span class="co">// using a plain object</span></span>
<span id="cb56-7"><a href="#cb56-7" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">createMany</span>({ data<span class="op">:</span> [{ title<span class="op">:</span> <span class="st">'foo'</span> }<span class="op">,</span> { title<span class="op">:</span> <span class="st">'bar'</span> }] })<span class="op">;</span></span>
<span id="cb56-8"><a href="#cb56-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb56-9"><a href="#cb56-9" aria-hidden="true" tabindex="-1"></a><span class="co">// using a custom class</span></span>
<span id="cb56-10"><a href="#cb56-10" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Note <span class="kw">implements</span> IMyServiceMrsNotesNote {</span>
<span id="cb56-11"><a href="#cb56-11" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb56-12"><a href="#cb56-12" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb56-13"><a href="#cb56-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb56-14"><a href="#cb56-14" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> note1 <span class="op">=</span> <span class="kw">new</span> <span class="fu">Note</span>()<span class="op">;</span></span>
<span id="cb56-15"><a href="#cb56-15" aria-hidden="true" tabindex="-1"></a>note1<span class="op">.</span><span class="at">title</span> <span class="op">=</span> <span class="st">'foo'</span><span class="op">;</span></span>
<span id="cb56-16"><a href="#cb56-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb56-17"><a href="#cb56-17" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> note2 <span class="op">=</span> <span class="kw">new</span> <span class="fu">Note</span>({ <span class="co">/* */</span> })<span class="op">;</span></span>
<span id="cb56-18"><a href="#cb56-18" aria-hidden="true" tabindex="-1"></a>note1<span class="op">.</span><span class="at">title</span> <span class="op">=</span> <span class="st">'bar'</span><span class="op">;</span></span>
<span id="cb56-19"><a href="#cb56-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb56-20"><a href="#cb56-20" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">createMany</span>({ data<span class="op">:</span> [note1<span class="op">,</span> note2] })<span class="op">;</span></span></code></pre></div>
<h2 data-number="5.7" id="view-find-ts"><span
class="header-section-number">5.7</span> View.find
</h2>
<p><code>find</code> is used to query the subset of REST
<a href="#rest-document">Documents</a> (that optionally
match a given filter) in the first page.</p>
<h3 data-number="5.7.1" id="options-find"><span
class="header-section-number">5.7.1</span> Options
(find)</h3>
<table>
<caption>REST View Options (find)</caption>
<colgroup>
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 70%" />
</colgroup>
<thead>
<tr class="header">
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>cursor</td>
<td>object</td>
<td>No</td>
<td>Retrieve documents using unique and sequential
fields as cursor.</td>
</tr>
<tr class="even">
<td>orderBy</td>
<td>object</td>
<td>No</td>
<td>Determines the sort order of specific fields.</td>
</tr>
<tr class="odd">
<td>select</td>
<td>object</td>
<td>No</td>
<td>Specifies which properties to include in the
returned object.</td>
</tr>
<tr class="even">
<td>skip</td>
<td>number</td>
<td>No</td>
<td>How many documents to skip before returning one of
the matches.</td>
</tr>
<tr class="odd">
<td>where</td>
<td>object</td>
<td>No</td>
<td>Filtering conditions that apply to specific
fields.</td>
</tr>
<tr class="even">
<td>take</td>
<td>number</td>
<td>No</td>
<td>The maximum size of the page.</td>
</tr>
<tr class="odd">
<td>readOwnWrites</td>
<td>boolean</td>
<td>No</td>
<td>Ensures read consistency for a cluster of
servers.</td>
</tr>
</tbody>
</table>
<h3 data-number="5.7.2" id="return-type-find"><span
class="header-section-number">5.7.2</span> Return Type
(find)</h3>
<p>An array of JSON objects representing the first page
of REST Documents matching the filter. If there are more
matching REST Documents, the array contains an
additional <code>hasMore</code> truthy property and a
<code>next()</code> async function that automatically
retrieves the subsequent page of REST Documents.</p>
<h3 data-number="5.7.3" id="reference-find"><span
class="header-section-number">5.7.3</span> Reference
(find)</h3>
<div class="sourceCode" id="cb57"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb57-1"><a href="#cb57-1" aria-hidden="true" tabindex="-1"></a><span class="kw">async</span> <span class="kw">function</span> <span class="fu">find</span> ({ cursor<span class="op">,</span> orderBy<span class="op">,</span> select<span class="op">,</span> skip<span class="op">,</span> take<span class="op">,</span> where }<span class="op">:</span> IFindManyOptions<span class="op"><</span>Item<span class="op">,</span> Filterable<span class="op">,</span> Cursors<span class="op">></span>)<span class="op">:</span> <span class="bu">Promise</span><span class="op"><</span>PaginatedList<span class="op"><</span>Item<span class="op">>></span> {</span>
<span id="cb57-2"><a href="#cb57-2" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb57-3"><a href="#cb57-3" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb57-4"><a href="#cb57-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb57-5"><a href="#cb57-5" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IFindManyOptions<span class="op"><</span>Item<span class="op">,</span> Filterable<span class="op">,</span> Iterable<span class="op">></span> {</span>
<span id="cb57-6"><a href="#cb57-6" aria-hidden="true" tabindex="-1"></a> cursor<span class="op">?:</span> Cursor<span class="op"><</span>Iterable<span class="op">>;</span></span>
<span id="cb57-7"><a href="#cb57-7" aria-hidden="true" tabindex="-1"></a> orderBy<span class="op">?:</span> ColumnOrder<span class="op"><</span>Filterable<span class="op">>;</span></span>
<span id="cb57-8"><a href="#cb57-8" aria-hidden="true" tabindex="-1"></a> select<span class="op">?:</span> BooleanFieldMapSelect<span class="op"><</span>Item<span class="op">></span> <span class="op">|</span> FieldNameSelect<span class="op"><</span>Item<span class="op">>;</span></span>
<span id="cb57-9"><a href="#cb57-9" aria-hidden="true" tabindex="-1"></a> skip<span class="op">?:</span> <span class="dt">number</span><span class="op">;</span></span>
<span id="cb57-10"><a href="#cb57-10" aria-hidden="true" tabindex="-1"></a> take<span class="op">?:</span> <span class="dt">number</span><span class="op">;</span></span>
<span id="cb57-11"><a href="#cb57-11" aria-hidden="true" tabindex="-1"></a> where<span class="op">?:</span> DataFilter<span class="op"><</span>Filterable<span class="op">>;</span></span>
<span id="cb57-12"><a href="#cb57-12" aria-hidden="true" tabindex="-1"></a> readOwnWrites<span class="op">?:</span> <span class="dt">boolean</span><span class="op">;</span></span>
<span id="cb57-13"><a href="#cb57-13" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb57-14"><a href="#cb57-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb57-15"><a href="#cb57-15" aria-hidden="true" tabindex="-1"></a><span class="im">export</span> <span class="kw">interface</span> IExhaustedList<span class="op"><</span>T<span class="op">></span> <span class="kw">extends</span> <span class="bu">Array</span><span class="op"><</span>T<span class="op">></span> {</span>
<span id="cb57-16"><a href="#cb57-16" aria-hidden="true" tabindex="-1"></a> hasMore<span class="op">:</span> <span class="kw">false</span><span class="op">,</span></span>
<span id="cb57-17"><a href="#cb57-17" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb57-18"><a href="#cb57-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb57-19"><a href="#cb57-19" aria-hidden="true" tabindex="-1"></a><span class="im">export</span> <span class="kw">interface</span> INotExhaustedList<span class="op"><</span>T<span class="op">></span> <span class="kw">extends</span> <span class="bu">Array</span><span class="op"><</span>T<span class="op">></span> {</span>
<span id="cb57-20"><a href="#cb57-20" aria-hidden="true" tabindex="-1"></a> hasMore<span class="op">:</span> <span class="kw">true</span><span class="op">,</span></span>
<span id="cb57-21"><a href="#cb57-21" aria-hidden="true" tabindex="-1"></a> <span class="fu">next</span>()<span class="op">:</span> <span class="bu">Promise</span><span class="op"><</span>PaginatedList<span class="op"><</span>T<span class="op">>>,</span></span>
<span id="cb57-22"><a href="#cb57-22" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb57-23"><a href="#cb57-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb57-24"><a href="#cb57-24" aria-hidden="true" tabindex="-1"></a><span class="im">export type</span> PaginatedList<span class="op"><</span>T<span class="op">></span> <span class="op">=</span> IExhaustedList<span class="op"><</span>T<span class="op">></span> <span class="op">|</span> INotExhaustedList<span class="op"><</span>T<span class="op">>;</span></span></code></pre></div>
<h3 data-number="5.7.4" id="example-find"><span
class="header-section-number">5.7.4</span> Example
(find)</h3>
<div class="sourceCode" id="cb58"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb58-1"><a href="#cb58-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">'./myService.mrs.sdk/myService'</span><span class="op">;</span></span>
<span id="cb58-2"><a href="#cb58-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb58-3"><a href="#cb58-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()<span class="op">;</span></span>
<span id="cb58-4"><a href="#cb58-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb58-5"><a href="#cb58-5" aria-hidden="true" tabindex="-1"></a><span class="co">// get all notes of the first page</span></span>
<span id="cb58-6"><a href="#cb58-6" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">find</span>()<span class="op">;</span></span>
<span id="cb58-7"><a href="#cb58-7" aria-hidden="true" tabindex="-1"></a><span class="co">// get the first 3 notes</span></span>
<span id="cb58-8"><a href="#cb58-8" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">find</span>({ take<span class="op">:</span> <span class="dv">3</span> })<span class="op">;</span></span>
<span id="cb58-9"><a href="#cb58-9" aria-hidden="true" tabindex="-1"></a><span class="co">// get notes of then first page where the id is greater than 10</span></span>
<span id="cb58-10"><a href="#cb58-10" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">find</span>({ where<span class="op">:</span> { id<span class="op">:</span> { $gt<span class="op">:</span> <span class="dv">10</span> } } })<span class="op">;</span></span>
<span id="cb58-11"><a href="#cb58-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb58-12"><a href="#cb58-12" aria-hidden="true" tabindex="-1"></a><span class="co">// iterate over the pages</span></span>
<span id="cb58-13"><a href="#cb58-13" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> notes <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">find</span>()<span class="op">;</span></span>
<span id="cb58-14"><a href="#cb58-14" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> (notes<span class="op">.</span><span class="at">hasMore</span>) {</span>
<span id="cb58-15"><a href="#cb58-15" aria-hidden="true" tabindex="-1"></a> <span class="co">// automatically get the next page (if there is one)</span></span>
<span id="cb58-16"><a href="#cb58-16" aria-hidden="true" tabindex="-1"></a> notes <span class="op">=</span> <span class="cf">await</span> notes<span class="op">.</span><span class="fu">next</span>()<span class="op">;</span></span>
<span id="cb58-17"><a href="#cb58-17" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h2 data-number="5.8" id="view-findfirst-ts"><span
class="header-section-number">5.8</span> View.findFirst
</h2>
<p><code>findFirst</code> is used to query the first
REST Document (<strong>in no specific order</strong>)
that matches a given optional filter.</p>
<h3 data-number="5.8.1" id="options-findfirst"><span
class="header-section-number">5.8.1</span> Options
(findFirst)</h3>
<table>
<caption>REST View Options (findFirst)</caption>
<colgroup>
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 70%" />
</colgroup>
<thead>
<tr class="header">
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>where</td>
<td>object</td>
<td>No</td>
<td>Filtering conditions that apply to specific
fields.</td>
</tr>
<tr class="even">
<td>select</td>
<td>object</td>
<td>No</td>
<td>Specifies which properties to include in the
returned object.</td>
</tr>
<tr class="odd">
<td>skip</td>
<td>number</td>
<td>No</td>
<td>Specifies how many documents to skip before
returning one of the matches.</td>
</tr>
<tr class="even">
<td>readOwnWrites</td>
<td>boolean</td>
<td>No</td>
<td>Ensures read consistency for a cluster of
servers.</td>
</tr>
</tbody>
</table>
<h3 data-number="5.8.2" id="return-type-findfirst"><span
class="header-section-number">5.8.2</span> Return Type
(findFirst)</h3>
<p>A JSON object representing the first REST <a
href="#rest-document">Document</a> that matches the
filter or <code>undefined</code> when the document was
not found.</p>
<h3 data-number="5.8.3" id="reference-findfirst"><span
class="header-section-number">5.8.3</span> Reference
(findFirst)</h3>
<div class="sourceCode" id="cb59"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb59-1"><a href="#cb59-1" aria-hidden="true" tabindex="-1"></a><span class="kw">async</span> <span class="kw">function</span> <span class="fu">findFirst</span> (args<span class="op">?:</span> IFindOptions<span class="op"><</span>Selectable<span class="op">,</span> Filterable<span class="op">></span>)<span class="op">:</span> <span class="bu">Promise</span><span class="op"><</span>Selectable <span class="op">|</span> <span class="dt">undefined</span><span class="op">></span> {</span>
<span id="cb59-2"><a href="#cb59-2" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb59-3"><a href="#cb59-3" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb59-4"><a href="#cb59-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb59-5"><a href="#cb59-5" aria-hidden="true" tabindex="-1"></a><span class="im">export</span> <span class="kw">interface</span> IFindOptions<span class="op"><</span>Selectable<span class="op">,</span> Filterable<span class="op">></span> {</span>
<span id="cb59-6"><a href="#cb59-6" aria-hidden="true" tabindex="-1"></a> orderBy<span class="op">?:</span> ColumnOrder<span class="op"><</span>Filterable<span class="op">>;</span></span>
<span id="cb59-7"><a href="#cb59-7" aria-hidden="true" tabindex="-1"></a> select<span class="op">?:</span> BooleanFieldMapSelect<span class="op"><</span>Selectable<span class="op">></span> <span class="op">|</span> FieldNameSelect<span class="op"><</span>Selectable<span class="op">>;</span></span>
<span id="cb59-8"><a href="#cb59-8" aria-hidden="true" tabindex="-1"></a> skip<span class="op">?:</span> <span class="dt">number</span><span class="op">;</span></span>
<span id="cb59-9"><a href="#cb59-9" aria-hidden="true" tabindex="-1"></a> where<span class="op">?:</span> DataFilter<span class="op"><</span>Filterable<span class="op">>;</span></span>
<span id="cb59-10"><a href="#cb59-10" aria-hidden="true" tabindex="-1"></a> readOwnWrites<span class="op">?:</span> <span class="dt">boolean</span><span class="op">;</span></span>
<span id="cb59-11"><a href="#cb59-11" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h3 data-number="5.8.4" id="example-findfirst"><span
class="header-section-number">5.8.4</span> Example
(findFirst)</h3>
<div class="sourceCode" id="cb60"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb60-1"><a href="#cb60-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">'./myService.mrs.sdk/myService'</span><span class="op">;</span></span>
<span id="cb60-2"><a href="#cb60-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb60-3"><a href="#cb60-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()<span class="op">;</span></span>
<span id="cb60-4"><a href="#cb60-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb60-5"><a href="#cb60-5" aria-hidden="true" tabindex="-1"></a><span class="co">// get the first note, without any filter</span></span>
<span id="cb60-6"><a href="#cb60-6" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">findFirst</span>()<span class="op">;</span></span>
<span id="cb60-7"><a href="#cb60-7" aria-hidden="true" tabindex="-1"></a><span class="co">// get the last note, without any filter</span></span>
<span id="cb60-8"><a href="#cb60-8" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">findFirst</span>({ orderBy<span class="op">:</span> { id<span class="op">:</span> <span class="st">"DESC"</span> } })<span class="op">;</span></span>
<span id="cb60-9"><a href="#cb60-9" aria-hidden="true" tabindex="-1"></a><span class="co">// get the second note, without any filter</span></span>
<span id="cb60-10"><a href="#cb60-10" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">findFirst</span>({ skip<span class="op">:</span> <span class="dv">1</span> })<span class="op">;</span></span>
<span id="cb60-11"><a href="#cb60-11" aria-hidden="true" tabindex="-1"></a><span class="co">// get the title and shared fields of the second note</span></span>
<span id="cb60-12"><a href="#cb60-12" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">findFirst</span>({ select<span class="op">:</span> { title<span class="op">:</span> <span class="kw">true</span><span class="op">,</span> shared<span class="op">:</span> <span class="kw">true</span> }<span class="op">,</span> skip<span class="op">:</span> <span class="dv">1</span> })<span class="op">;</span></span>
<span id="cb60-13"><a href="#cb60-13" aria-hidden="true" tabindex="-1"></a><span class="co">// get the title and shared fields of the first note</span></span>
<span id="cb60-14"><a href="#cb60-14" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">findFirst</span>({ select<span class="op">:</span> [<span class="st">"title"</span><span class="op">,</span> <span class="st">"shared"</span>] })<span class="op">;</span></span>
<span id="cb60-15"><a href="#cb60-15" aria-hidden="true" tabindex="-1"></a><span class="co">// get the first shared note</span></span>
<span id="cb60-16"><a href="#cb60-16" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">findFirst</span>({ where<span class="op">:</span> { shared<span class="op">:</span> <span class="kw">true</span> } })<span class="op">;</span></span>
<span id="cb60-17"><a href="#cb60-17" aria-hidden="true" tabindex="-1"></a><span class="co">// get the first note whose title includes the string "foo"</span></span>
<span id="cb60-18"><a href="#cb60-18" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">findFirst</span>({ where<span class="op">:</span> { title<span class="op">:</span> { $like<span class="op">:</span> <span class="st">"%foo%"</span> } } })<span class="op">;</span></span></code></pre></div>
<h2 data-number="5.9" id="view-findunique-ts"><span
class="header-section-number">5.9</span> View.findUnique
</h2>
<p><code>findUnique</code> is used to query a single,
uniquely identified REST Document by:</p>
<ul>
<li>Primary key column(s)</li>
<li>Unique column(s)</li>
</ul>
<p>If no document was found matching the given
<code>where</code> condition, <code>undefined</code> is
returned. To have an exception thrown in this case, see
<a href="#finduniqueorthrow">findUniqueOrThrow</a>.</p>
<h3 data-number="5.9.1" id="options-findunique"><span
class="header-section-number">5.9.1</span> Options
(findUnique)</h3>
<table>
<caption>REST View Options (findUnique)</caption>
<colgroup>
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 70%" />
</colgroup>
<thead>
<tr class="header">
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>where</td>
<td>object</td>
<td>Yes</td>
<td>Wraps all unique columns so that individual
documents can be selected.</td>
</tr>
<tr class="even">
<td>select</td>
<td>object</td>
<td>No</td>
<td>Specifies which properties to include in the
returned object.</td>
</tr>
<tr class="odd">
<td>readOwnWrites</td>
<td>boolean</td>
<td>No</td>
<td>Ensures read consistency for a cluster of
servers.</td>
</tr>
</tbody>
</table>
<h3 data-number="5.9.2"
id="return-type-findunique"><span
class="header-section-number">5.9.2</span> Return Type
(findUnique)</h3>
<p>A JSON object representing the REST <a
href="#rest-document">Document</a> that matches the
filter or <code>undefined</code> when the document was
not found.</p>
<h3 data-number="5.9.3" id="reference-findunique"><span
class="header-section-number">5.9.3</span> Reference
(findUnique)</h3>
<div class="sourceCode" id="cb61"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb61-1"><a href="#cb61-1" aria-hidden="true" tabindex="-1"></a><span class="kw">async</span> <span class="kw">function</span> <span class="fu">findUnique</span> (args<span class="op">?:</span> IFindUniqueOptions<span class="op"><</span>Selectable<span class="op">,</span> Filterable<span class="op">></span>)<span class="op">:</span> <span class="bu">Promise</span><span class="op"><</span>Selectable <span class="op">|</span> <span class="dt">undefined</span><span class="op">></span> {</span>
<span id="cb61-2"><a href="#cb61-2" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb61-3"><a href="#cb61-3" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb61-4"><a href="#cb61-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb61-5"><a href="#cb61-5" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IFindUniqueOptions<span class="op"><</span>Selectable<span class="op">,</span> Filterable<span class="op">></span> {</span>
<span id="cb61-6"><a href="#cb61-6" aria-hidden="true" tabindex="-1"></a> select<span class="op">?:</span> BooleanFieldMapSelect<span class="op"><</span>Selectable<span class="op">></span> <span class="op">|</span> FieldNameSelect<span class="op"><</span>Selectable<span class="op">>;</span></span>
<span id="cb61-7"><a href="#cb61-7" aria-hidden="true" tabindex="-1"></a> where<span class="op">?:</span> DataFilter<span class="op"><</span>Filterable<span class="op">>;</span></span>
<span id="cb61-8"><a href="#cb61-8" aria-hidden="true" tabindex="-1"></a> readOwnWrites<span class="op">?:</span> <span class="dt">boolean</span><span class="op">;</span></span>
<span id="cb61-9"><a href="#cb61-9" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h3 data-number="5.9.4" id="example-findunique"><span
class="header-section-number">5.9.4</span> Example
(findUnique)</h3>
<div class="sourceCode" id="cb62"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb62-1"><a href="#cb62-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">'./myService.mrs.sdk/myService'</span><span class="op">;</span></span>
<span id="cb62-2"><a href="#cb62-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb62-3"><a href="#cb62-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()<span class="op">;</span></span>
<span id="cb62-4"><a href="#cb62-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb62-5"><a href="#cb62-5" aria-hidden="true" tabindex="-1"></a><span class="co">// Get the note with id 4.</span></span>
<span id="cb62-6"><a href="#cb62-6" aria-hidden="true" tabindex="-1"></a><span class="co">// using implicit equality</span></span>
<span id="cb62-7"><a href="#cb62-7" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">findUnique</span>({ where<span class="op">:</span> { id<span class="op">:</span> <span class="dv">4</span> } })<span class="op">;</span></span>
<span id="cb62-8"><a href="#cb62-8" aria-hidden="true" tabindex="-1"></a><span class="co">// or using explicit equality</span></span>
<span id="cb62-9"><a href="#cb62-9" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">findUnique</span>({ where<span class="op">:</span> { id<span class="op">:</span> { $eq<span class="op">:</span> <span class="dv">4</span> } } })<span class="op">;</span></span></code></pre></div>
<h2 data-number="5.10"
id="view-finduniqueorthrow-ts"><span
class="header-section-number">5.10</span>
View.findUniqueOrThrow</h2>
<p><code>findUniqueOrThrow</code> retrieves a single
REST <a href="#rest-document">Document</a> in the same
way as <a href="#findunique">findUnique</a>. However, if
the query does not find a document, it throws a
<code>NotFoundError</code>.</p>
<p><code>findUniqueOrThrow</code> differs from
<code>findUnique</code> as follows:</p>
<ul>
<li>Its return type is non-nullable. For example,
myService.mrsNotes.note.findUnique() can return a note
or undefined, but
myService.mrsNotes.note.findUniqueOrThrow() always
returns a note.</li>
</ul>
<h2 data-number="5.11" id="view-delete-ts"><span
class="header-section-number">5.11</span> View.delete
</h2>
<p><code>delete</code> is used to delete the first REST
Document that matches a given required filter.</p>
<h3 data-number="5.11.1" id="options-delete"><span
class="header-section-number">5.11.1</span> Options
(delete)</h3>
<table>
<caption>REST View Options (delete)</caption>
<colgroup>
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 70%" />
</colgroup>
<thead>
<tr class="header">
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>where</td>
<td>object</td>
<td>Yes</td>
<td>Filtering conditions that apply to specific
fields.</td>
</tr>
<tr class="even">
<td>readOwnWrites</td>
<td>boolean</td>
<td>No</td>
<td>Ensures read consistency for a cluster of
servers.</td>
</tr>
</tbody>
</table>
<h3 data-number="5.11.2" id="return-type-delete"><span
class="header-section-number">5.11.2</span> Return Type
(delete)</h3>
<p><code>true</code> if the document was deleted
successfully or <code>false</code> otherwise.</p>
<h3 data-number="5.11.3" id="reference-delete"><span
class="header-section-number">5.11.3</span> Reference
(delete)</h3>
<div class="sourceCode" id="cb63"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb63-1"><a href="#cb63-1" aria-hidden="true" tabindex="-1"></a><span class="kw">async</span> <span class="kw">function</span> <span class="fu">delete</span> (args<span class="op">:</span> IDeleteOptions<span class="op"><</span>IMyServiceMrsNotesUserParams<span class="op">></span>)<span class="op">:</span> <span class="bu">Promise</span><span class="op"><</span>IMrsDeleteResult<span class="op">></span> {</span>
<span id="cb63-2"><a href="#cb63-2" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb63-3"><a href="#cb63-3" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb63-4"><a href="#cb63-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb63-5"><a href="#cb63-5" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IDeleteOptions<span class="op"><</span>Filterable<span class="op">></span> {</span>
<span id="cb63-6"><a href="#cb63-6" aria-hidden="true" tabindex="-1"></a> where<span class="op">?:</span> DataFilter<span class="op"><</span>Filterable<span class="op">>;</span></span>
<span id="cb63-7"><a href="#cb63-7" aria-hidden="true" tabindex="-1"></a> readOwnWrites<span class="op">?:</span> <span class="dt">boolean</span><span class="op">;</span></span>
<span id="cb63-8"><a href="#cb63-8" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb63-9"><a href="#cb63-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb63-10"><a href="#cb63-10" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IMrsDeleteResult {</span>
<span id="cb63-11"><a href="#cb63-11" aria-hidden="true" tabindex="-1"></a> itemsDeleted<span class="op">:</span> <span class="dv">1</span><span class="op">;</span></span>
<span id="cb63-12"><a href="#cb63-12" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h3 data-number="5.11.4" id="example-delete"><span
class="header-section-number">5.11.4</span> Example
(delete)</h3>
<div class="sourceCode" id="cb64"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb64-1"><a href="#cb64-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">'./myService.mrs.sdk/myService'</span><span class="op">;</span></span>
<span id="cb64-2"><a href="#cb64-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb64-3"><a href="#cb64-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()<span class="op">;</span></span>
<span id="cb64-4"><a href="#cb64-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb64-5"><a href="#cb64-5" aria-hidden="true" tabindex="-1"></a><span class="co">// delete the first note whose title includes the string "foo"</span></span>
<span id="cb64-6"><a href="#cb64-6" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">delete</span>({ where<span class="op">:</span> { title<span class="op">:</span> { $like<span class="op">:</span> <span class="st">"%foo%"</span> } } })<span class="op">;</span></span></code></pre></div>
<h2 data-number="5.12" id="view-deletemany-ts"><span
class="header-section-number">5.12</span>
View.deleteMany</h2>
<p><code>delete</code> is used to delete all REST
Documents that match a given filter.</p>
<h3 data-number="5.12.1" id="options-deletemany"><span
class="header-section-number">5.12.1</span> Options
(deleteMany)</h3>
<table>
<caption>REST View Options (deleteMany)</caption>
<colgroup>
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 70%" />
</colgroup>
<thead>
<tr class="header">
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>where</td>
<td>object</td>
<td>No</td>
<td>Filtering conditions that apply to specific
fields.</td>
</tr>
<tr class="even">
<td>readOwnWrites</td>
<td>boolean</td>
<td>No</td>
<td>Ensures read consistency for a cluster of
servers.</td>
</tr>
</tbody>
</table>
<h3 data-number="5.12.2"
id="return-type-deletemany"><span
class="header-section-number">5.12.2</span> Return Type
(deleteMany)</h3>
<p>The number of REST Documents that were deleted.</p>
<h3 data-number="5.12.3" id="reference-deletemany"><span
class="header-section-number">5.12.3</span> Reference
(deleteMany)</h3>
<div class="sourceCode" id="cb65"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb65-1"><a href="#cb65-1" aria-hidden="true" tabindex="-1"></a><span class="kw">async</span> <span class="kw">function</span> <span class="fu">deleteMany</span> (args<span class="op">:</span> IDeleteOptions<span class="op"><</span>IMyServiceMrsNotesUserParams<span class="op">></span>)<span class="op">:</span> <span class="bu">Promise</span><span class="op"><</span><span class="dt">number</span><span class="op">></span> {</span>
<span id="cb65-2"><a href="#cb65-2" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb65-3"><a href="#cb65-3" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb65-4"><a href="#cb65-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb65-5"><a href="#cb65-5" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IDeleteOptions<span class="op"><</span>Filterable<span class="op">></span> {</span>
<span id="cb65-6"><a href="#cb65-6" aria-hidden="true" tabindex="-1"></a> where<span class="op">?:</span> DataFilter<span class="op"><</span>Filterable<span class="op">>;</span></span>
<span id="cb65-7"><a href="#cb65-7" aria-hidden="true" tabindex="-1"></a> readOwnWrites<span class="op">:</span> <span class="dt">boolean</span><span class="op">;</span></span>
<span id="cb65-8"><a href="#cb65-8" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h4 data-number="5.12.3.1" id="example-deletemany"><span
class="header-section-number">5.12.3.1</span> Example
(deleteMany)</h4>
<div class="sourceCode" id="cb66"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb66-1"><a href="#cb66-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">'./myService.mrs.sdk/myService'</span><span class="op">;</span></span>
<span id="cb66-2"><a href="#cb66-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb66-3"><a href="#cb66-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()<span class="op">;</span></span>
<span id="cb66-4"><a href="#cb66-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb66-5"><a href="#cb66-5" aria-hidden="true" tabindex="-1"></a><span class="co">// delete all notes whose title includes the string "foo"</span></span>
<span id="cb66-6"><a href="#cb66-6" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">deleteMany</span>({ where<span class="op">:</span> { title<span class="op">:</span> { $like<span class="op">:</span> <span class="st">"%foo%"</span> } } })<span class="op">;</span></span>
<span id="cb66-7"><a href="#cb66-7" aria-hidden="true" tabindex="-1"></a><span class="co">// delete all shared notes</span></span>
<span id="cb66-8"><a href="#cb66-8" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">deleteMany</span>({ where<span class="op">:</span> { shared<span class="op">:</span> <span class="kw">true</span> } })<span class="op">;</span></span></code></pre></div>
<h2 data-number="5.13" id="view-update-ts"><span
class="header-section-number">5.13</span> View.update
</h2>
<p><code>update</code> is used to update a REST Document
with a given identifier or primary key.</p>
<h3 data-number="5.13.1" id="options-update"><span
class="header-section-number">5.13.1</span> Options
(update)</h3>
<table>
<caption>REST View Options (update)</caption>
<colgroup>
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 70%" />
</colgroup>
<thead>
<tr class="header">
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>data</td>
<td>object</td>
<td>Yes</td>
<td>Set of fields and corresponding values to
update.</td>
</tr>
</tbody>
</table>
<h3 data-number="5.13.2" id="return-type-update"><span
class="header-section-number">5.13.2</span> Return Type
(update)</h3>
<p>A JSON object representing the up-to-date REST <a
href="#rest-document">Document</a>.</p>
<h3 data-number="5.13.3" id="reference-update"><span
class="header-section-number">5.13.3</span> Reference
(update)</h3>
<div class="sourceCode" id="cb67"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb67-1"><a href="#cb67-1" aria-hidden="true" tabindex="-1"></a><span class="kw">async</span> <span class="kw">function</span> <span class="fu">update</span> (args<span class="op">:</span> IUpdateOptions<span class="op"><</span>UpdatableFields<span class="op">></span>)<span class="op">:</span> <span class="bu">Promise</span><span class="op"><</span>Data<span class="op">></span> {</span>
<span id="cb67-2"><a href="#cb67-2" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb67-3"><a href="#cb67-3" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb67-4"><a href="#cb67-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb67-5"><a href="#cb67-5" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> IUpdateOptions<span class="op"><</span>Type<span class="op">></span> <span class="op">=</span> ICreateOptions<span class="op"><</span>Type<span class="op">>;</span></span></code></pre></div>
<h3 data-number="5.13.4" id="example-update"><span
class="header-section-number">5.13.4</span> Example
(update)</h3>
<div class="sourceCode" id="cb68"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb68-1"><a href="#cb68-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> <span class="im">type</span> { IMyServiceMrsNotesNote } <span class="im">from</span> <span class="st">'/path/to/sdk/myService'</span><span class="op">;</span></span>
<span id="cb68-2"><a href="#cb68-2" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">'./myService.mrs.sdk/myService'</span><span class="op">;</span></span>
<span id="cb68-3"><a href="#cb68-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb68-4"><a href="#cb68-4" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()<span class="op">;</span></span>
<span id="cb68-5"><a href="#cb68-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb68-6"><a href="#cb68-6" aria-hidden="true" tabindex="-1"></a><span class="co">// update the note with id is 1 using a plain object</span></span>
<span id="cb68-7"><a href="#cb68-7" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">update</span>({ data<span class="op">:</span> { id<span class="op">:</span> <span class="dv">1</span><span class="op">,</span> title<span class="op">:</span> <span class="st">'bar'</span> } })<span class="op">;</span></span>
<span id="cb68-8"><a href="#cb68-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb68-9"><a href="#cb68-9" aria-hidden="true" tabindex="-1"></a><span class="co">// using a custom class instance</span></span>
<span id="cb68-10"><a href="#cb68-10" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Note <span class="kw">implements</span> IMyServiceMrsNotesNote {</span>
<span id="cb68-11"><a href="#cb68-11" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb68-12"><a href="#cb68-12" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb68-13"><a href="#cb68-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb68-14"><a href="#cb68-14" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> note <span class="op">=</span> <span class="kw">new</span> <span class="fu">Note</span>()<span class="op">;</span></span>
<span id="cb68-15"><a href="#cb68-15" aria-hidden="true" tabindex="-1"></a>note<span class="op">.</span><span class="at">id</span> <span class="op">=</span> <span class="dv">1</span></span>
<span id="cb68-16"><a href="#cb68-16" aria-hidden="true" tabindex="-1"></a>note<span class="op">.</span><span class="at">shared</span> <span class="op">=</span> <span class="kw">false</span><span class="op">;</span></span>
<span id="cb68-17"><a href="#cb68-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb68-18"><a href="#cb68-18" aria-hidden="true" tabindex="-1"></a><span class="co">// update the note with id 1</span></span>
<span id="cb68-19"><a href="#cb68-19" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">update</span>({ data<span class="op">:</span> note })<span class="op">;</span></span></code></pre></div>
<h2 data-number="5.14" id="view-updatemany-ts"><span
class="header-section-number">5.14</span>
View.updateMany</h2>
<p><code>updateMany</code> is used to update all REST
Documents with matching identifiers or primary keys.</p>
<h3 data-number="5.14.1" id="options-updatemany"><span
class="header-section-number">5.14.1</span> Options
(updateMany)</h3>
<table>
<caption>REST View Options (updateMany)</caption>
<colgroup>
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 70%" />
</colgroup>
<thead>
<tr class="header">
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>data</td>
<td>object</td>
<td>Yes</td>
<td>Set of fields and corresponding values to
update.</td>
</tr>
</tbody>
</table>
<h3 data-number="5.14.2"
id="return-type-updatemany"><span
class="header-section-number">5.14.2</span> Return Type
(updateMany)</h3>
<p>An array of JSON objects representing the up-to-date
REST <a href="#rest-document">Documents</a>.</p>
<h3 data-number="5.14.3" id="reference-updatemany"><span
class="header-section-number">5.14.3</span> Reference
(updateMany)</h3>
<div class="sourceCode" id="cb69"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb69-1"><a href="#cb69-1" aria-hidden="true" tabindex="-1"></a><span class="kw">async</span> <span class="kw">function</span> <span class="fu">updateMany</span> (args<span class="op">:</span> IUpdateOptions<span class="op"><</span>UpdatableFields[]<span class="op">></span>)<span class="op">:</span> <span class="bu">Promise</span><span class="op"><</span>Data[]<span class="op">></span> {</span>
<span id="cb69-2"><a href="#cb69-2" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb69-3"><a href="#cb69-3" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb69-4"><a href="#cb69-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb69-5"><a href="#cb69-5" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> IUpdateOptions<span class="op"><</span>Type<span class="op">></span> <span class="op">=</span> ICreateOptions<span class="op"><</span>Type<span class="op">>;</span></span></code></pre></div>
<h3 data-number="5.14.4" id="example-updatemany"><span
class="header-section-number">5.14.4</span> Example
(updateMany)</h3>
<div class="sourceCode" id="cb70"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb70-1"><a href="#cb70-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> <span class="im">type</span> { IMyServiceMrsNotesNote } <span class="im">from</span> <span class="st">'/path/to/sdk/myService'</span><span class="op">;</span></span>
<span id="cb70-2"><a href="#cb70-2" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">'./myService.mrs.sdk/myService'</span><span class="op">;</span></span>
<span id="cb70-3"><a href="#cb70-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-4"><a href="#cb70-4" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()<span class="op">;</span></span>
<span id="cb70-5"><a href="#cb70-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-6"><a href="#cb70-6" aria-hidden="true" tabindex="-1"></a><span class="co">// update the notes with id 1 and 2 using a plain object</span></span>
<span id="cb70-7"><a href="#cb70-7" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">update</span>({ data<span class="op">:</span> [{ id<span class="op">:</span> <span class="dv">1</span><span class="op">,</span> title<span class="op">:</span> <span class="st">'bar'</span> }<span class="op">,</span> { id<span class="op">:</span> <span class="dv">2</span><span class="op">,</span> title<span class="op">:</span> <span class="st">'bar'</span> }] })<span class="op">;</span></span>
<span id="cb70-8"><a href="#cb70-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-9"><a href="#cb70-9" aria-hidden="true" tabindex="-1"></a><span class="co">// using a custom class instance</span></span>
<span id="cb70-10"><a href="#cb70-10" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Note <span class="kw">implements</span> IMyServiceMrsNotesNote {</span>
<span id="cb70-11"><a href="#cb70-11" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb70-12"><a href="#cb70-12" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb70-13"><a href="#cb70-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-14"><a href="#cb70-14" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> note1 <span class="op">=</span> <span class="kw">new</span> <span class="fu">Note</span>()<span class="op">;</span></span>
<span id="cb70-15"><a href="#cb70-15" aria-hidden="true" tabindex="-1"></a>note<span class="op">.</span><span class="at">id</span> <span class="op">=</span> <span class="dv">1</span><span class="op">;</span></span>
<span id="cb70-16"><a href="#cb70-16" aria-hidden="true" tabindex="-1"></a>note<span class="op">.</span><span class="at">shared</span> <span class="op">=</span> <span class="kw">false</span><span class="op">;</span></span>
<span id="cb70-17"><a href="#cb70-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-18"><a href="#cb70-18" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> note2 <span class="op">=</span> <span class="kw">new</span> <span class="fu">Note</span>()<span class="op">;</span></span>
<span id="cb70-19"><a href="#cb70-19" aria-hidden="true" tabindex="-1"></a>note<span class="op">.</span><span class="at">id</span> <span class="op">=</span> <span class="dv">2</span><span class="op">;</span></span>
<span id="cb70-20"><a href="#cb70-20" aria-hidden="true" tabindex="-1"></a>note<span class="op">.</span><span class="at">shared</span> <span class="op">=</span> <span class="kw">false</span><span class="op">;</span></span>
<span id="cb70-21"><a href="#cb70-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-22"><a href="#cb70-22" aria-hidden="true" tabindex="-1"></a><span class="co">// update the notes with id 1 and 2</span></span>
<span id="cb70-23"><a href="#cb70-23" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">note</span><span class="op">.</span><span class="fu">update</span>({ data<span class="op">:</span> [note1<span class="op">,</span> note2] })<span class="op">;</span></span></code></pre></div>
<h2 data-number="5.15" id="document-update-ts"><span
class="header-section-number">5.15</span>
Document.update</h2>
<p><code>update</code> is used to update a given REST
document by committing the set of updates performed
locally on the corresponding instance in the
application.</p>
<blockquote>
<p>This function is only available if the REST View
enables the “UPDATE” CRUD operation and specifies one or
more identifier fields.</p>
</blockquote>
<h3 data-number="5.15.1" id="reference-update-1"><span
class="header-section-number">5.15.1</span> Reference
(update)</h3>
<div class="sourceCode" id="cb71"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb71-1"><a href="#cb71-1" aria-hidden="true" tabindex="-1"></a><span class="kw">async</span> <span class="kw">function</span> <span class="fu">update</span>()<span class="op">:</span> <span class="bu">Promise</span><span class="op"><</span>IMyServiceSakilaActor<span class="op">></span> {</span>
<span id="cb71-2"><a href="#cb71-2" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb71-3"><a href="#cb71-3" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb71-4"><a href="#cb71-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb71-5"><a href="#cb71-5" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IMyServiceSakilaActor {</span>
<span id="cb71-6"><a href="#cb71-6" aria-hidden="true" tabindex="-1"></a> <span class="kw">readonly</span> actorId<span class="op">?:</span> <span class="dt">number</span><span class="op">;</span></span>
<span id="cb71-7"><a href="#cb71-7" aria-hidden="true" tabindex="-1"></a> firstName<span class="op">?:</span> <span class="dt">string</span><span class="op">;</span></span>
<span id="cb71-8"><a href="#cb71-8" aria-hidden="true" tabindex="-1"></a> lastName<span class="op">?:</span> <span class="dt">string</span><span class="op">;</span></span>
<span id="cb71-9"><a href="#cb71-9" aria-hidden="true" tabindex="-1"></a> lastUpdate<span class="op">?:</span> <span class="dt">string</span><span class="op">;</span></span>
<span id="cb71-10"><a href="#cb71-10" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h3 data-number="5.15.2" id="example-update-1"><span
class="header-section-number">5.15.2</span> Example
(update)</h3>
<div class="sourceCode" id="cb72"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb72-1"><a href="#cb72-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">'./myService.mrs.sdk/myService'</span><span class="op">;</span></span>
<span id="cb72-2"><a href="#cb72-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb72-3"><a href="#cb72-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()<span class="op">;</span></span>
<span id="cb72-4"><a href="#cb72-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb72-5"><a href="#cb72-5" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> actor <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">actor</span><span class="op">.</span><span class="fu">findFirst</span>()<span class="op">;</span></span>
<span id="cb72-6"><a href="#cb72-6" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> (actor) {</span>
<span id="cb72-7"><a href="#cb72-7" aria-hidden="true" tabindex="-1"></a> actor<span class="op">.</span><span class="at">lastName</span> <span class="op">=</span> <span class="st">"FOO"</span><span class="op">;</span></span>
<span id="cb72-8"><a href="#cb72-8" aria-hidden="true" tabindex="-1"></a> <span class="kw">const</span> modifiedActor <span class="op">=</span> <span class="cf">await</span> actor<span class="op">.</span><span class="fu">update</span>()<span class="op">;</span></span>
<span id="cb72-9"><a href="#cb72-9" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(modifiedActor<span class="op">.</span><span class="at">lastName</span>)<span class="op">;</span> <span class="co">// FOO</span></span>
<span id="cb72-10"><a href="#cb72-10" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h2 data-number="5.16" id="document-delete-ts"><span
class="header-section-number">5.16</span>
Document.delete</h2>
<p><code>delete</code> is used to delete a given REST
document represented by a corresponding instance in the
application.</p>
<blockquote>
<p>This function is only available if the REST View
enables the “DELETE” CRUD operation and specifies one or
more identifier fields.</p>
</blockquote>
<h3 data-number="5.16.1" id="return-type-delete-1"><span
class="header-section-number">5.16.1</span> Return Type
(delete)</h3>
<p><code>true</code> if the document was deleted
successfully or <code>false</code> otherwise.</p>
<h3 data-number="5.16.2" id="reference-delete-1"><span
class="header-section-number">5.16.2</span> Reference
(delete)</h3>
<div class="sourceCode" id="cb73"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb73-1"><a href="#cb73-1" aria-hidden="true" tabindex="-1"></a><span class="kw">async</span> <span class="kw">function</span> <span class="fu">delete</span>()<span class="op">:</span> <span class="bu">Promise</span><span class="op"><</span><span class="dt">boolean</span><span class="op">></span> {</span>
<span id="cb73-2"><a href="#cb73-2" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb73-3"><a href="#cb73-3" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h3 data-number="5.16.3" id="example-delete-1"><span
class="header-section-number">5.16.3</span> Example
(delete)</h3>
<div class="sourceCode" id="cb74"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb74-1"><a href="#cb74-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">'./myService.mrs.sdk/myService'</span><span class="op">;</span></span>
<span id="cb74-2"><a href="#cb74-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-3"><a href="#cb74-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()<span class="op">;</span></span>
<span id="cb74-4"><a href="#cb74-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-5"><a href="#cb74-5" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> actor <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">actor</span><span class="op">.</span><span class="fu">findFirst</span>()<span class="op">;</span></span>
<span id="cb74-6"><a href="#cb74-6" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> (actor) {</span>
<span id="cb74-7"><a href="#cb74-7" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> (<span class="cf">await</span> actor<span class="op">.</span><span class="fu">delete</span>()) {</span>
<span id="cb74-8"><a href="#cb74-8" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="vs">`Actor </span><span class="sc">${</span>actor<span class="op">.</span><span class="at">actorId</span><span class="sc">}</span><span class="vs"> was deleted.`</span>)</span>
<span id="cb74-9"><a href="#cb74-9" aria-hidden="true" tabindex="-1"></a> } <span class="cf">else</span> {</span>
<span id="cb74-10"><a href="#cb74-10" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="vs">`Actor </span><span class="sc">${</span>actor<span class="op">.</span><span class="at">actorId</span><span class="sc">}</span><span class="vs"> was not deleted.`</span>)</span>
<span id="cb74-11"><a href="#cb74-11" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb74-12"><a href="#cb74-12" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h2 data-number="5.17" id="function-call-ts"><span
class="header-section-number">5.17</span> Function.call
</h2>
<p><code>call</code> is used to execute a REST routine
(<code>FUNCTION</code> or <code>PROCEDURE</code>). The
first parameter of the command is an <code>object</code>
containing the set of <code>IN</code>/<code>INOUT</code>
parameters (and corresponding values) as specified by
the database routine. The second parameter is an
<code>object</code> with execution options which is only
available if the REST routine has an associated Async
Task.</p>
<h3 data-number="5.17.1" id="options-call"><span
class="header-section-number">5.17.1</span> Options
(call)</h3>
<table>
<caption>REST Function/Procedure Options
(call)</caption>
<colgroup>
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 70%" />
</colgroup>
<thead>
<tr class="header">
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>refreshRate</td>
<td>number (>=500)</td>
<td>No</td>
<td>Time (ms) to wait (default 2000) for retrieving the
next progress report. (available only if the routine has
an associated Async Task)</td>
</tr>
<tr class="even">
<td>progress</td>
<td>async function</td>
<td>No</td>
<td>Callback to be executed using the details of each
progress report while the routine does not finish.</td>
</tr>
<tr class="odd">
<td>timeout</td>
<td>number</td>
<td>No</td>
<td>Maximum time to wait for the execution to complete.
If this threshold is reached, the ongoing task is
killed. By default, no timeout is enforced. (available
only if the routine has an associated Async Task)</td>
</tr>
</tbody>
</table>
<h3 data-number="5.17.2" id="return-type-call"><span
class="header-section-number">5.17.2</span> Return Type
(call)</h3>
<p>In the case of a <code>FUNCTION</code>, the value
returned by that function. In the case of a
<code>PROCEDURE</code>, a JSON object containing the
result produced by the procedure (including
<code>OUT</code>/<code>INOUT</code> parameters and
result sets).</p>
<p>Note: Procedures with an associated Async Task are
not capable of not producing result sets, only
<code>OUT</code>/<code>INOUT</code> parameter
values.</p>
<h3 data-number="5.17.3" id="reference-call"><span
class="header-section-number">5.17.3</span> Reference
(call)</h3>
<div class="sourceCode" id="cb75"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb75-1"><a href="#cb75-1" aria-hidden="true" tabindex="-1"></a><span class="kw">async</span> <span class="kw">function</span> <span class="fu">call</span> (noteUpdateParams<span class="op">?:</span> IMyServiceMrsNotesNoteUpdateParams<span class="op">,</span> options<span class="op">?:</span> IMrsTaskRunOptions<span class="op"><</span><span class="dt">object</span><span class="op">,</span> IMrsProcedureResult<span class="op"><</span>IMyServiceMrsNotesNoteUpdateParamsOut<span class="op">,</span> IMyServiceMrsNotesNoteUpdateResultSet<span class="op">>></span>)<span class="op">:</span> <span class="bu">Promise</span><span class="op"><</span>IMrsProcedureResult<span class="op"><</span>IMyServiceMrsNotesNoteUpdateParamsOut<span class="op">,</span> IMyServiceMrsNotesNoteUpdateResultSet<span class="op">>></span> {</span>
<span id="cb75-2"><a href="#cb75-2" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb75-3"><a href="#cb75-3" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb75-4"><a href="#cb75-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb75-5"><a href="#cb75-5" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IMyServiceMrsNotesNoteUpdateParams {</span>
<span id="cb75-6"><a href="#cb75-6" aria-hidden="true" tabindex="-1"></a> tags<span class="op">?:</span> JsonValue<span class="op">;</span></span>
<span id="cb75-7"><a href="#cb75-7" aria-hidden="true" tabindex="-1"></a> lockedDown<span class="op">?:</span> <span class="dt">boolean</span><span class="op">;</span></span>
<span id="cb75-8"><a href="#cb75-8" aria-hidden="true" tabindex="-1"></a> noteId<span class="op">?:</span> <span class="dt">number</span><span class="op">;</span></span>
<span id="cb75-9"><a href="#cb75-9" aria-hidden="true" tabindex="-1"></a> title<span class="op">?:</span> <span class="dt">string</span><span class="op">;</span></span>
<span id="cb75-10"><a href="#cb75-10" aria-hidden="true" tabindex="-1"></a> content<span class="op">?:</span> <span class="dt">string</span><span class="op">;</span></span>
<span id="cb75-11"><a href="#cb75-11" aria-hidden="true" tabindex="-1"></a> pinned<span class="op">?:</span> <span class="dt">boolean</span><span class="op">;</span></span>
<span id="cb75-12"><a href="#cb75-12" aria-hidden="true" tabindex="-1"></a> userId<span class="op">?:</span> <span class="dt">string</span><span class="op">;</span></span>
<span id="cb75-13"><a href="#cb75-13" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb75-14"><a href="#cb75-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb75-15"><a href="#cb75-15" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IMrsTaskStartOptions {</span>
<span id="cb75-16"><a href="#cb75-16" aria-hidden="true" tabindex="-1"></a> refreshRate<span class="op">?:</span> <span class="dt">number</span><span class="op">;</span></span>
<span id="cb75-17"><a href="#cb75-17" aria-hidden="true" tabindex="-1"></a> timeout<span class="op">?:</span> <span class="dt">number</span><span class="op">;</span></span>
<span id="cb75-18"><a href="#cb75-18" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb75-19"><a href="#cb75-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb75-20"><a href="#cb75-20" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IMrsTaskRunOptions<span class="op"><</span>MrsTaskStatusUpdate<span class="op">,</span> MrsTaskResult<span class="op">></span> <span class="kw">extends</span> IMrsTaskStartOptions {</span>
<span id="cb75-21"><a href="#cb75-21" aria-hidden="true" tabindex="-1"></a> progress<span class="op">?</span>(report<span class="op">:</span> IMrsRunningTaskReport<span class="op"><</span>MrsTaskStatusUpdate<span class="op">,</span> MrsTaskResult<span class="op">></span>)<span class="op">:</span> <span class="bu">Promise</span><span class="op"><</span><span class="dt">void</span><span class="op">>;</span></span>
<span id="cb75-22"><a href="#cb75-22" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb75-23"><a href="#cb75-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb75-24"><a href="#cb75-24" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IMrsRunningTaskReport<span class="op"><</span>MrsTaskStatusUpdate<span class="op">,</span> MrsTaskResult<span class="op">></span> {</span>
<span id="cb75-25"><a href="#cb75-25" aria-hidden="true" tabindex="-1"></a> data<span class="op">:</span> MrsTaskStatusUpdate<span class="op">;</span></span>
<span id="cb75-26"><a href="#cb75-26" aria-hidden="true" tabindex="-1"></a> status<span class="op">:</span> <span class="st">"RUNNING"</span><span class="op">;</span></span>
<span id="cb75-27"><a href="#cb75-27" aria-hidden="true" tabindex="-1"></a> message<span class="op">:</span> <span class="dt">string</span><span class="op">;</span></span>
<span id="cb75-28"><a href="#cb75-28" aria-hidden="true" tabindex="-1"></a> progress<span class="op">:</span> <span class="dt">number</span><span class="op">;</span></span>
<span id="cb75-29"><a href="#cb75-29" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb75-30"><a href="#cb75-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb75-31"><a href="#cb75-31" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> IMyServiceMrsNotesNoteUpdateParamsOut <span class="op">=</span> <span class="dt">never</span><span class="op">;</span></span>
<span id="cb75-32"><a href="#cb75-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb75-33"><a href="#cb75-33" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> IMyServiceMrsNotesNoteUpdateResultSet <span class="op">=</span> JsonObject<span class="op">;</span></span>
<span id="cb75-34"><a href="#cb75-34" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb75-35"><a href="#cb75-35" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IMrsProcedureResult<span class="op"><</span>OutParams<span class="op">,</span> ResultSet<span class="op">></span> {</span>
<span id="cb75-36"><a href="#cb75-36" aria-hidden="true" tabindex="-1"></a> outParameters<span class="op">?:</span> OutParams<span class="op">;</span></span>
<span id="cb75-37"><a href="#cb75-37" aria-hidden="true" tabindex="-1"></a> resultSets<span class="op">:</span> ResultSet[]<span class="op">;</span></span>
<span id="cb75-38"><a href="#cb75-38" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h4 data-number="5.17.3.1" id="example-call"><span
class="header-section-number">5.17.3.1</span> Example
(call)</h4>
<div class="sourceCode" id="cb76"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb76-1"><a href="#cb76-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">'./myService.mrs.sdk/myService'</span><span class="op">;</span></span>
<span id="cb76-2"><a href="#cb76-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb76-3"><a href="#cb76-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()<span class="op">;</span></span>
<span id="cb76-4"><a href="#cb76-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb76-5"><a href="#cb76-5" aria-hidden="true" tabindex="-1"></a><span class="co">// update the title of a note with a given id</span></span>
<span id="cb76-6"><a href="#cb76-6" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">noteUpdate</span><span class="op">.</span><span class="fu">call</span>({ noteId<span class="op">:</span> note<span class="op">.</span><span class="at">id</span><span class="op">,</span> title<span class="op">:</span> <span class="st">"hello world"</span> })<span class="op">;</span></span>
<span id="cb76-7"><a href="#cb76-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb76-8"><a href="#cb76-8" aria-hidden="true" tabindex="-1"></a><span class="co">// execute a function for each progress status update</span></span>
<span id="cb76-9"><a href="#cb76-9" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> progress <span class="op">=</span> (report) <span class="kw">=></span> {</span>
<span id="cb76-10"><a href="#cb76-10" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(report<span class="op">.</span><span class="at">progress</span>)</span>
<span id="cb76-11"><a href="#cb76-11" aria-hidden="true" tabindex="-1"></a>}<span class="op">;</span></span>
<span id="cb76-12"><a href="#cb76-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb76-13"><a href="#cb76-13" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">noteUpdate</span><span class="op">.</span><span class="fu">call</span>({ noteId<span class="op">:</span> note<span class="op">.</span><span class="at">id</span><span class="op">,</span> title<span class="op">:</span> <span class="st">"hello world"</span> }<span class="op">,</span> { progress })<span class="op">;</span></span></code></pre></div>
<h2 data-number="5.18" id="function-start-ts"><span
class="header-section-number">5.18</span> Function.start
</h2>
<p><code>start</code> is used to start a REST routine
(<code>FUNCTION</code> or <code>PROCEDURE</code>) with
an associated Async Task. The first parameter of the
command is an <code>object</code> containing the set of
<code>IN</code>/<code>INOUT</code> parameters (and
corresponding values) as specified by the database
routine. The second and last parameter of the command is
an <code>object</code> with a set of routine execution
constraint options.</p>
<h3 data-number="5.18.1" id="options-start"><span
class="header-section-number">5.18.1</span> Options
(start)</h3>
<table>
<colgroup>
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 70%" />
</colgroup>
<thead>
<tr class="header">
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>refreshRate</td>
<td>number (>=500)</td>
<td>No</td>
<td>Time (ms) to wait (default 2000) for retrieving the
next progress report (available only if the routine has
an associated Async Task).</td>
</tr>
<tr class="even">
<td>timeout</td>
<td>number</td>
<td>No</td>
<td>Time (ms) to wait for the routine to produce a
result.</td>
</tr>
</tbody>
</table>
<h3 data-number="5.18.2" id="return-type-start"><span
class="header-section-number">5.18.2</span> Return Type
(start)</h3>
<p>A <a href="#task">Task</a> instance.</p>
<h3 data-number="5.18.3" id="reference-start"><span
class="header-section-number">5.18.3</span> Reference
(start)</h3>
<div class="sourceCode" id="cb77"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb77-1"><a href="#cb77-1" aria-hidden="true" tabindex="-1"></a><span class="kw">async</span> <span class="kw">function</span> <span class="fu">start</span>(params<span class="op">?:</span> IMyServiceMrsNotesNoteUpdateParams<span class="op">,</span> options<span class="op">?:</span> IMrsTaskStartOptions)<span class="op">:</span> <span class="bu">Promise</span><span class="op"><</span>MrsTask<span class="op"><</span><span class="dt">object</span><span class="op">,</span> IMrsProcedureResult<span class="op"><</span>IMyServiceMrsNotesNoteUpdateParamsOut<span class="op">,</span> IMyServiceMrsNotesNoteUpdateResultSet<span class="op">>>></span> {</span>
<span id="cb77-2"><a href="#cb77-2" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb77-3"><a href="#cb77-3" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb77-4"><a href="#cb77-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb77-5"><a href="#cb77-5" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IMyServiceMrsNotesNoteUpdateParams {</span>
<span id="cb77-6"><a href="#cb77-6" aria-hidden="true" tabindex="-1"></a> tags<span class="op">?:</span> JsonValue<span class="op">;</span></span>
<span id="cb77-7"><a href="#cb77-7" aria-hidden="true" tabindex="-1"></a> lockedDown<span class="op">?:</span> <span class="dt">boolean</span><span class="op">;</span></span>
<span id="cb77-8"><a href="#cb77-8" aria-hidden="true" tabindex="-1"></a> noteId<span class="op">?:</span> <span class="dt">number</span><span class="op">;</span></span>
<span id="cb77-9"><a href="#cb77-9" aria-hidden="true" tabindex="-1"></a> title<span class="op">?:</span> <span class="dt">string</span><span class="op">;</span></span>
<span id="cb77-10"><a href="#cb77-10" aria-hidden="true" tabindex="-1"></a> content<span class="op">?:</span> <span class="dt">string</span><span class="op">;</span></span>
<span id="cb77-11"><a href="#cb77-11" aria-hidden="true" tabindex="-1"></a> pinned<span class="op">?:</span> <span class="dt">boolean</span><span class="op">;</span></span>
<span id="cb77-12"><a href="#cb77-12" aria-hidden="true" tabindex="-1"></a> userId<span class="op">?:</span> <span class="dt">string</span><span class="op">;</span></span>
<span id="cb77-13"><a href="#cb77-13" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb77-14"><a href="#cb77-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb77-15"><a href="#cb77-15" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> IMyServiceMrsNotesNoteUpdateParamsOut <span class="op">=</span> <span class="dt">never</span><span class="op">;</span></span>
<span id="cb77-16"><a href="#cb77-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb77-17"><a href="#cb77-17" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> IMyServiceMrsNotesNoteUpdateResultSet <span class="op">=</span> JsonObject<span class="op">;</span></span>
<span id="cb77-18"><a href="#cb77-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb77-19"><a href="#cb77-19" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IMrsProcedureResult<span class="op"><</span>OutParams<span class="op">,</span> ResultSet<span class="op">></span> {</span>
<span id="cb77-20"><a href="#cb77-20" aria-hidden="true" tabindex="-1"></a> outParameters<span class="op">?:</span> OutParams<span class="op">;</span></span>
<span id="cb77-21"><a href="#cb77-21" aria-hidden="true" tabindex="-1"></a> resultSets<span class="op">:</span> ResultSet[]<span class="op">;</span></span>
<span id="cb77-22"><a href="#cb77-22" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb77-23"><a href="#cb77-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb77-24"><a href="#cb77-24" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IMrsTaskStartOptions {</span>
<span id="cb77-25"><a href="#cb77-25" aria-hidden="true" tabindex="-1"></a> refreshRate<span class="op">?:</span> <span class="dt">number</span><span class="op">;</span></span>
<span id="cb77-26"><a href="#cb77-26" aria-hidden="true" tabindex="-1"></a> timeout<span class="op">?:</span> <span class="dt">number</span><span class="op">;</span></span>
<span id="cb77-27"><a href="#cb77-27" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h4 data-number="5.18.3.1" id="example-start"><span
class="header-section-number">5.18.3.1</span> Example
(start)</h4>
<div class="sourceCode" id="cb78"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb78-1"><a href="#cb78-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">'./myService.mrs.sdk/myService'</span><span class="op">;</span></span>
<span id="cb78-2"><a href="#cb78-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb78-3"><a href="#cb78-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()<span class="op">;</span></span>
<span id="cb78-4"><a href="#cb78-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb78-5"><a href="#cb78-5" aria-hidden="true" tabindex="-1"></a><span class="co">// update the title of a note with a given id</span></span>
<span id="cb78-6"><a href="#cb78-6" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> task <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">noteUpdate</span><span class="op">.</span><span class="fu">start</span>({ noteId<span class="op">:</span> note<span class="op">.</span><span class="at">id</span><span class="op">,</span> title<span class="op">:</span> <span class="st">"hello world"</span> })<span class="op">;</span></span>
<span id="cb78-7"><a href="#cb78-7" aria-hidden="true" tabindex="-1"></a><span class="co">// check for status updates every 1 second</span></span>
<span id="cb78-8"><a href="#cb78-8" aria-hidden="true" tabindex="-1"></a>task <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">noteUpdate</span><span class="op">.</span><span class="fu">start</span>({ noteId<span class="op">:</span> note<span class="op">.</span><span class="at">id</span><span class="op">,</span> title<span class="op">:</span> <span class="st">"hello world"</span> }<span class="op">,</span> { refreshRate<span class="op">:</span> <span class="dv">1000</span> })<span class="op">;</span></span>
<span id="cb78-9"><a href="#cb78-9" aria-hidden="true" tabindex="-1"></a><span class="co">// cancel the execution after 5 seconds</span></span>
<span id="cb78-10"><a href="#cb78-10" aria-hidden="true" tabindex="-1"></a>task <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">noteUpdate</span><span class="op">.</span><span class="fu">start</span>({ noteId<span class="op">:</span> note<span class="op">.</span><span class="at">id</span><span class="op">,</span> title<span class="op">:</span> <span class="st">"hello world"</span> }<span class="op">,</span> { timeout<span class="op">:</span> <span class="dv">5000</span> })<span class="op">;</span></span></code></pre></div>
<h2 data-number="5.19" id="procedure-call-ts"><span
class="header-section-number">5.19</span> Procedure.call
</h2>
<p><code>call</code> is used to execute a REST routine
(<code>FUNCTION</code> or <code>PROCEDURE</code>).
Please see <a href="#function-call-ts">Function.call</a>
for more details.</p>
<h2 data-number="5.20" id="procedure-start-ts"><span
class="header-section-number">5.20</span>
Procedure.start</h2>
<p><code>start</code> is used to start a REST routine
(<code>FUNCTION</code> or <code>PROCEDURE</code>) with
an associated Async Task. Please see <a
href="#function-start-ts">Function.start</a> for more
details.</p>
<h2 data-number="5.21" id="task-watch-ts"><span
class="header-section-number">5.21</span> Task.watch
</h2>
<p><code>watch</code> is used to monitor the status of a
REST routine (<code>FUNCTION</code> or
<code>PROCEDURE</code>) with an associated Async
Task.</p>
<h3 data-number="5.21.1" id="return-type-watch"><span
class="header-section-number">5.21.1</span> Return Type
(watch)</h3>
<p>An <a
href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AsyncGenerator">AsyncGenerator</a>
instance which produces status update reports with
details about the execution context of the REST
routine.</p>
<h3 data-number="5.21.2" id="reference-watch"><span
class="header-section-number">5.21.2</span> Reference
(watch)</h3>
<div class="sourceCode" id="cb79"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb79-1"><a href="#cb79-1" aria-hidden="true" tabindex="-1"></a><span class="kw">async</span> <span class="kw">function</span> <span class="fu">watch</span>()<span class="op">:</span> AsyncGenerator<span class="op"><</span></span>
<span id="cb79-2"><a href="#cb79-2" aria-hidden="true" tabindex="-1"></a> IMrsTaskReport<span class="op"><</span><span class="dt">object</span><span class="op">,</span> IMrsProcedureResult<span class="op"><</span>IMyServiceMrsNotesNoteUpdateParamsOut<span class="op">,</span> IMyServiceMrsNotesNoteUpdateResultSet<span class="op">>>></span> {</span>
<span id="cb79-3"><a href="#cb79-3" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb79-4"><a href="#cb79-4" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb79-5"><a href="#cb79-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb79-6"><a href="#cb79-6" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> IMyServiceMrsNotesNoteUpdateParamsOut <span class="op">=</span> <span class="dt">never</span><span class="op">;</span></span>
<span id="cb79-7"><a href="#cb79-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb79-8"><a href="#cb79-8" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> IMyServiceMrsNotesNoteUpdateResultSet <span class="op">=</span> JsonObject<span class="op">;</span></span>
<span id="cb79-9"><a href="#cb79-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb79-10"><a href="#cb79-10" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IMrsProcedureResult<span class="op"><</span>OutParams<span class="op">,</span> ResultSet<span class="op">></span> {</span>
<span id="cb79-11"><a href="#cb79-11" aria-hidden="true" tabindex="-1"></a> outParameters<span class="op">?:</span> OutParams<span class="op">;</span></span>
<span id="cb79-12"><a href="#cb79-12" aria-hidden="true" tabindex="-1"></a> resultSets<span class="op">:</span> ResultSet[]</span>
<span id="cb79-13"><a href="#cb79-13" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb79-14"><a href="#cb79-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb79-15"><a href="#cb79-15" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IMrsScheduledTaskReport<span class="op"><</span>MrsTaskStatusUpdate<span class="op">,</span> MrsTaskResult<span class="op">></span> {</span>
<span id="cb79-16"><a href="#cb79-16" aria-hidden="true" tabindex="-1"></a> status<span class="op">:</span> <span class="st">"SCHEDULED"</span><span class="op">;</span></span>
<span id="cb79-17"><a href="#cb79-17" aria-hidden="true" tabindex="-1"></a> message<span class="op">:</span> <span class="dt">string</span><span class="op">;</span></span>
<span id="cb79-18"><a href="#cb79-18" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb79-19"><a href="#cb79-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb79-20"><a href="#cb79-20" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IMrsRunningTaskReport<span class="op"><</span>MrsTaskStatusUpdate<span class="op">,</span> MrsTaskResult<span class="op">></span> {</span>
<span id="cb79-21"><a href="#cb79-21" aria-hidden="true" tabindex="-1"></a> data<span class="op">:</span> MrsTaskStatusUpdate<span class="op">;</span></span>
<span id="cb79-22"><a href="#cb79-22" aria-hidden="true" tabindex="-1"></a> status<span class="op">:</span> <span class="st">"RUNNING"</span><span class="op">;</span></span>
<span id="cb79-23"><a href="#cb79-23" aria-hidden="true" tabindex="-1"></a> message<span class="op">:</span> <span class="dt">string</span><span class="op">;</span></span>
<span id="cb79-24"><a href="#cb79-24" aria-hidden="true" tabindex="-1"></a> progress<span class="op">:</span> <span class="dt">number</span><span class="op">;</span></span>
<span id="cb79-25"><a href="#cb79-25" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb79-26"><a href="#cb79-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb79-27"><a href="#cb79-27" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IMrsCompletedTaskReport<span class="op"><</span>MrsTaskStatusUpdate<span class="op">,</span> MrsTaskResult<span class="op">></span> {</span>
<span id="cb79-28"><a href="#cb79-28" aria-hidden="true" tabindex="-1"></a> data<span class="op">:</span> MrsTaskResult<span class="op">;</span></span>
<span id="cb79-29"><a href="#cb79-29" aria-hidden="true" tabindex="-1"></a> status<span class="op">:</span> <span class="st">"COMPLETED"</span><span class="op">;</span></span>
<span id="cb79-30"><a href="#cb79-30" aria-hidden="true" tabindex="-1"></a> message<span class="op">:</span> <span class="dt">string</span><span class="op">;</span></span>
<span id="cb79-31"><a href="#cb79-31" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb79-32"><a href="#cb79-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb79-33"><a href="#cb79-33" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IMrsCancelledTaskReport<span class="op"><</span>MrsTaskStatusUpdate<span class="op">,</span> MrsTaskResult<span class="op">></span> {</span>
<span id="cb79-34"><a href="#cb79-34" aria-hidden="true" tabindex="-1"></a> status<span class="op">:</span> <span class="st">"CANCELLED"</span><span class="op">;</span></span>
<span id="cb79-35"><a href="#cb79-35" aria-hidden="true" tabindex="-1"></a> message<span class="op">:</span> <span class="dt">string</span><span class="op">;</span></span>
<span id="cb79-36"><a href="#cb79-36" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb79-37"><a href="#cb79-37" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb79-38"><a href="#cb79-38" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IMrsErrorTaskReport<span class="op"><</span>MrsTaskStatusUpdate<span class="op">,</span> MrsTaskResult<span class="op">></span> {</span>
<span id="cb79-39"><a href="#cb79-39" aria-hidden="true" tabindex="-1"></a> status<span class="op">:</span> <span class="st">"ERROR"</span><span class="op">;</span></span>
<span id="cb79-40"><a href="#cb79-40" aria-hidden="true" tabindex="-1"></a> message<span class="op">:</span> <span class="dt">string</span><span class="op">;</span></span>
<span id="cb79-41"><a href="#cb79-41" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb79-42"><a href="#cb79-42" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb79-43"><a href="#cb79-43" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IMrsTimedOutTaskReport<span class="op"><</span>MrsTaskStatusUpdate<span class="op">,</span> MrsTaskResult<span class="op">></span> {</span>
<span id="cb79-44"><a href="#cb79-44" aria-hidden="true" tabindex="-1"></a> status<span class="op">:</span> <span class="st">"TIMEOUT"</span><span class="op">;</span></span>
<span id="cb79-45"><a href="#cb79-45" aria-hidden="true" tabindex="-1"></a> message<span class="op">:</span> <span class="dt">string</span><span class="op">;</span></span>
<span id="cb79-46"><a href="#cb79-46" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb79-47"><a href="#cb79-47" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb79-48"><a href="#cb79-48" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> IMrsTaskReport<span class="op"><</span>MrsTaskStatusUpdate<span class="op">,</span> MrsTaskResult<span class="op">></span> <span class="op">=</span></span>
<span id="cb79-49"><a href="#cb79-49" aria-hidden="true" tabindex="-1"></a> IMrsRunningTaskReport<span class="op"><</span>MrsTaskStatusUpdate<span class="op">,</span> MrsTaskResult<span class="op">></span></span>
<span id="cb79-50"><a href="#cb79-50" aria-hidden="true" tabindex="-1"></a> <span class="op">|</span> IMrsCompletedTaskReport<span class="op"><</span>MrsTaskStatusUpdate<span class="op">,</span> MrsTaskResult<span class="op">></span></span>
<span id="cb79-51"><a href="#cb79-51" aria-hidden="true" tabindex="-1"></a> <span class="op">|</span> IMrsCancelledTaskReport<span class="op"><</span>MrsTaskStatusUpdate<span class="op">,</span> MrsTaskResult<span class="op">></span></span>
<span id="cb79-52"><a href="#cb79-52" aria-hidden="true" tabindex="-1"></a> <span class="op">|</span> IMrsErrorTaskReport<span class="op"><</span>MrsTaskStatusUpdate<span class="op">,</span> MrsTaskResult<span class="op">></span></span>
<span id="cb79-53"><a href="#cb79-53" aria-hidden="true" tabindex="-1"></a> <span class="op">|</span> IMrsTimedOutTaskReport<span class="op"><</span>MrsTaskStatusUpdate<span class="op">,</span> MrsTaskResult<span class="op">>;</span></span></code></pre></div>
<h3 data-number="5.21.3" id="example-watch"><span
class="header-section-number">5.21.3</span> Example
(watch)</h3>
<div class="sourceCode" id="cb80"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb80-1"><a href="#cb80-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">'./myService.mrs.sdk/myService'</span><span class="op">;</span></span>
<span id="cb80-2"><a href="#cb80-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb80-3"><a href="#cb80-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()<span class="op">;</span></span>
<span id="cb80-4"><a href="#cb80-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb80-5"><a href="#cb80-5" aria-hidden="true" tabindex="-1"></a><span class="co">// update the title of a note with a given id</span></span>
<span id="cb80-6"><a href="#cb80-6" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> task <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">noteUpdate</span><span class="op">.</span><span class="fu">start</span>({ noteId<span class="op">:</span> note<span class="op">.</span><span class="at">id</span><span class="op">,</span> title<span class="op">:</span> <span class="st">"hello world"</span> })<span class="op">;</span></span>
<span id="cb80-7"><a href="#cb80-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb80-8"><a href="#cb80-8" aria-hidden="true" tabindex="-1"></a><span class="co">// assuming it is a long-running operation, watch for status updates</span></span>
<span id="cb80-9"><a href="#cb80-9" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="cf">await</span> (<span class="kw">const</span> report <span class="kw">of</span> task<span class="op">.</span><span class="fu">watch</span>()) {</span>
<span id="cb80-10"><a href="#cb80-10" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> (report<span class="op">.</span><span class="at">status</span> <span class="op">===</span> <span class="st">"RUNNING"</span>) {</span>
<span id="cb80-11"><a href="#cb80-11" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(report<span class="op">.</span><span class="at">progress</span>)<span class="op">;</span></span>
<span id="cb80-12"><a href="#cb80-12" aria-hidden="true" tabindex="-1"></a> } <span class="cf">else</span> <span class="cf">if</span> (report<span class="op">.</span><span class="at">status</span> <span class="op">===</span> <span class="st">"ERROR"</span>) {</span>
<span id="cb80-13"><a href="#cb80-13" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(report<span class="op">.</span><span class="at">message</span>)<span class="op">;</span></span>
<span id="cb80-14"><a href="#cb80-14" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb80-15"><a href="#cb80-15" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h2 data-number="5.22" id="task-kill-ts"><span
class="header-section-number">5.22</span> Task.kill
</h2>
<p><code>kill</code> is used to kill the underlying
Async Task of a REST routine (<code>FUNCTION</code> or
<code>PROCEDURE</code>) and cancel its execution.</p>
<h3 data-number="5.22.1" id="reference-kill"><span
class="header-section-number">5.22.1</span> Reference
(kill)</h3>
<div class="sourceCode" id="cb81"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb81-1"><a href="#cb81-1" aria-hidden="true" tabindex="-1"></a><span class="kw">async</span> <span class="kw">function</span> <span class="fu">kill</span>()<span class="op">:</span> <span class="bu">Promise</span><span class="op"><</span><span class="dt">void</span><span class="op">></span> {</span>
<span id="cb81-2"><a href="#cb81-2" aria-hidden="true" tabindex="-1"></a> <span class="co">// ...</span></span>
<span id="cb81-3"><a href="#cb81-3" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h3 data-number="5.22.2" id="example-kill"><span
class="header-section-number">5.22.2</span> Example
(kill)</h3>
<div class="sourceCode" id="cb82"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb82-1"><a href="#cb82-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">'./myService.mrs.sdk/myService'</span><span class="op">;</span></span>
<span id="cb82-2"><a href="#cb82-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb82-3"><a href="#cb82-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()<span class="op">;</span></span>
<span id="cb82-4"><a href="#cb82-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb82-5"><a href="#cb82-5" aria-hidden="true" tabindex="-1"></a><span class="co">// update the title of a note with a given id, kill the task if it takes more than 10 seconds to finish</span></span>
<span id="cb82-6"><a href="#cb82-6" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> task <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="at">mrsNotes</span><span class="op">.</span><span class="at">noteUpdate</span><span class="op">.</span><span class="fu">start</span>({ noteId<span class="op">:</span> note<span class="op">.</span><span class="at">id</span><span class="op">,</span> title<span class="op">:</span> <span class="st">"hello world"</span> }<span class="op">,</span> { timeout<span class="op">:</span> <span class="dv">10000</span> })<span class="op">;</span></span>
<span id="cb82-7"><a href="#cb82-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb82-8"><a href="#cb82-8" aria-hidden="true" tabindex="-1"></a><span class="co">// assuming it is a long-running operation, kill the task if it takes more than 10 seconds to finish</span></span>
<span id="cb82-9"><a href="#cb82-9" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="cf">await</span> (<span class="kw">const</span> report <span class="kw">of</span> task<span class="op">.</span><span class="fu">watch</span>()) {</span>
<span id="cb82-10"><a href="#cb82-10" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> (report<span class="op">.</span><span class="at">status</span> <span class="op">===</span> <span class="st">"TIMEOUT"</span>) {</span>
<span id="cb82-11"><a href="#cb82-11" aria-hidden="true" tabindex="-1"></a> <span class="cf">await</span> task<span class="op">.</span><span class="fu">kill</span>()<span class="op">;</span></span>
<span id="cb82-12"><a href="#cb82-12" aria-hidden="true" tabindex="-1"></a> } <span class="cf">else</span> <span class="cf">if</span> (report<span class="op">.</span><span class="at">status</span> <span class="op">===</span> <span class="st">"CANCELLED"</span>) {</span>
<span id="cb82-13"><a href="#cb82-13" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(report<span class="op">.</span><span class="at">message</span>)<span class="op">;</span></span>
<span id="cb82-14"><a href="#cb82-14" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb82-15"><a href="#cb82-15" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<!-- Copyright (c) 2024, 2026, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2.0,
as published by the Free Software Foundation.
This program is designed to work with certain software (including
but not limited to OpenSSL) that is licensed under separate terms, as
designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have either included with
the program or referenced in the documentation.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
the GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -->
<h1 data-number="6"
id="python-client-api-reference"><span
class="header-section-number">6</span> Python Client API
Reference</h1>
<p>The MRS Python SDK requires Python 3.12+.</p>
<h2 data-number="6.1" id="rest-resources"><span
class="header-section-number">6.1</span> REST
Resources</h2>
<p>The MRS Python SDK exposes a type-safe programmable
interface for the MySQL REST Service that unifies, under
a set of contextual commands, the available HTTP
operations to access and use database objects (schemas,
tables, views, functions, etc.) exposed as REST
resources.</p>
<p>The following <code>MRS Resources</code> exist as
part of the MRS Python SDK:</p>
<ul>
<li><a href="#rest-services">REST Service</a>
<ul>
<li><a href="#rest-schemas">REST Schema</a>
<ul>
<li><a href="#rest-views">REST View</a>, <a
href="#rest-functions">Function</a> and <a
href="#rest-procedures">Procedure</a>
<ul>
<li><a href="#rest-documents">REST Document</a></li>
</ul></li>
</ul></li>
</ul></li>
</ul>
<p>MRS resources, as shown above, are grouped under
service namespaces.</p>
<p>The following commands can be executed in the scope
of a client-side representation of any MRS resource
(except <a href="#rest-documents">REST
Documents</a>).</p>
<ul>
<li><a href="#get_metadata">get_metadata</a></li>
</ul>
<h3 data-number="6.1.1" id="get_metadata-py"><span
class="header-section-number">6.1.1</span> get_metadata
</h3>
<p>The MRS has a dedicated JSON field where users can
store application specific metadata at different levels:
service, schema and objects of the schema (such as Views
or Functions).</p>
<p><code>get_metadata()</code> is a command that enables
users to access the underlying MRS metadata information
from client REST objects.</p>
<h4 data-number="6.1.1.1"
id="options-get_metadata"><span
class="header-section-number">6.1.1.1</span> Options
(get_metadata)</h4>
<p><code>None</code>.</p>
<h4 data-number="6.1.1.2"
id="return-type-get_metadata"><span
class="header-section-number">6.1.1.2</span> Return Type
(get_metadata)</h4>
<p>The metadata information is returned as a JSON-like
object (<code>dict</code>). If there is no metadata
specified for a given MRS resource, an empty JSON object
(ultimately, a Python <code>dict</code>) is
returned.</p>
<h4 data-number="6.1.1.3"
id="example-get_metadata"><span
class="header-section-number">6.1.1.3</span> Example
(get_metadata)</h4>
<div class="sourceCode" id="cb83"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb83-1"><a href="#cb83-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService</span>
<span id="cb83-2"><a href="#cb83-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb83-3"><a href="#cb83-3" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb83-4"><a href="#cb83-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb83-5"><a href="#cb83-5" aria-hidden="true" tabindex="-1"></a><span class="bu">print</span>(<span class="cf">await</span> my_service.get_metadata()) <span class="co"># {"title": "My Service"}</span></span>
<span id="cb83-6"><a href="#cb83-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb83-7"><a href="#cb83-7" aria-hidden="true" tabindex="-1"></a><span class="bu">print</span>(<span class="cf">await</span> my_service.sakila.get_metadata()) <span class="co"># {"title": "Sakila Sample Database"}</span></span></code></pre></div>
<h2 data-number="6.2" id="rest-services"><span
class="header-section-number">6.2</span> REST
Services</h2>
<p>In the Python SDK, schemas are grouped under service
namespaces.</p>
<p>The following resources can be accessed from a
service namespace:</p>
<ul>
<li><a href="#rest-schemas">REST Schemas</a></li>
</ul>
<p>The following options are supported when creating a
service:</p>
<ul>
<li><a href="#base_url">base_url</a></li>
<li><a href="#verify_tls_cert">verify_tls_cert</a></li>
</ul>
<p>The following commands can be accessed from a service
object:</p>
<ul>
<li>Properties
<ul>
<li><a href="#tls_context">tls_context</a></li>
</ul></li>
<li>Methods
<ul>
<li><a href="#get_auth_apps">get_auth_apps</a></li>
<li><a href="#authenticate">authenticate</a></li>
<li><a href="#deauthenticate">deauthenticate</a></li>
</ul></li>
</ul>
<h3 data-number="6.2.1" id="base_url"><span
class="header-section-number">6.2.1</span> base_url</h3>
<p><code>base_url</code> is a service constructor option
that allows you to customize the service URL.</p>
<div class="sourceCode" id="cb84"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb84-1"><a href="#cb84-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService</span>
<span id="cb84-2"><a href="#cb84-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb84-3"><a href="#cb84-3" aria-hidden="true" tabindex="-1"></a>domain <span class="op">=</span> <span class="st">"my_domain"</span></span>
<span id="cb84-4"><a href="#cb84-4" aria-hidden="true" tabindex="-1"></a>port <span class="op">=</span> <span class="dv">8443</span></span>
<span id="cb84-5"><a href="#cb84-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb84-6"><a href="#cb84-6" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService(base_url<span class="op">=</span><span class="ss">f"https://</span><span class="sc">{</span>domain<span class="sc">}</span><span class="ss">:</span><span class="sc">{</span>port<span class="sc">}</span><span class="ss">/myService"</span>)</span></code></pre></div>
<p>By default, <code>base_url</code> corresponds to the
URL specified when the Python SDK was
exported/dumped.</p>
<h3 data-number="6.2.2" id="verify_tls_cert"><span
class="header-section-number">6.2.2</span>
verify_tls_cert</h3>
<p><code>verify_tls_cert</code> is a service constructor
option that allows you to customize the configuration of
the TLS/SSL context that is created alongside the
service. This option can be used to disable TLS/SSL CA
certificate (cert) verification or specify what cert(s)
should be loaded during the verification.</p>
<p><strong>TLS/SSL cert(s) verification is enabled by
default</strong>, in this regard, if
<code>verify_tls_cert</code> is never set, or set as
<code>True</code> explicitly, TLS/SSL cert verification
is enabled and a set of default “certification
authority” (CA) certificates from default locations are
loaded (see <a
href="https://docs.python.org/3/library/ssl.html#ssl.SSLContext.load_default_certs">TLS/SSL
default certs</a>).</p>
<div class="sourceCode" id="cb85"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb85-1"><a href="#cb85-1" aria-hidden="true" tabindex="-1"></a><span class="co"># default behavior</span></span>
<span id="cb85-2"><a href="#cb85-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb85-3"><a href="#cb85-3" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService</span>
<span id="cb85-4"><a href="#cb85-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb85-5"><a href="#cb85-5" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb85-6"><a href="#cb85-6" aria-hidden="true" tabindex="-1"></a><span class="co"># print(my_service.tls_context.verify_mode)</span></span>
<span id="cb85-7"><a href="#cb85-7" aria-hidden="true" tabindex="-1"></a><span class="co"># ------------------------------</span></span>
<span id="cb85-8"><a href="#cb85-8" aria-hidden="true" tabindex="-1"></a><span class="co"># True</span></span></code></pre></div>
<p><strong>To customize what CA certificates should be
loaded</strong>, instead of relying on the default
behavior, <code>verify_tls_cert</code> must be specified
as a path-like string (the string can be the path to a
CA certificate file, or it can be the path to a folder
containing several CA certificates). The file(s)
referenced by the specified path-like string are loaded
during TLS/SSL cert verification. Certificates should be
in PEM format, following an <a
href="https://docs.openssl.org/master/man3/SSL_CTX_load_verify_locations/">OpenSSL
specific layout</a>.</p>
<div class="sourceCode" id="cb86"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb86-1"><a href="#cb86-1" aria-hidden="true" tabindex="-1"></a><span class="co"># customize what CA certificates should be loaded</span></span>
<span id="cb86-2"><a href="#cb86-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb86-3"><a href="#cb86-3" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService</span>
<span id="cb86-4"><a href="#cb86-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb86-5"><a href="#cb86-5" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService(verify_tls_cert<span class="op">=</span><span class="st">"/path/to/certfile"</span>)</span>
<span id="cb86-6"><a href="#cb86-6" aria-hidden="true" tabindex="-1"></a><span class="co"># print(my_service.tls_context.verify_mode)</span></span>
<span id="cb86-7"><a href="#cb86-7" aria-hidden="true" tabindex="-1"></a><span class="co"># ------------------------------</span></span>
<span id="cb86-8"><a href="#cb86-8" aria-hidden="true" tabindex="-1"></a><span class="co"># True</span></span></code></pre></div>
<p>Finally, <strong>to disable TLS/SSL cert(s)
verification</strong>, <code>verify tls cert</code> must
be specified as <code>False</code>.</p>
<div class="sourceCode" id="cb87"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb87-1"><a href="#cb87-1" aria-hidden="true" tabindex="-1"></a><span class="co"># disable TLS/SSL cert(s) verification</span></span>
<span id="cb87-2"><a href="#cb87-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb87-3"><a href="#cb87-3" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService</span>
<span id="cb87-4"><a href="#cb87-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb87-5"><a href="#cb87-5" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService(verify_tls_cert<span class="op">=</span><span class="va">False</span>)</span>
<span id="cb87-6"><a href="#cb87-6" aria-hidden="true" tabindex="-1"></a><span class="co"># print(my_service.tls_context.verify_mode)</span></span>
<span id="cb87-7"><a href="#cb87-7" aria-hidden="true" tabindex="-1"></a><span class="co"># ------------------------------</span></span>
<span id="cb87-8"><a href="#cb87-8" aria-hidden="true" tabindex="-1"></a><span class="co"># False</span></span></code></pre></div>
<h3 data-number="6.2.3" id="tls_context"><span
class="header-section-number">6.2.3</span>
tls_context</h3>
<p><code>tls_context</code> is a service-level property
that gets the TLS/SSL context configured for the
service, which is used when executing HTTPS requests.
The TLS/SSL context configuration depends on how
<code>verify_tls_cert</code> is set when the service is
created, see <a
href="#verify_tls_cert">verify_tls_cert</a>.</p>
<h4 data-number="6.2.3.1"
id="return-type-tls_context"><span
class="header-section-number">6.2.3.1</span> Return Type
(tls_context)</h4>
<p>An <code>ssl.SSLContext</code> instance.</p>
<h4 data-number="6.2.3.2" id="example-tls_context"><span
class="header-section-number">6.2.3.2</span> Example
(tls_context)</h4>
<div class="sourceCode" id="cb88"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb88-1"><a href="#cb88-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService</span>
<span id="cb88-2"><a href="#cb88-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb88-3"><a href="#cb88-3" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb88-4"><a href="#cb88-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb88-5"><a href="#cb88-5" aria-hidden="true" tabindex="-1"></a>tls_context <span class="op">=</span> my_service.tls_context</span>
<span id="cb88-6"><a href="#cb88-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb88-7"><a href="#cb88-7" aria-hidden="true" tabindex="-1"></a><span class="co"># print(tls_context.verify_mode)</span></span>
<span id="cb88-8"><a href="#cb88-8" aria-hidden="true" tabindex="-1"></a><span class="co"># ------------------------------</span></span>
<span id="cb88-9"><a href="#cb88-9" aria-hidden="true" tabindex="-1"></a><span class="co"># True</span></span></code></pre></div>
<h3 data-number="6.2.4"
id="service-get_auth_apps-py"><span
class="header-section-number">6.2.4</span>
Service.get_auth_apps</h3>
<p><code>get_auth_apps()</code> is a service-level
command that enables users to get a list containing the
authentication apps and vendor IDs registered for the
given service.</p>
<h4 data-number="6.2.4.1"
id="options-get_auth_apps"><span
class="header-section-number">6.2.4.1</span> Options
(get_auth_apps)</h4>
<p>This command expects no input from the calling
application.</p>
<h4 data-number="6.2.4.2"
id="return-type-get_auth_apps"><span
class="header-section-number">6.2.4.2</span> Return Type
(get_auth_apps)</h4>
<p>A list of dictionaries. Each element in the list is a
<em>2-key</em> dictionary, where keys are
<code>name</code> and <code>vendor_id</code>.</p>
<h4 data-number="6.2.4.3"
id="example-get_auth_apps"><span
class="header-section-number">6.2.4.3</span> Example
(get_auth_apps)</h4>
<div class="sourceCode" id="cb89"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb89-1"><a href="#cb89-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService</span>
<span id="cb89-2"><a href="#cb89-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb89-3"><a href="#cb89-3" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb89-4"><a href="#cb89-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb89-5"><a href="#cb89-5" aria-hidden="true" tabindex="-1"></a>auth_apps <span class="op">=</span> <span class="cf">await</span> my_service.get_auth_apps()</span>
<span id="cb89-6"><a href="#cb89-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb89-7"><a href="#cb89-7" aria-hidden="true" tabindex="-1"></a><span class="co"># print(auth_apps)</span></span>
<span id="cb89-8"><a href="#cb89-8" aria-hidden="true" tabindex="-1"></a><span class="co"># ----------------</span></span>
<span id="cb89-9"><a href="#cb89-9" aria-hidden="true" tabindex="-1"></a><span class="co"># [</span></span>
<span id="cb89-10"><a href="#cb89-10" aria-hidden="true" tabindex="-1"></a><span class="co"># {"name": "MRS", "vendor_id": "0x30000000000000000000000000000000"},</span></span>
<span id="cb89-11"><a href="#cb89-11" aria-hidden="true" tabindex="-1"></a><span class="co"># {"name": "MySQL", "vendor_id": "0x31000000000000000000000000000000"}</span></span>
<span id="cb89-12"><a href="#cb89-12" aria-hidden="true" tabindex="-1"></a><span class="co"># ]</span></span></code></pre></div>
<h3 data-number="6.2.5"
id="service-authenticate-py"><span
class="header-section-number">6.2.5</span>
Service.authenticate</h3>
<p><code>authenticate</code> is a service-level command
that authenticates a user so he/she can work with
restricted MySQL REST Services.</p>
<h4 data-number="6.2.5.1"
id="options-authenticate"><span
class="header-section-number">6.2.5.1</span> Options
(authenticate)</h4>
<table>
<caption>REST Service Options for
Authentication</caption>
<colgroup>
<col style="width: 16%" />
<col style="width: 14%" />
<col style="width: 14%" />
<col style="width: 14%" />
<col style="width: 40%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Argument Name</th>
<th style="text-align: left;">Data Type</th>
<th style="text-align: left;">Required</th>
<th style="text-align: left;">Default</th>
<th style="text-align: left;">Notes</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">app</td>
<td style="text-align: left;"><code>str</code></td>
<td style="text-align: left;">Yes</td>
<td style="text-align: left;">N/A</td>
<td style="text-align: left;">Name of the authentication
application (as specified by the admin).</td>
</tr>
<tr class="even">
<td style="text-align: left;">username</td>
<td style="text-align: left;"><code>str</code></td>
<td style="text-align: left;">Yes</td>
<td style="text-align: left;">N/A</td>
<td style="text-align: left;">User name</td>
</tr>
<tr class="odd">
<td style="text-align: left;">password</td>
<td style="text-align: left;"><code>str</code></td>
<td style="text-align: left;">No</td>
<td style="text-align: left;"><code>""</code></td>
<td style="text-align: left;">If not provided, the empty
string is assumed as the password</td>
</tr>
<tr class="even">
<td style="text-align: left;">vendor_id</td>
<td style="text-align: left;"><code>str</code></td>
<td style="text-align: left;">No</td>
<td style="text-align: left;"><code>None</code></td>
<td style="text-align: left;">ID of the underlying
authentication mechanism. Specifying the vendor ID
avoids an additional round-trip to the server</td>
</tr>
</tbody>
</table>
<p>The following authentication app vendors are
supported:</p>
<ul>
<li><em>MRS</em></li>
<li><em>MySQL Internal</em></li>
</ul>
<h4 data-number="6.2.5.2"
id="return-type-authenticate"><span
class="header-section-number">6.2.5.2</span> Return Type
(authenticate)</h4>
<p>This command returns nothing.</p>
<h4 data-number="6.2.5.3" id="raises-authenticate"><span
class="header-section-number">6.2.5.3</span> Raises
(authenticate)</h4>
<p><code>AuthenticationError</code> if something goes
wrong during the authentication workflow.</p>
<h4 data-number="6.2.5.4"
id="example-authenticate"><span
class="header-section-number">6.2.5.4</span> Example
(authenticate)</h4>
<div class="sourceCode" id="cb90"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb90-1"><a href="#cb90-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService</span>
<span id="cb90-2"><a href="#cb90-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb90-3"><a href="#cb90-3" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb90-4"><a href="#cb90-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb90-5"><a href="#cb90-5" aria-hidden="true" tabindex="-1"></a><span class="co"># `authenticate` will account for authentication</span></span>
<span id="cb90-6"><a href="#cb90-6" aria-hidden="true" tabindex="-1"></a> <span class="cf">await</span> my_service.authenticate(</span>
<span id="cb90-7"><a href="#cb90-7" aria-hidden="true" tabindex="-1"></a> app<span class="op">=</span><span class="st">"MySQL"</span>,</span>
<span id="cb90-8"><a href="#cb90-8" aria-hidden="true" tabindex="-1"></a> username<span class="op">=</span><span class="st">"Lucas"</span>,</span>
<span id="cb90-9"><a href="#cb90-9" aria-hidden="true" tabindex="-1"></a> password<span class="op">=</span><span class="st">"S3cr3t"</span>,</span>
<span id="cb90-10"><a href="#cb90-10" aria-hidden="true" tabindex="-1"></a> vendor_id<span class="op">=</span><span class="st">"0x31000000000000000000000000000000"</span></span>
<span id="cb90-11"><a href="#cb90-11" aria-hidden="true" tabindex="-1"></a>)</span>
<span id="cb90-12"><a href="#cb90-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb90-13"><a href="#cb90-13" aria-hidden="true" tabindex="-1"></a><span class="co"># Service is ready and tied database objects can be utilized</span></span>
<span id="cb90-14"><a href="#cb90-14" aria-hidden="true" tabindex="-1"></a><span class="co"># E.g., calling a function</span></span>
<span id="cb90-15"><a href="#cb90-15" aria-hidden="true" tabindex="-1"></a>res <span class="op">=</span> <span class="cf">await</span> my_service.sakila.hello_func.call(name<span class="op">=</span><span class="st">"Rui"</span>)</span>
<span id="cb90-16"><a href="#cb90-16" aria-hidden="true" tabindex="-1"></a><span class="co"># print(res) -> Hello, Rui!</span></span></code></pre></div>
<p>When <code>vendor_id</code> is not specified, a
vendor ID lookup is performed. The vendor ID that
matches the given <code>app</code> is picked and used
down the road. If not a match takes place, an
<code>AuthenticationError</code> exception is
raised.</p>
<p>In the case the vendor ID is not specified, and a
nonexisting app is provided, an
<code>AuthenticationError</code> exception is
raised.</p>
<p>Also, in the case the vendor ID is specified
alongside a nonexisting app, there will not be a lookup.
This means that if, by accident, or not, there is no
authentication app from the specified
<code>vendor_id</code> with the given <code>app</code>,
an <code>AuthenticationError</code> exception is
returned to the application.</p>
<h3 data-number="6.2.6"
id="service-deauthenticate-py"><span
class="header-section-number">6.2.6</span>
Service.deauthenticate</h3>
<p><code>deauthenticate</code> is a service-level
command that logs you out from authenticated MySQL REST
Services.</p>
<h4 data-number="6.2.6.1"
id="options-deauthenticate"><span
class="header-section-number">6.2.6.1</span> Options
(deauthenticate)</h4>
<p>This command expects no input from the calling
application.</p>
<h4 data-number="6.2.6.2"
id="return-type-deauthenticate"><span
class="header-section-number">6.2.6.2</span> Return Type
(deauthenticate)</h4>
<p>This command returns nothing.</p>
<h4 data-number="6.2.6.3"
id="raises-deauthenticate"><span
class="header-section-number">6.2.6.3</span> Raises
(deauthenticate)</h4>
<p><code>DeauthenticationError</code> if no user is
currently authenticated.</p>
<h4 data-number="6.2.6.4"
id="example-deauthenticate"><span
class="header-section-number">6.2.6.4</span> Example
(deauthenticate)</h4>
<div class="sourceCode" id="cb91"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb91-1"><a href="#cb91-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService</span>
<span id="cb91-2"><a href="#cb91-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb91-3"><a href="#cb91-3" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb91-4"><a href="#cb91-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb91-5"><a href="#cb91-5" aria-hidden="true" tabindex="-1"></a><span class="co"># Log in - `authenticate` will account for authentication</span></span>
<span id="cb91-6"><a href="#cb91-6" aria-hidden="true" tabindex="-1"></a> <span class="cf">await</span> my_service.authenticate(</span>
<span id="cb91-7"><a href="#cb91-7" aria-hidden="true" tabindex="-1"></a> app<span class="op">=</span><span class="st">"MySQL"</span>,</span>
<span id="cb91-8"><a href="#cb91-8" aria-hidden="true" tabindex="-1"></a> username<span class="op">=</span><span class="st">"Lucas"</span>,</span>
<span id="cb91-9"><a href="#cb91-9" aria-hidden="true" tabindex="-1"></a> password<span class="op">=</span><span class="st">"S3cr3t"</span></span>
<span id="cb91-10"><a href="#cb91-10" aria-hidden="true" tabindex="-1"></a>)</span>
<span id="cb91-11"><a href="#cb91-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb91-12"><a href="#cb91-12" aria-hidden="true" tabindex="-1"></a><span class="co"># Call a function</span></span>
<span id="cb91-13"><a href="#cb91-13" aria-hidden="true" tabindex="-1"></a>res <span class="op">=</span> <span class="cf">await</span> my_service.sakila.hello_func.call(name<span class="op">=</span><span class="st">"Oscar"</span>)</span>
<span id="cb91-14"><a href="#cb91-14" aria-hidden="true" tabindex="-1"></a><span class="co"># print(res) -> Hello, Oscar!</span></span>
<span id="cb91-15"><a href="#cb91-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb91-16"><a href="#cb91-16" aria-hidden="true" tabindex="-1"></a><span class="co"># Log out</span></span>
<span id="cb91-17"><a href="#cb91-17" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> my_service.deauthenticate()</span>
<span id="cb91-18"><a href="#cb91-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb91-19"><a href="#cb91-19" aria-hidden="true" tabindex="-1"></a><span class="co"># Calling the function again - you should get an HTTP 401 (Unauthorized) error</span></span>
<span id="cb91-20"><a href="#cb91-20" aria-hidden="true" tabindex="-1"></a>res <span class="op">=</span> <span class="cf">await</span> my_service.sakila.hello_func.call(name<span class="op">=</span><span class="st">"Rui"</span>)</span>
<span id="cb91-21"><a href="#cb91-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb91-22"><a href="#cb91-22" aria-hidden="true" tabindex="-1"></a><span class="co"># Log out again - you should get an `ServiceNotAuthenticatedError` exception</span></span>
<span id="cb91-23"><a href="#cb91-23" aria-hidden="true" tabindex="-1"></a><span class="cf">await</span> my_service.deauthenticate()</span></code></pre></div>
<h2 data-number="6.3" id="rest-schemas"><span
class="header-section-number">6.3</span> REST
Schemas</h2>
<p>In the Python SDK, database objects such as tables
and functions are grouped under namespaces that
correspond to their schema. Applications can access and
use those database objects via the API exposed by each
one.</p>
<p>The following REST resources can be accessed from the
corresponding schema namespace:</p>
<ul>
<li><a href="#rest-views">REST Views</a></li>
<li><a href="#rest-documents">REST Documents</a></li>
<li><a href="#rest-functions">REST Functions</a></li>
<li><a href="#rest-procedures">REST Procedures</a></li>
</ul>
<h2 data-number="6.4" id="rest-views"><span
class="header-section-number">6.4</span> REST Views</h2>
<h3 data-number="6.4.1" id="view-create-py"><span
class="header-section-number">6.4.1</span> View.create
</h3>
<p><code>create</code> is used to insert a record (a
REST document) into the database. The REST document is
represented as a typed dictionary object whose fields,
or keys, should comply with the interface exposed by the
type definition <code>INew${obj_class_name}</code> where
<code>${obj_class_name}</code> is a variable containing
a string which is a fully-qualified name composed by the
names of the <em>REST Service</em>, <em>REST Schema</em>
and <em>REST View</em> themselves.</p>
<blockquote>
<p>To insert multiple documents, see <a
href="#create_many">create_many</a>.</p>
</blockquote>
<h4 data-number="6.4.1.1" id="options-create"><span
class="header-section-number">6.4.1.1</span> Options
(create)</h4>
<table>
<caption>REST Views Options (create)</caption>
<colgroup>
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 70%" />
</colgroup>
<thead>
<tr class="header">
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>data</td>
<td>TypedDict</td>
<td>Yes</td>
<td>Object containing the mapping between column names
and values for the record to be inserted</td>
</tr>
</tbody>
</table>
<h4 data-number="6.4.1.2" id="return-type-create"><span
class="header-section-number">6.4.1.2</span> Return Type
(create)</h4>
<p>A REST document data class object representing the
record that was inserted. For more details about REST
documents, check the <a href="#rest-documents">REST
Documents</a> section.</p>
<h4 data-number="6.4.1.3" id="example-create"><span
class="header-section-number">6.4.1.3</span> Example
(create)</h4>
<div class="sourceCode" id="cb92"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb92-1"><a href="#cb92-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python.my_service <span class="im">import</span> IMyServiceSakilaActor <span class="im">as</span> Actor, MyService</span>
<span id="cb92-2"><a href="#cb92-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb92-3"><a href="#cb92-3" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb92-4"><a href="#cb92-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb92-5"><a href="#cb92-5" aria-hidden="true" tabindex="-1"></a>actor: Actor <span class="op">=</span> <span class="cf">await</span> my_service.sakila.actor.create(</span>
<span id="cb92-6"><a href="#cb92-6" aria-hidden="true" tabindex="-1"></a> data<span class="op">=</span>{</span>
<span id="cb92-7"><a href="#cb92-7" aria-hidden="true" tabindex="-1"></a> <span class="st">"first_name"</span>: <span class="st">"FOO"</span>,</span>
<span id="cb92-8"><a href="#cb92-8" aria-hidden="true" tabindex="-1"></a> <span class="st">"last_name"</span>: <span class="st">"BAR"</span>,</span>
<span id="cb92-9"><a href="#cb92-9" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb92-10"><a href="#cb92-10" aria-hidden="true" tabindex="-1"></a>)</span>
<span id="cb92-11"><a href="#cb92-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb92-12"><a href="#cb92-12" aria-hidden="true" tabindex="-1"></a><span class="bu">print</span>(actor)</span>
<span id="cb92-13"><a href="#cb92-13" aria-hidden="true" tabindex="-1"></a><span class="co"># IMyServiceSakilaActor(actor_id=35000, first_name='FOO', last_name='BAR', last_update='2024-06-04 10:14:33.000000')</span></span></code></pre></div>
<p>The <code>actor_id</code> and
<code>last_update</code> columns from the
<code>sakila</code> table on the sample <a
href="https://dev.mysql.com/doc/sakila/en/">sakila
database</a> are automatically generated on each insert,
which means they can be omitted.</p>
<h3 data-number="6.4.2" id="view-create_many-py"><span
class="header-section-number">6.4.2</span>
View.create_many</h3>
<p><code>create_many</code> is used to insert one or
more records (REST documents) into the database. A
record is represented as a typed dictionary object whose
fields, or keys, should comply with the interface
exposed by the type definition
<code>INew${obj_class_name}</code> where
<code>${obj_class_name}</code> is a variable which value
depends on the <em>service, schema and table</em> names
themselves.</p>
<blockquote>
<p>To insert a single record, see <a
href="#create">create</a>.</p>
</blockquote>
<h4 data-number="6.4.2.1" id="options-create_many"><span
class="header-section-number">6.4.2.1</span> Options
(create_many)</h4>
<table>
<caption>REST Views Options (create_many)</caption>
<colgroup>
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 70%" />
</colgroup>
<thead>
<tr class="header">
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>data</td>
<td>Sequence of <code>TypedDict</code> - it can be any
Python object supporting the iteration protocol, such as
lists and tuples</td>
<td>Yes</td>
<td>List of objects containing the mapping between
column names and values for the records to be
inserted</td>
</tr>
</tbody>
</table>
<h4 data-number="6.4.2.2"
id="return-type-create_many"><span
class="header-section-number">6.4.2.2</span> Return Type
(create_many)</h4>
<p>A list of REST document data class objects
representing each record that was inserted. For more
details about REST documents, check the <a
href="#rest-documents">REST Documents</a> section.</p>
<h4 data-number="6.4.2.3" id="example-create_many"><span
class="header-section-number">6.4.2.3</span> Example
(create_many)</h4>
<div class="sourceCode" id="cb93"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb93-1"><a href="#cb93-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python.my_service <span class="im">import</span> IMyServiceSakilaActor <span class="im">as</span> Actor, MyService</span>
<span id="cb93-2"><a href="#cb93-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb93-3"><a href="#cb93-3" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb93-4"><a href="#cb93-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb93-5"><a href="#cb93-5" aria-hidden="true" tabindex="-1"></a>actors: <span class="bu">list</span>[Actor] <span class="op">=</span> <span class="cf">await</span> my_service.sakila.actor.create_many(</span>
<span id="cb93-6"><a href="#cb93-6" aria-hidden="true" tabindex="-1"></a> data<span class="op">=</span>[</span>
<span id="cb93-7"><a href="#cb93-7" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb93-8"><a href="#cb93-8" aria-hidden="true" tabindex="-1"></a> <span class="st">"first_name"</span>: <span class="st">"FOO"</span>,</span>
<span id="cb93-9"><a href="#cb93-9" aria-hidden="true" tabindex="-1"></a> <span class="st">"last_name"</span>: <span class="st">"BAR"</span>,</span>
<span id="cb93-10"><a href="#cb93-10" aria-hidden="true" tabindex="-1"></a> },</span>
<span id="cb93-11"><a href="#cb93-11" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb93-12"><a href="#cb93-12" aria-hidden="true" tabindex="-1"></a> <span class="st">"first_name"</span>: <span class="st">"OOF"</span>,</span>
<span id="cb93-13"><a href="#cb93-13" aria-hidden="true" tabindex="-1"></a> <span class="st">"last_name"</span>: <span class="st">"RAB"</span>,</span>
<span id="cb93-14"><a href="#cb93-14" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb93-15"><a href="#cb93-15" aria-hidden="true" tabindex="-1"></a> ]</span>
<span id="cb93-16"><a href="#cb93-16" aria-hidden="true" tabindex="-1"></a>)</span>
<span id="cb93-17"><a href="#cb93-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb93-18"><a href="#cb93-18" aria-hidden="true" tabindex="-1"></a><span class="bu">print</span>(actors)</span>
<span id="cb93-19"><a href="#cb93-19" aria-hidden="true" tabindex="-1"></a><span class="co"># [</span></span>
<span id="cb93-20"><a href="#cb93-20" aria-hidden="true" tabindex="-1"></a><span class="co"># IMyServiceSakilaActor(</span></span>
<span id="cb93-21"><a href="#cb93-21" aria-hidden="true" tabindex="-1"></a><span class="co"># actor_id=35000,</span></span>
<span id="cb93-22"><a href="#cb93-22" aria-hidden="true" tabindex="-1"></a><span class="co"># first_name='FOO',</span></span>
<span id="cb93-23"><a href="#cb93-23" aria-hidden="true" tabindex="-1"></a><span class="co"># last_name='BAR',</span></span>
<span id="cb93-24"><a href="#cb93-24" aria-hidden="true" tabindex="-1"></a><span class="co"># last_update='2024-06-04 10:14:33.000000'</span></span>
<span id="cb93-25"><a href="#cb93-25" aria-hidden="true" tabindex="-1"></a><span class="co"># ),</span></span>
<span id="cb93-26"><a href="#cb93-26" aria-hidden="true" tabindex="-1"></a><span class="co"># IMyServiceSakilaActor(</span></span>
<span id="cb93-27"><a href="#cb93-27" aria-hidden="true" tabindex="-1"></a><span class="co"># actor_id=36000,</span></span>
<span id="cb93-28"><a href="#cb93-28" aria-hidden="true" tabindex="-1"></a><span class="co"># first_name='OOF',</span></span>
<span id="cb93-29"><a href="#cb93-29" aria-hidden="true" tabindex="-1"></a><span class="co"># last_name='RAB',</span></span>
<span id="cb93-30"><a href="#cb93-30" aria-hidden="true" tabindex="-1"></a><span class="co"># last_update='2024-08-04 10:14:33.000000'</span></span>
<span id="cb93-31"><a href="#cb93-31" aria-hidden="true" tabindex="-1"></a><span class="co"># )</span></span>
<span id="cb93-32"><a href="#cb93-32" aria-hidden="true" tabindex="-1"></a><span class="co"># ]</span></span></code></pre></div>
<p>The <code>actor_id</code> and
<code>last_update</code> columns from the
<code>sakila</code> table on the sample <a
href="https://dev.mysql.com/doc/sakila/en/">sakila
database</a> are automatically generated on each insert,
which means they can be omitted.</p>
<h3 data-number="6.4.3" id="view-find_first-py"><span
class="header-section-number">6.4.3</span>
View.find_first</h3>
<p><code>find_first</code> is used to query the first
REST document (<strong>in no specific order</strong>)
that matches a given optional filter. It returns
<code>None</code> if no document is found.</p>
<blockquote>
<p>To raise an exception if there are no matches, use <a
href="#find_first_or_throw">find_first_or_throw</a>
instead.</p>
<p>To find multiple REST documents, see <a
href="#find">find</a>.</p>
</blockquote>
<h4 data-number="6.4.3.1" id="options-find_first"><span
class="header-section-number">6.4.3.1</span> Options
(find_first)</h4>
<table>
<caption>REST Views Options (find_first)</caption>
<colgroup>
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 70%" />
</colgroup>
<thead>
<tr class="header">
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>select</td>
<td>dict or list</td>
<td>No</td>
<td>Specifies which properties to include or exclude on
the returned document - works as a <em>field
filter</em></td>
</tr>
<tr class="even">
<td>where</td>
<td>dict</td>
<td>No</td>
<td>Applies filtering conditions based on specific
fields - works as a <em>document filter</em></td>
</tr>
<tr class="odd">
<td>skip</td>
<td>int</td>
<td>No</td>
<td>Specifies how many documents to skip before
returning one of the matches</td>
</tr>
<tr class="even">
<td>order_by</td>
<td>dict</td>
<td>No</td>
<td>Lets you customize the order (<code>ASC</code> or
<code>DESC</code>) in which the documents are returned
based on specific fields</td>
</tr>
<tr class="odd">
<td>cursor</td>
<td>dict</td>
<td>No</td>
<td>Specifies the position of the first item to include
in the result set. A cursor bookmarks a location in a
result set and must be a column containing unique and
sequential values.</td>
</tr>
<tr class="even">
<td>read_own_writes</td>
<td>bool</td>
<td>No</td>
<td>Ensures read consistency for a cluster of servers -
<code>False</code> is used by default</td>
</tr>
</tbody>
</table>
<blockquote>
<p>Cursor-based pagination takes precedence over
offset-based pagination, which means that if a cursor is
defined, the value of the offset property
(<code>skip</code>) will be ignored.</p>
</blockquote>
<h4 data-number="6.4.3.2"
id="return-type-find_first"><span
class="header-section-number">6.4.3.2</span> Return Type
(find_first)</h4>
<p>If there is a match, a REST document data class
object meeting the filter conditions, otherwise
<code>None</code> is returned. For more details about
REST documents, check the <a href="#rest-documents">REST
Documents</a> section.</p>
<h4 data-number="6.4.3.3" id="example-find_first"><span
class="header-section-number">6.4.3.3</span> Example
(find_first)</h4>
<p>Consider the following generic usage snippet of
<code>find_first</code>:</p>
<div class="sourceCode" id="cb94"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb94-1"><a href="#cb94-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python.my_service <span class="im">import</span> IMyServiceSakilaActor <span class="im">as</span> Actor, MyService</span>
<span id="cb94-2"><a href="#cb94-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb94-3"><a href="#cb94-3" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb94-4"><a href="#cb94-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb94-5"><a href="#cb94-5" aria-hidden="true" tabindex="-1"></a>actor: Optional[Actor] <span class="op">=</span> <span class="cf">await</span> <span class="va">self</span>.my_service.sakila.actor.find_first(</span>
<span id="cb94-6"><a href="#cb94-6" aria-hidden="true" tabindex="-1"></a> select<span class="op">=</span>{<span class="st">"last_name"</span>: <span class="va">False</span>},</span>
<span id="cb94-7"><a href="#cb94-7" aria-hidden="true" tabindex="-1"></a> where<span class="op">=</span>{<span class="st">"first_name"</span>: {<span class="st">"like"</span>: <span class="st">"</span><span class="sc">%%</span><span class="st">ED</span><span class="sc">%%</span><span class="st">"</span>}},</span>
<span id="cb94-8"><a href="#cb94-8" aria-hidden="true" tabindex="-1"></a> .</span>
<span id="cb94-9"><a href="#cb94-9" aria-hidden="true" tabindex="-1"></a> .</span>
<span id="cb94-10"><a href="#cb94-10" aria-hidden="true" tabindex="-1"></a>)</span></code></pre></div>
<p>In the following subsections, a small usage example
is included for each option.</p>
<h5 data-number="6.4.3.3.1" id="select-find_first"><span
class="header-section-number">6.4.3.3.1</span> Select
(find_first)</h5>
<div class="sourceCode" id="cb95"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb95-1"><a href="#cb95-1" aria-hidden="true" tabindex="-1"></a><span class="co"># Only include the fields specified (`list` use case)</span></span>
<span id="cb95-2"><a href="#cb95-2" aria-hidden="true" tabindex="-1"></a>select<span class="op">=</span>[<span class="st">"last_update"</span>]</span>
<span id="cb95-3"><a href="#cb95-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb95-4"><a href="#cb95-4" aria-hidden="true" tabindex="-1"></a><span class="co"># Only include the fields specified (`dict` use case)</span></span>
<span id="cb95-5"><a href="#cb95-5" aria-hidden="true" tabindex="-1"></a>select<span class="op">=</span>{<span class="st">"last_name"</span>: <span class="va">True</span>}</span>
<span id="cb95-6"><a href="#cb95-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb95-7"><a href="#cb95-7" aria-hidden="true" tabindex="-1"></a><span class="co"># Include all fields but the specified</span></span>
<span id="cb95-8"><a href="#cb95-8" aria-hidden="true" tabindex="-1"></a>select<span class="op">=</span>{<span class="st">"last_name"</span>: <span class="va">False</span>}</span></code></pre></div>
<h5 data-number="6.4.3.3.2" id="where-find_first"><span
class="header-section-number">6.4.3.3.2</span> Where
(find_first)</h5>
<div class="sourceCode" id="cb96"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb96-1"><a href="#cb96-1" aria-hidden="true" tabindex="-1"></a><span class="co"># Equality - these two are equivalent</span></span>
<span id="cb96-2"><a href="#cb96-2" aria-hidden="true" tabindex="-1"></a>where<span class="op">=</span>{<span class="st">"actor_id"</span>: <span class="dv">3</span>}</span>
<span id="cb96-3"><a href="#cb96-3" aria-hidden="true" tabindex="-1"></a>where<span class="op">=</span>{<span class="st">"actor_id"</span>: {<span class="st">"equals"</span>: <span class="dv">3</span>}}</span>
<span id="cb96-4"><a href="#cb96-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb96-5"><a href="#cb96-5" aria-hidden="true" tabindex="-1"></a><span class="co"># Difference</span></span>
<span id="cb96-6"><a href="#cb96-6" aria-hidden="true" tabindex="-1"></a>where<span class="op">=</span>{<span class="st">"last_name"</span>: {<span class="st">"ne"</span>: <span class="st">"Pacheco"</span>}}</span>
<span id="cb96-7"><a href="#cb96-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb96-8"><a href="#cb96-8" aria-hidden="true" tabindex="-1"></a><span class="co"># Greater than</span></span>
<span id="cb96-9"><a href="#cb96-9" aria-hidden="true" tabindex="-1"></a>where<span class="op">=</span>{<span class="st">"actor_id"</span>: {<span class="st">"gt"</span>: <span class="dv">3</span>}}</span>
<span id="cb96-10"><a href="#cb96-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb96-11"><a href="#cb96-11" aria-hidden="true" tabindex="-1"></a><span class="co"># Greater than or equal</span></span>
<span id="cb96-12"><a href="#cb96-12" aria-hidden="true" tabindex="-1"></a>where<span class="op">=</span>{<span class="st">"actor_id"</span>: {<span class="st">"gte"</span>: <span class="dv">3</span>}}</span>
<span id="cb96-13"><a href="#cb96-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb96-14"><a href="#cb96-14" aria-hidden="true" tabindex="-1"></a><span class="co"># Lower than</span></span>
<span id="cb96-15"><a href="#cb96-15" aria-hidden="true" tabindex="-1"></a>where<span class="op">=</span>{<span class="st">"actor_id"</span>: {<span class="st">"lt"</span>: <span class="dv">3</span>}}</span>
<span id="cb96-16"><a href="#cb96-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb96-17"><a href="#cb96-17" aria-hidden="true" tabindex="-1"></a><span class="co"># Lower than or equal</span></span>
<span id="cb96-18"><a href="#cb96-18" aria-hidden="true" tabindex="-1"></a>where<span class="op">=</span>{<span class="st">"actor_id"</span>: {<span class="st">"lte"</span>: <span class="dv">3</span>}}</span>
<span id="cb96-19"><a href="#cb96-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb96-20"><a href="#cb96-20" aria-hidden="true" tabindex="-1"></a><span class="co"># Leads to a match when the field is not NULL.</span></span>
<span id="cb96-21"><a href="#cb96-21" aria-hidden="true" tabindex="-1"></a><span class="co"># In this case, we would get documents where the</span></span>
<span id="cb96-22"><a href="#cb96-22" aria-hidden="true" tabindex="-1"></a><span class="co"># field `last_update` is not NULL.</span></span>
<span id="cb96-23"><a href="#cb96-23" aria-hidden="true" tabindex="-1"></a>where<span class="op">=</span>{<span class="st">"last_updated"</span>: {<span class="st">"not"</span>: <span class="va">None</span>}}</span>
<span id="cb96-24"><a href="#cb96-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb96-25"><a href="#cb96-25" aria-hidden="true" tabindex="-1"></a><span class="co"># Pattern</span></span>
<span id="cb96-26"><a href="#cb96-26" aria-hidden="true" tabindex="-1"></a>where<span class="op">=</span>{<span class="st">"first_name"</span>: {<span class="st">"like"</span>: <span class="st">"</span><span class="sc">%%</span><span class="st">ED</span><span class="sc">%%</span><span class="st">"</span>}}</span>
<span id="cb96-27"><a href="#cb96-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb96-28"><a href="#cb96-28" aria-hidden="true" tabindex="-1"></a><span class="co"># Union of conditions</span></span>
<span id="cb96-29"><a href="#cb96-29" aria-hidden="true" tabindex="-1"></a>where<span class="op">=</span>{</span>
<span id="cb96-30"><a href="#cb96-30" aria-hidden="true" tabindex="-1"></a> <span class="st">"AND"</span>: [</span>
<span id="cb96-31"><a href="#cb96-31" aria-hidden="true" tabindex="-1"></a> {<span class="st">"first_name"</span>: <span class="st">"PENELOPE"</span>},</span>
<span id="cb96-32"><a href="#cb96-32" aria-hidden="true" tabindex="-1"></a> {<span class="st">"actor_id"</span>: {<span class="st">"gte"</span>: <span class="dv">3</span>}}</span>
<span id="cb96-33"><a href="#cb96-33" aria-hidden="true" tabindex="-1"></a> ]</span>
<span id="cb96-34"><a href="#cb96-34" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb96-35"><a href="#cb96-35" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb96-36"><a href="#cb96-36" aria-hidden="true" tabindex="-1"></a><span class="co"># Intersection of conditions</span></span>
<span id="cb96-37"><a href="#cb96-37" aria-hidden="true" tabindex="-1"></a>where<span class="op">=</span>{</span>
<span id="cb96-38"><a href="#cb96-38" aria-hidden="true" tabindex="-1"></a> <span class="st">"OR"</span>: [</span>
<span id="cb96-39"><a href="#cb96-39" aria-hidden="true" tabindex="-1"></a> {<span class="st">"first_name"</span>: <span class="st">"MICHAEL"</span>},</span>
<span id="cb96-40"><a href="#cb96-40" aria-hidden="true" tabindex="-1"></a> {<span class="st">"last_name"</span>: {<span class="st">"like"</span>: <span class="st">"</span><span class="sc">%%</span><span class="st">AB</span><span class="sc">%%</span><span class="st">"</span>}}</span>
<span id="cb96-41"><a href="#cb96-41" aria-hidden="true" tabindex="-1"></a> ]</span>
<span id="cb96-42"><a href="#cb96-42" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h5 data-number="6.4.3.3.3" id="skip-find_first"><span
class="header-section-number">6.4.3.3.3</span> Skip
(find_first)</h5>
<p>Offset-based pagination is non-inclusive, meaning
that if the position marking the offset is a match, it
will not be included in the result set.</p>
<p>Suppose the actor table contains a bunch of records
as shown in <a href="#cursor-find_first">Cursor
Example</a>. Then, the <code>skip</code> option can be
used as follows:</p>
<div class="sourceCode" id="cb97"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb97-1"><a href="#cb97-1" aria-hidden="true" tabindex="-1"></a>actor: Optional[Actor] <span class="op">=</span> <span class="cf">await</span> <span class="va">self</span>.my_service.sakila.actor.find_first(</span>
<span id="cb97-2"><a href="#cb97-2" aria-hidden="true" tabindex="-1"></a> where<span class="op">=</span>{<span class="st">"last_name"</span>: {<span class="st">"like"</span>: <span class="st">"</span><span class="sc">%%</span><span class="st">HA</span><span class="sc">%%</span><span class="st">"</span>}}, skip<span class="op">=</span><span class="dv">2</span></span>
<span id="cb97-3"><a href="#cb97-3" aria-hidden="true" tabindex="-1"></a>)</span>
<span id="cb97-4"><a href="#cb97-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb97-5"><a href="#cb97-5" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> actor <span class="kw">is</span> <span class="va">None</span>:</span>
<span id="cb97-6"><a href="#cb97-6" aria-hidden="true" tabindex="-1"></a> warnings.warn(<span class="ss">f"Actor not found"</span>)</span>
<span id="cb97-7"><a href="#cb97-7" aria-hidden="true" tabindex="-1"></a><span class="cf">else</span>:</span>
<span id="cb97-8"><a href="#cb97-8" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(actor.actor_id)</span></code></pre></div>
<p>The printed actor ID would be <code>32</code>.</p>
<h5 data-number="6.4.3.3.4"
id="order-by-find_first"><span
class="header-section-number">6.4.3.3.4</span> Order By
(find_first)</h5>
<div class="sourceCode" id="cb98"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb98-1"><a href="#cb98-1" aria-hidden="true" tabindex="-1"></a><span class="co"># Descending order</span></span>
<span id="cb98-2"><a href="#cb98-2" aria-hidden="true" tabindex="-1"></a>order_by<span class="op">=</span>{<span class="st">"first_name"</span>: <span class="st">"DESC"</span>}</span>
<span id="cb98-3"><a href="#cb98-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb98-4"><a href="#cb98-4" aria-hidden="true" tabindex="-1"></a><span class="co"># Ascending order</span></span>
<span id="cb98-5"><a href="#cb98-5" aria-hidden="true" tabindex="-1"></a>order_by<span class="op">=</span>{<span class="st">"actor_id"</span>: <span class="st">"ASC"</span>}</span></code></pre></div>
<h5 data-number="6.4.3.3.5" id="cursor-find_first"><span
class="header-section-number">6.4.3.3.5</span> Cursor
(find_first)</h5>
<p>The position bookmarked by the cursor is
non-inclusive, meaning that if the bookmarked position
is a match, it will not be included in the result
set.</p>
<p>Suppose the actor table contains a bunch of records.
In the following snippet, only those records where
<code>last_name</code> matches the pattern
<code>%%HA%%</code> are shown:</p>
<div class="sourceCode" id="cb99"><pre
class="sourceCode json"><code class="sourceCode json"><span id="cb99-1"><a href="#cb99-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
<span id="cb99-2"><a href="#cb99-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"actorId"</span><span class="fu">:</span> <span class="dv">1</span><span class="fu">,</span></span>
<span id="cb99-3"><a href="#cb99-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"lastName"</span><span class="fu">:</span> <span class="er">...</span><span class="fu">,</span></span>
<span id="cb99-4"><a href="#cb99-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"firstName"</span><span class="fu">:</span> <span class="er">...</span><span class="fu">,</span></span>
<span id="cb99-5"><a href="#cb99-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"lastUpdate"</span><span class="fu">:</span> <span class="er">...</span><span class="fu">,</span></span>
<span id="cb99-6"><a href="#cb99-6" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span><span class="er">,</span></span>
<span id="cb99-7"><a href="#cb99-7" aria-hidden="true" tabindex="-1"></a><span class="er">...,</span></span>
<span id="cb99-8"><a href="#cb99-8" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
<span id="cb99-9"><a href="#cb99-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"actorId"</span><span class="fu">:</span> <span class="dv">3</span><span class="fu">,</span></span>
<span id="cb99-10"><a href="#cb99-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">"lastName"</span><span class="fu">:</span> <span class="st">"CHASE"</span><span class="fu">,</span></span>
<span id="cb99-11"><a href="#cb99-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">"firstName"</span><span class="fu">:</span> <span class="st">"ED"</span><span class="fu">,</span></span>
<span id="cb99-12"><a href="#cb99-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">"lastUpdate"</span><span class="fu">:</span> <span class="st">"2006-02-15 04:34:33.000000"</span><span class="fu">,</span></span>
<span id="cb99-13"><a href="#cb99-13" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span><span class="er">,</span></span>
<span id="cb99-14"><a href="#cb99-14" aria-hidden="true" tabindex="-1"></a><span class="er">...,</span></span>
<span id="cb99-15"><a href="#cb99-15" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
<span id="cb99-16"><a href="#cb99-16" aria-hidden="true" tabindex="-1"></a> <span class="dt">"actorId"</span><span class="fu">:</span> <span class="dv">8</span><span class="fu">,</span></span>
<span id="cb99-17"><a href="#cb99-17" aria-hidden="true" tabindex="-1"></a> <span class="dt">"lastName"</span><span class="fu">:</span> <span class="st">"JOHANSSON"</span><span class="fu">,</span></span>
<span id="cb99-18"><a href="#cb99-18" aria-hidden="true" tabindex="-1"></a> <span class="dt">"firstName"</span><span class="fu">:</span> <span class="st">"MATTHEW"</span><span class="fu">,</span></span>
<span id="cb99-19"><a href="#cb99-19" aria-hidden="true" tabindex="-1"></a> <span class="dt">"lastUpdate"</span><span class="fu">:</span> <span class="st">"2006-02-15 04:34:33.000000"</span><span class="fu">,</span></span>
<span id="cb99-20"><a href="#cb99-20" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span><span class="er">,</span></span>
<span id="cb99-21"><a href="#cb99-21" aria-hidden="true" tabindex="-1"></a><span class="er">...,</span></span>
<span id="cb99-22"><a href="#cb99-22" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
<span id="cb99-23"><a href="#cb99-23" aria-hidden="true" tabindex="-1"></a> <span class="dt">"actorId"</span><span class="fu">:</span> <span class="dv">32</span><span class="fu">,</span></span>
<span id="cb99-24"><a href="#cb99-24" aria-hidden="true" tabindex="-1"></a> <span class="dt">"lastName"</span><span class="fu">:</span> <span class="st">"HACKMAN"</span><span class="fu">,</span></span>
<span id="cb99-25"><a href="#cb99-25" aria-hidden="true" tabindex="-1"></a> <span class="dt">"firstName"</span><span class="fu">:</span> <span class="st">"TIM"</span><span class="fu">,</span></span>
<span id="cb99-26"><a href="#cb99-26" aria-hidden="true" tabindex="-1"></a> <span class="dt">"lastUpdate"</span><span class="fu">:</span> <span class="st">"2006-02-15 04:34:33.000000"</span><span class="fu">,</span></span>
<span id="cb99-27"><a href="#cb99-27" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
<p>The cursor option can be used as follows:</p>
<div class="sourceCode" id="cb100"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb100-1"><a href="#cb100-1" aria-hidden="true" tabindex="-1"></a>actor: Optional[Actor] <span class="op">=</span> <span class="cf">await</span> <span class="va">self</span>.my_service.sakila.actor.find_first(</span>
<span id="cb100-2"><a href="#cb100-2" aria-hidden="true" tabindex="-1"></a> where<span class="op">=</span>{<span class="st">"last_name"</span>: {<span class="st">"like"</span>: <span class="st">"</span><span class="sc">%%</span><span class="st">HA</span><span class="sc">%%</span><span class="st">"</span>}},</span>
<span id="cb100-3"><a href="#cb100-3" aria-hidden="true" tabindex="-1"></a> cursor<span class="op">=</span>{<span class="st">"actor_id"</span>: <span class="dv">3</span>}, <span class="co"># cursor is exclusive</span></span>
<span id="cb100-4"><a href="#cb100-4" aria-hidden="true" tabindex="-1"></a>)</span>
<span id="cb100-5"><a href="#cb100-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb100-6"><a href="#cb100-6" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> actor <span class="kw">is</span> <span class="va">None</span>:</span>
<span id="cb100-7"><a href="#cb100-7" aria-hidden="true" tabindex="-1"></a> warnings.warn(<span class="ss">f"Actor not found"</span>)</span>
<span id="cb100-8"><a href="#cb100-8" aria-hidden="true" tabindex="-1"></a><span class="cf">else</span>:</span>
<span id="cb100-9"><a href="#cb100-9" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(actor.actor_id)</span></code></pre></div>
<p>The printed actor ID would be <code>8</code>.</p>
<h5 data-number="6.4.3.3.6"
id="read-own-writes-find_first"><span
class="header-section-number">6.4.3.3.6</span> Read Own
Writes (find_first)</h5>
<div class="sourceCode" id="cb101"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb101-1"><a href="#cb101-1" aria-hidden="true" tabindex="-1"></a><span class="co"># ON</span></span>
<span id="cb101-2"><a href="#cb101-2" aria-hidden="true" tabindex="-1"></a>read_own_writes<span class="op">=</span><span class="va">True</span></span>
<span id="cb101-3"><a href="#cb101-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb101-4"><a href="#cb101-4" aria-hidden="true" tabindex="-1"></a><span class="co"># OFF</span></span>
<span id="cb101-5"><a href="#cb101-5" aria-hidden="true" tabindex="-1"></a>read_own_writes<span class="op">=</span><span class="va">False</span></span></code></pre></div>
<h3 data-number="6.4.4"
id="view-find_first_or_throw-py"><span
class="header-section-number">6.4.4</span>
View.find_first_or_throw</h3>
<p><code>find_first_or_throw</code> is used to retrieve
the first REST document that matches a given optional
filter in the same way as <a
href="#find_first">find_first</a> does. However, if the
query does not find a document, it raises a
<code>MrsDocumentNotFoundError</code> exception.</p>
<blockquote>
<p>To not raise an exception and get <code>None</code>
if there are no matches, use <a
href="#find_first">find_first</a> instead.</p>
<p>To find multiple REST documents, see <a
href="#find">find</a>.</p>
</blockquote>
<h4 data-number="6.4.4.1"
id="options-find_first_or_throw"><span
class="header-section-number">6.4.4.1</span> Options
(find_first_or_throw)</h4>
<p><code>find_first_or_throw</code> and
<code>find_first</code> implement the very same options.
For more details about these, see <a
href="#options-find_first">Options (find_first)</a>.</p>
<h4 data-number="6.4.4.2"
id="return-type-find_first_or_throw"><span
class="header-section-number">6.4.4.2</span> Return Type
(find_first_or_throw)</h4>
<p>If there is a match, a REST document data class
object meeting the filter conditions is returned,
otherwise an exception
<code>MrsDocumentNotFoundError</code> is raised. For
more details about REST documents, check the <a
href="#rest-documents">REST Documents</a> section.</p>
<h4 data-number="6.4.4.3"
id="example-find_first_or_throw"><span
class="header-section-number">6.4.4.3</span> Example
(find_first_or_throw)</h4>
<p>Usage is similar to <code>find_first</code>, however,
now you should account for a possible exception:</p>
<div class="sourceCode" id="cb102"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb102-1"><a href="#cb102-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> warnings</span>
<span id="cb102-2"><a href="#cb102-2" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python.my_service <span class="im">import</span> IMyServiceSakilaActor <span class="im">as</span> Actor, MyService, MrsDocumentNotFoundError</span>
<span id="cb102-3"><a href="#cb102-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb102-4"><a href="#cb102-4" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb102-5"><a href="#cb102-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb102-6"><a href="#cb102-6" aria-hidden="true" tabindex="-1"></a><span class="cf">try</span>:</span>
<span id="cb102-7"><a href="#cb102-7" aria-hidden="true" tabindex="-1"></a> actor: Actor <span class="op">=</span> <span class="cf">await</span> <span class="va">self</span>.my_service.sakila.actor.find_first_or_throw(</span>
<span id="cb102-8"><a href="#cb102-8" aria-hidden="true" tabindex="-1"></a> select<span class="op">=</span>{<span class="st">"last_name"</span>: <span class="va">False</span>},</span>
<span id="cb102-9"><a href="#cb102-9" aria-hidden="true" tabindex="-1"></a> where<span class="op">=</span>{<span class="st">"first_name"</span>: {<span class="st">"like"</span>: <span class="st">"</span><span class="sc">%%</span><span class="st">ED</span><span class="sc">%%</span><span class="st">"</span>}},</span>
<span id="cb102-10"><a href="#cb102-10" aria-hidden="true" tabindex="-1"></a> )</span>
<span id="cb102-11"><a href="#cb102-11" aria-hidden="true" tabindex="-1"></a><span class="cf">except</span> MrsDocumentNotFoundError:</span>
<span id="cb102-12"><a href="#cb102-12" aria-hidden="true" tabindex="-1"></a> warnings.warn(<span class="st">"Ups, no matches found"</span>)</span></code></pre></div>
<p>See <a href="#example-find_first">Example
(find_first)</a> for additional usage options.</p>
<h3 data-number="6.4.5" id="view-find_unique-py"><span
class="header-section-number">6.4.5</span>
View.find_unique</h3>
<p><code>find_unique</code> is used to query a single,
uniquely identified REST document by:</p>
<ul>
<li>Primary key column(s)</li>
<li>Unique column(s)</li>
</ul>
<p>It returns <code>None</code> if no document is
found.</p>
<blockquote>
<p>To raise an exception if there are no matches, use <a
href="#find_unique_or_throw">find_unique_or_throw</a>
instead.</p>
</blockquote>
<h4 data-number="6.4.5.1" id="options-find_unique"><span
class="header-section-number">6.4.5.1</span> Options
(find_unique)</h4>
<table>
<caption>REST Views Options (find_unique)</caption>
<colgroup>
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 70%" />
</colgroup>
<thead>
<tr class="header">
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>select</td>
<td>dict or list</td>
<td>No</td>
<td>Specifies which properties to include or exclude on
the returned document - works as a <em>field
filter</em></td>
</tr>
<tr class="even">
<td>where</td>
<td>dict</td>
<td>Yes</td>
<td>Applies filtering conditions based on specific
fields (must be unique) - works as a <em>document
filter</em></td>
</tr>
<tr class="odd">
<td>read_own_writes</td>
<td>bool</td>
<td>No</td>
<td>Ensures read consistency for a cluster of servers -
<code>False</code> is used by default</td>
</tr>
</tbody>
</table>
<h4 data-number="6.4.5.2"
id="return-type-find_unique"><span
class="header-section-number">6.4.5.2</span> Return Type
(find_unique)</h4>
<p>If there is a match, a REST document data class
object meeting the filter conditions, otherwise
<code>None</code> is returned. For more details about
REST documents, check the <a href="#rest-documents">REST
Documents</a> section.</p>
<h4 data-number="6.4.5.3" id="example-find_unique"><span
class="header-section-number">6.4.5.3</span> Example
(find_unique)</h4>
<div class="sourceCode" id="cb103"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb103-1"><a href="#cb103-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> warnings</span>
<span id="cb103-2"><a href="#cb103-2" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python.my_service <span class="im">import</span> IMyServiceSakilaActor <span class="im">as</span> Actor, MyService</span>
<span id="cb103-3"><a href="#cb103-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb103-4"><a href="#cb103-4" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb103-5"><a href="#cb103-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb103-6"><a href="#cb103-6" aria-hidden="true" tabindex="-1"></a>aid <span class="op">=</span> <span class="dv">3</span></span>
<span id="cb103-7"><a href="#cb103-7" aria-hidden="true" tabindex="-1"></a>actor: Actor <span class="op">=</span> <span class="cf">await</span> <span class="va">self</span>.my_service.sakila.actor.find_unique(</span>
<span id="cb103-8"><a href="#cb103-8" aria-hidden="true" tabindex="-1"></a> where<span class="op">=</span>{<span class="st">"actor_id"</span>: aid}, select<span class="op">=</span>[<span class="st">"last_update"</span>], read_own_writes<span class="op">=</span><span class="va">False</span></span>
<span id="cb103-9"><a href="#cb103-9" aria-hidden="true" tabindex="-1"></a>)</span>
<span id="cb103-10"><a href="#cb103-10" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> actor <span class="kw">is</span> <span class="va">None</span>:</span>
<span id="cb103-11"><a href="#cb103-11" aria-hidden="true" tabindex="-1"></a> warnings.warn(<span class="ss">f"Actor with id=</span><span class="sc">{</span>aid<span class="sc">}</span><span class="ss"> not found"</span>)</span>
<span id="cb103-12"><a href="#cb103-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb103-13"><a href="#cb103-13" aria-hidden="true" tabindex="-1"></a><span class="cf">assert</span> actor.actor_id <span class="op">==</span> aid</span></code></pre></div>
<p>See <a href="#example-find_first">Example
(find_first)</a> for additional usage options.</p>
<h3 data-number="6.4.6"
id="view-find_unique_or_throw-py"><span
class="header-section-number">6.4.6</span>
View.find_unique_or_throw</h3>
<p><code>find_unique_or_throw</code> is used to query a
single, uniquely identified REST document by:</p>
<ul>
<li>Primary key column(s)</li>
<li>Unique column(s)</li>
</ul>
<p>If no document was found matching the given filter
conditions, <code>MrsDocumentNotFoundError</code> is
raised.</p>
<blockquote>
<p>To not raise an exception and get <code>None</code>
if there are no matches, use <a
href="#find_unique">find_unique</a> instead.</p>
</blockquote>
<h4 data-number="6.4.6.1"
id="options-find_unique_or_throw"><span
class="header-section-number">6.4.6.1</span> Options
(find_unique_or_throw)</h4>
<p><code>find_unique_or_throw</code> and
<code>find_unique</code> implement the very same
options. For more details about these, see <a
href="#options-find_unique">Options
(find_unique)</a>.</p>
<h4 data-number="6.4.6.2"
id="return-type-find_unique_or_throw"><span
class="header-section-number">6.4.6.2</span> Return Type
(find_unique_or_throw)</h4>
<p>If there is a match, a REST document data class
object meeting the filter conditions, otherwise
<code>MrsDocumentNotFoundError</code> is raised. For
more details about REST documents, check the <a
href="#rest-documents">REST Documents</a> section.</p>
<h4 data-number="6.4.6.3"
id="example-find_unique_or_throw"><span
class="header-section-number">6.4.6.3</span> Example
(find_unique_or_throw)</h4>
<div class="sourceCode" id="cb104"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb104-1"><a href="#cb104-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> warnings</span>
<span id="cb104-2"><a href="#cb104-2" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python.my_service <span class="im">import</span> IMyServiceSakilaActor <span class="im">as</span> Actor, MyService, MrsDocumentNotFoundError</span>
<span id="cb104-3"><a href="#cb104-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb104-4"><a href="#cb104-4" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb104-5"><a href="#cb104-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb104-6"><a href="#cb104-6" aria-hidden="true" tabindex="-1"></a>aid <span class="op">=</span> <span class="dv">3</span></span>
<span id="cb104-7"><a href="#cb104-7" aria-hidden="true" tabindex="-1"></a><span class="cf">try</span>:</span>
<span id="cb104-8"><a href="#cb104-8" aria-hidden="true" tabindex="-1"></a> actor: Actor <span class="op">=</span> <span class="cf">await</span> <span class="va">self</span>.my_service.sakila.actor.find_unique_or_throw(</span>
<span id="cb104-9"><a href="#cb104-9" aria-hidden="true" tabindex="-1"></a> where<span class="op">=</span>{<span class="st">"actor_id"</span>: aid}, select<span class="op">=</span>[<span class="st">"last_update"</span>], read_own_writes<span class="op">=</span><span class="va">False</span></span>
<span id="cb104-10"><a href="#cb104-10" aria-hidden="true" tabindex="-1"></a> )</span>
<span id="cb104-11"><a href="#cb104-11" aria-hidden="true" tabindex="-1"></a><span class="cf">except</span> MrsDocumentNotFoundError:</span>
<span id="cb104-12"><a href="#cb104-12" aria-hidden="true" tabindex="-1"></a> warnings.warn(<span class="st">"Ups, no matches found"</span>)</span></code></pre></div>
<p>See <a href="#example-find_first">Example
(find_first)</a> for additional usage options.</p>
<h3 data-number="6.4.7" id="view-find-py"><span
class="header-section-number">6.4.7</span> View.find
</h3>
<p><code>find</code> is used to query a subset of REST
documents in one or more pages, and optionally, those
that match a given filter.</p>
<h4 data-number="6.4.7.1" id="options-find"><span
class="header-section-number">6.4.7.1</span> Options
(find)</h4>
<table>
<caption>REST Views Options (find)</caption>
<colgroup>
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 70%" />
</colgroup>
<thead>
<tr class="header">
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>select</td>
<td>dict or list</td>
<td>No</td>
<td>Specifies which properties to include or exclude on
the returned document - works as a <em>field
filter</em></td>
</tr>
<tr class="even">
<td>where</td>
<td>dict</td>
<td>No</td>
<td>Applies filtering conditions based on specific
fields - works as a <em>document filter</em></td>
</tr>
<tr class="odd">
<td>skip</td>
<td>int</td>
<td>No</td>
<td>Specifies how many documents to skip before
returning one of the matches</td>
</tr>
<tr class="even">
<td>order_by</td>
<td>dict</td>
<td>No</td>
<td>Lets you customize the order (<code>ASC</code> or
<code>DESC</code>) in which the documents are returned
based on specific fields</td>
</tr>
<tr class="odd">
<td>cursor</td>
<td>dict</td>
<td>No</td>
<td>Specifies the position of the first item to include
in the result set. A cursor bookmarks a location in a
result set and must be a column containing unique and
sequential values.</td>
</tr>
<tr class="even">
<td>read_own_writes</td>
<td>bool</td>
<td>No</td>
<td>Ensures read consistency for a cluster of servers -
<code>False</code> is used by default</td>
</tr>
<tr class="odd">
<td>take</td>
<td>int</td>
<td>No</td>
<td>The maximum size of the page.</td>
</tr>
<tr class="even">
<td>in order to avoid n + 1 requests, the internal
iterator stops after the MySQL Router says there are no
more items. Default value is <code>True</code>
(enabled).</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<blockquote>
<p>Cursor-based pagination takes precedence over
offset-based pagination, which means that if a cursor is
defined, the value of the offset property
(<code>skip</code>) will be ignored.</p>
</blockquote>
<h4 data-number="6.4.7.2" id="return-type-find"><span
class="header-section-number">6.4.7.2</span> Return Type
(find)</h4>
<p>A list of objects representing the first page of REST
Documents matching the filter. If there are more
matching REST Documents, the array contains an
additional <code>has_more</code> truthy property and a
<code>next()</code> async function that automatically
retrieves the subsequent page of REST Documents.</p>
<h4 data-number="6.4.7.3" id="example-find"><span
class="header-section-number">6.4.7.3</span> Example
(find)</h4>
<div class="sourceCode" id="cb105"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb105-1"><a href="#cb105-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python.my_service <span class="im">import</span> MyService</span>
<span id="cb105-2"><a href="#cb105-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb105-3"><a href="#cb105-3" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb105-4"><a href="#cb105-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb105-5"><a href="#cb105-5" aria-hidden="true" tabindex="-1"></a>actors <span class="op">=</span> <span class="cf">await</span> <span class="va">self</span>.my_service.sakila.countries.find()</span>
<span id="cb105-6"><a href="#cb105-6" aria-hidden="true" tabindex="-1"></a><span class="bu">print</span>(actors)</span>
<span id="cb105-7"><a href="#cb105-7" aria-hidden="true" tabindex="-1"></a><span class="co"># [</span></span>
<span id="cb105-8"><a href="#cb105-8" aria-hidden="true" tabindex="-1"></a><span class="co"># IMyServiceSakilaCountry(</span></span>
<span id="cb105-9"><a href="#cb105-9" aria-hidden="true" tabindex="-1"></a><span class="co"># country_id=1,</span></span>
<span id="cb105-10"><a href="#cb105-10" aria-hidden="true" tabindex="-1"></a><span class="co"># last_update=datetime.datetime(2006, 2, 15, 4, 44),</span></span>
<span id="cb105-11"><a href="#cb105-11" aria-hidden="true" tabindex="-1"></a><span class="co"># country='Afghanistan',</span></span>
<span id="cb105-12"><a href="#cb105-12" aria-hidden="true" tabindex="-1"></a><span class="co"># ),</span></span>
<span id="cb105-13"><a href="#cb105-13" aria-hidden="true" tabindex="-1"></a><span class="co"># IMyServiceSakilaCountry(</span></span>
<span id="cb105-14"><a href="#cb105-14" aria-hidden="true" tabindex="-1"></a><span class="co"># country_id=2,</span></span>
<span id="cb105-15"><a href="#cb105-15" aria-hidden="true" tabindex="-1"></a><span class="co"># last_update=datetime.datetime(2006, 2, 15, 4, 44),</span></span>
<span id="cb105-16"><a href="#cb105-16" aria-hidden="true" tabindex="-1"></a><span class="co"># country='Algeria',</span></span>
<span id="cb105-17"><a href="#cb105-17" aria-hidden="true" tabindex="-1"></a><span class="co"># ),</span></span>
<span id="cb105-18"><a href="#cb105-18" aria-hidden="true" tabindex="-1"></a><span class="co"># ...</span></span>
<span id="cb105-19"><a href="#cb105-19" aria-hidden="true" tabindex="-1"></a><span class="co"># IMyServiceSakilaCountry(</span></span>
<span id="cb105-20"><a href="#cb105-20" aria-hidden="true" tabindex="-1"></a><span class="co"># country_id=25,</span></span>
<span id="cb105-21"><a href="#cb105-21" aria-hidden="true" tabindex="-1"></a><span class="co"># last_update=datetime.datetime(2006, 2, 15, 4, 44),</span></span>
<span id="cb105-22"><a href="#cb105-22" aria-hidden="true" tabindex="-1"></a><span class="co"># country='Congo, The Democratic Republic of the',</span></span>
<span id="cb105-23"><a href="#cb105-23" aria-hidden="true" tabindex="-1"></a><span class="co"># )</span></span>
<span id="cb105-24"><a href="#cb105-24" aria-hidden="true" tabindex="-1"></a><span class="co"># ]</span></span>
<span id="cb105-25"><a href="#cb105-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb105-26"><a href="#cb105-26" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> actors.has_more <span class="kw">is</span> <span class="va">True</span>:</span>
<span id="cb105-27"><a href="#cb105-27" aria-hidden="true" tabindex="-1"></a> actors <span class="op">=</span> <span class="cf">await</span> actors.<span class="bu">next</span>()</span>
<span id="cb105-28"><a href="#cb105-28" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(actors)</span>
<span id="cb105-29"><a href="#cb105-29" aria-hidden="true" tabindex="-1"></a> <span class="co"># [</span></span>
<span id="cb105-30"><a href="#cb105-30" aria-hidden="true" tabindex="-1"></a> <span class="co"># IMyServiceSakilaCountry(</span></span>
<span id="cb105-31"><a href="#cb105-31" aria-hidden="true" tabindex="-1"></a> <span class="co"># country_id=26,</span></span>
<span id="cb105-32"><a href="#cb105-32" aria-hidden="true" tabindex="-1"></a> <span class="co"># last_update=datetime.datetime(2006, 2, 15, 4, 44),</span></span>
<span id="cb105-33"><a href="#cb105-33" aria-hidden="true" tabindex="-1"></a> <span class="co"># country='Czech Republic',</span></span>
<span id="cb105-34"><a href="#cb105-34" aria-hidden="true" tabindex="-1"></a> <span class="co"># ),</span></span>
<span id="cb105-35"><a href="#cb105-35" aria-hidden="true" tabindex="-1"></a> <span class="co"># IMyServiceSakilaCountry(</span></span>
<span id="cb105-36"><a href="#cb105-36" aria-hidden="true" tabindex="-1"></a> <span class="co"># country_id=27,</span></span>
<span id="cb105-37"><a href="#cb105-37" aria-hidden="true" tabindex="-1"></a> <span class="co"># last_update=datetime.datetime(2006, 2, 15, 4, 44),</span></span>
<span id="cb105-38"><a href="#cb105-38" aria-hidden="true" tabindex="-1"></a> <span class="co"># country='Dominican Republic',</span></span>
<span id="cb105-39"><a href="#cb105-39" aria-hidden="true" tabindex="-1"></a> <span class="co"># ),</span></span>
<span id="cb105-40"><a href="#cb105-40" aria-hidden="true" tabindex="-1"></a> <span class="co"># ...</span></span>
<span id="cb105-41"><a href="#cb105-41" aria-hidden="true" tabindex="-1"></a> <span class="co"># IMyServiceSakilaCountry(</span></span>
<span id="cb105-42"><a href="#cb105-42" aria-hidden="true" tabindex="-1"></a> <span class="co"># country_id=50,</span></span>
<span id="cb105-43"><a href="#cb105-43" aria-hidden="true" tabindex="-1"></a> <span class="co"># last_update=datetime.datetime(2006, 2, 15, 4, 44),</span></span>
<span id="cb105-44"><a href="#cb105-44" aria-hidden="true" tabindex="-1"></a> <span class="co"># country='Japan',</span></span>
<span id="cb105-45"><a href="#cb105-45" aria-hidden="true" tabindex="-1"></a> <span class="co"># )</span></span></code></pre></div>
<blockquote>
<p>Due the way attributes work in Python, for the MyPy
type checker to be able to correctly narrow the types
returned by <code>next()</code>, <code>has_more</code>
must be explicitly checked against
<code>True</code>.</p>
</blockquote>
<p>See <a href="#example-find_first">Example
(find_first)</a> for additional usage options.</p>
<h3 data-number="6.4.8" id="view-delete-py"><span
class="header-section-number">6.4.8</span> View.delete
</h3>
<p><code>delete</code> is used to delete a single,
uniquely identified REST document by:</p>
<ul>
<li>Primary key column(s)</li>
<li>Unique column(s)</li>
</ul>
<blockquote>
<p>To delete multiple documents, see <a
href="#delete_many">delete_many</a>.</p>
</blockquote>
<h4 data-number="6.4.8.1" id="options-delete"><span
class="header-section-number">6.4.8.1</span> Options
(delete)</h4>
<table>
<caption>REST Views Options (delete)</caption>
<colgroup>
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 70%" />
</colgroup>
<thead>
<tr class="header">
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>where</td>
<td>dict</td>
<td>Yes</td>
<td>Applies filtering conditions based on specific
fields (must be unique) - works as a <em>document
filter</em></td>
</tr>
<tr class="even">
<td>read_own_writes</td>
<td>bool</td>
<td>No</td>
<td>Ensures read consistency for a cluster of servers -
<code>False</code> is used by default</td>
</tr>
</tbody>
</table>
<h4 data-number="6.4.8.2" id="return-type-delete"><span
class="header-section-number">6.4.8.2</span> Return Type
(delete)</h4>
<p><code>True</code> if the document was deleted
successfully or <code>False</code> otherwise.</p>
<h4 data-number="6.4.8.3" id="example-delete"><span
class="header-section-number">6.4.8.3</span> Example
(delete)</h4>
<div class="sourceCode" id="cb106"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb106-1"><a href="#cb106-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> warnings</span>
<span id="cb106-2"><a href="#cb106-2" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python.my_service <span class="im">import</span> IMyServiceSakilaActor <span class="im">as</span> Actor, MyService</span>
<span id="cb106-3"><a href="#cb106-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb106-4"><a href="#cb106-4" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb106-5"><a href="#cb106-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb106-6"><a href="#cb106-6" aria-hidden="true" tabindex="-1"></a>aid <span class="op">=</span> <span class="dv">3</span></span>
<span id="cb106-7"><a href="#cb106-7" aria-hidden="true" tabindex="-1"></a>ans: <span class="bu">bool</span> <span class="op">=</span> <span class="cf">await</span> <span class="va">self</span>.my_service.sakila.actor.delete(</span>
<span id="cb106-8"><a href="#cb106-8" aria-hidden="true" tabindex="-1"></a> where<span class="op">=</span>{<span class="st">"actor_id"</span>: aid}</span>
<span id="cb106-9"><a href="#cb106-9" aria-hidden="true" tabindex="-1"></a>)</span>
<span id="cb106-10"><a href="#cb106-10" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> ans <span class="kw">is</span> <span class="va">False</span>:</span>
<span id="cb106-11"><a href="#cb106-11" aria-hidden="true" tabindex="-1"></a> warnings.warn(<span class="ss">f"Actor not deleted - actor_id=</span><span class="sc">{</span>aid<span class="sc">}</span><span class="ss"> not found"</span>)</span>
<span id="cb106-12"><a href="#cb106-12" aria-hidden="true" tabindex="-1"></a><span class="cf">else</span>:</span>
<span id="cb106-13"><a href="#cb106-13" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f"Actor document with ID=</span><span class="sc">{</span>aid<span class="sc">}</span><span class="ss"> was deleted"</span>)</span></code></pre></div>
<h3 data-number="6.4.9" id="view-delete_many-py"><span
class="header-section-number">6.4.9</span>
View.delete_many</h3>
<p><code>delete_many</code> is used to delete all REST
documents that match a given filter. To delete a single
document, see <a href="#delete">delete</a>.</p>
<h4 data-number="6.4.9.1" id="options-delete_many"><span
class="header-section-number">6.4.9.1</span> Options
(delete_many)</h4>
<table>
<caption>REST Views Options (delete_many)</caption>
<colgroup>
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 70%" />
</colgroup>
<thead>
<tr class="header">
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>where</td>
<td>dict</td>
<td>Yes</td>
<td>Applies filtering conditions based on specific
fields - works as a <em>document filter</em></td>
</tr>
<tr class="even">
<td>read_own_writes</td>
<td>bool</td>
<td>No</td>
<td>Ensures read consistency for a cluster of servers -
<code>False</code> is used by default</td>
</tr>
</tbody>
</table>
<h4 data-number="6.4.9.2"
id="return-type-delete_many"><span
class="header-section-number">6.4.9.2</span> Return Type
(delete_many)</h4>
<p>An integer indicating the number of deleted
documents.</p>
<h4 data-number="6.4.9.3" id="example-delete_many"><span
class="header-section-number">6.4.9.3</span> Example
(delete_many)</h4>
<p>Suppose the actor table contains a bunch of records
as shown in <a href="#cursor-find_first">Cursor
Example</a>.</p>
<div class="sourceCode" id="cb107"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb107-1"><a href="#cb107-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python.my_service <span class="im">import</span> IMyServiceSakilaActor <span class="im">as</span> Actor, MyService</span>
<span id="cb107-2"><a href="#cb107-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb107-3"><a href="#cb107-3" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb107-4"><a href="#cb107-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb107-5"><a href="#cb107-5" aria-hidden="true" tabindex="-1"></a>num_items_removed <span class="op">=</span> <span class="cf">await</span> <span class="va">self</span>.my_service.sakila.actor.delete_many(</span>
<span id="cb107-6"><a href="#cb107-6" aria-hidden="true" tabindex="-1"></a> where<span class="op">=</span>{<span class="st">"last_name"</span>: {<span class="st">"like"</span>: <span class="st">"</span><span class="sc">%%</span><span class="st">HA</span><span class="sc">%%</span><span class="st">"</span>}}</span>
<span id="cb107-7"><a href="#cb107-7" aria-hidden="true" tabindex="-1"></a>)</span>
<span id="cb107-8"><a href="#cb107-8" aria-hidden="true" tabindex="-1"></a><span class="bu">print</span>(num_items_removed)</span>
<span id="cb107-9"><a href="#cb107-9" aria-hidden="true" tabindex="-1"></a><span class="co"># 3</span></span></code></pre></div>
<h3 data-number="6.4.10" id="view-update-py"><span
class="header-section-number">6.4.10</span> View.update
</h3>
<p><code>update</code> is used to update a REST document
with a given identifier or primary key.</p>
<blockquote>
<p>To update multiple documents, see <a
href="#update_many">update_many</a>.</p>
</blockquote>
<h4 data-number="6.4.10.1" id="options-update"><span
class="header-section-number">6.4.10.1</span> Options
(update)</h4>
<table>
<caption>REST Views Options (update)</caption>
<colgroup>
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 70%" />
</colgroup>
<thead>
<tr class="header">
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>data</td>
<td>TypedDict</td>
<td>Yes</td>
<td>Set of fields and corresponding values to update.
The identifier or primary key must be included</td>
</tr>
</tbody>
</table>
<h4 data-number="6.4.10.2" id="return-type-update"><span
class="header-section-number">6.4.10.2</span> Return
Type (update)</h4>
<p>A REST document data class object representing the
up-to-date record. For more details about REST
documents, check the <a href="#rest-documents">REST
Documents</a> section.</p>
<h4 data-number="6.4.10.3" id="example-update"><span
class="header-section-number">6.4.10.3</span> Example
(update)</h4>
<div class="sourceCode" id="cb108"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb108-1"><a href="#cb108-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> datetime <span class="im">import</span> datetime</span>
<span id="cb108-2"><a href="#cb108-2" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python.my_service <span class="im">import</span> IMyServiceSakilaActor <span class="im">as</span> Actor, MyService</span>
<span id="cb108-3"><a href="#cb108-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb108-4"><a href="#cb108-4" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb108-5"><a href="#cb108-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb108-6"><a href="#cb108-6" aria-hidden="true" tabindex="-1"></a><span class="co"># The `actor_id` and `last_update` columns from the `sakila` table on the</span></span>
<span id="cb108-7"><a href="#cb108-7" aria-hidden="true" tabindex="-1"></a><span class="co"># sample [sakila database](https://dev.mysql.com/doc/sakila/en/) are</span></span>
<span id="cb108-8"><a href="#cb108-8" aria-hidden="true" tabindex="-1"></a><span class="co"># automatically generated on each insert, which means they can be omitted.</span></span>
<span id="cb108-9"><a href="#cb108-9" aria-hidden="true" tabindex="-1"></a>actor: Actor <span class="op">=</span> <span class="cf">await</span> <span class="va">self</span>.my_service.sakila.actor.create(</span>
<span id="cb108-10"><a href="#cb108-10" aria-hidden="true" tabindex="-1"></a> data<span class="op">=</span>{<span class="st">"first_name"</span>: <span class="st">"Foo"</span>, <span class="st">"last_name"</span>: <span class="st">"Bar"</span>, <span class="st">"actor_id"</span>: <span class="dv">345</span>}</span>
<span id="cb108-11"><a href="#cb108-11" aria-hidden="true" tabindex="-1"></a>)</span>
<span id="cb108-12"><a href="#cb108-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb108-13"><a href="#cb108-13" aria-hidden="true" tabindex="-1"></a>actor_updated: Actor <span class="op">=</span> <span class="cf">await</span> <span class="va">self</span>.my_service.sakila.actor.update(</span>
<span id="cb108-14"><a href="#cb108-14" aria-hidden="true" tabindex="-1"></a> data<span class="op">=</span>{</span>
<span id="cb108-15"><a href="#cb108-15" aria-hidden="true" tabindex="-1"></a> <span class="st">"actor_id"</span>: cast(<span class="bu">int</span>, actor.actor_id),</span>
<span id="cb108-16"><a href="#cb108-16" aria-hidden="true" tabindex="-1"></a> <span class="st">"first_name"</span>: <span class="st">"Rodolfo"</span>,</span>
<span id="cb108-17"><a href="#cb108-17" aria-hidden="true" tabindex="-1"></a> <span class="st">"last_name"</span>: <span class="st">"Smith"</span>,</span>
<span id="cb108-18"><a href="#cb108-18" aria-hidden="true" tabindex="-1"></a> <span class="st">"last_update"</span>: <span class="bu">str</span>(datetime.now()),</span>
<span id="cb108-19"><a href="#cb108-19" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb108-20"><a href="#cb108-20" aria-hidden="true" tabindex="-1"></a> )</span>
<span id="cb108-21"><a href="#cb108-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb108-22"><a href="#cb108-22" aria-hidden="true" tabindex="-1"></a><span class="cf">assert</span> actor_updated.first_name <span class="op">==</span> <span class="st">"Rodolfo"</span></span>
<span id="cb108-23"><a href="#cb108-23" aria-hidden="true" tabindex="-1"></a><span class="cf">assert</span> actor_updated.last_name <span class="op">==</span> <span class="st">"Smith"</span></span>
<span id="cb108-24"><a href="#cb108-24" aria-hidden="true" tabindex="-1"></a><span class="cf">assert</span> actor.actor_id <span class="op">==</span> actor_updated.actor_id</span></code></pre></div>
<h3 data-number="6.4.11" id="view-update_many-py"><span
class="header-section-number">6.4.11</span>
View.update_many</h3>
<p><code>update_many</code> is used to update all REST
documents with matching identifiers or primary keys.</p>
<blockquote>
<p>To update a single document, see <a
href="#update">update</a>.</p>
</blockquote>
<h4 data-number="6.4.11.1"
id="options-update_many"><span
class="header-section-number">6.4.11.1</span> Options
(update_many)</h4>
<table>
<caption>REST Views Options (update_many)</caption>
<colgroup>
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 10%" />
<col style="width: 70%" />
</colgroup>
<thead>
<tr class="header">
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>data</td>
<td>list of <code>TypedDict</code></td>
<td>Yes</td>
<td>A list of set of fields and corresponding values to
update. The identifier or primary key must be included
for each “set of fields” (document)</td>
</tr>
</tbody>
</table>
<h4 data-number="6.4.11.2"
id="return-type-update_many"><span
class="header-section-number">6.4.11.2</span> Return
Type (update_many)</h4>
<p>A list of REST document data class objects
representing the up-to-date records. For more details
about REST documents, check the <a
href="#rest-documents">REST Documents</a> section.</p>
<h4 data-number="6.4.11.3"
id="example-update_many"><span
class="header-section-number">6.4.11.3</span> Example
(update_many)</h4>
<div class="sourceCode" id="cb109"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb109-1"><a href="#cb109-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> datetime <span class="im">import</span> datetime</span>
<span id="cb109-2"><a href="#cb109-2" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python.my_service <span class="im">import</span> IMyServiceSakilaActor <span class="im">as</span> Actor, MyService</span>
<span id="cb109-3"><a href="#cb109-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb109-4"><a href="#cb109-4" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb109-5"><a href="#cb109-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb109-6"><a href="#cb109-6" aria-hidden="true" tabindex="-1"></a><span class="co"># The `actor_id` and `last_update` columns from the `sakila` table on the</span></span>
<span id="cb109-7"><a href="#cb109-7" aria-hidden="true" tabindex="-1"></a><span class="co"># sample [sakila database](https://dev.mysql.com/doc/sakila/en/) are</span></span>
<span id="cb109-8"><a href="#cb109-8" aria-hidden="true" tabindex="-1"></a><span class="co"># automatically generated on each insert, which means they can be omitted.</span></span>
<span id="cb109-9"><a href="#cb109-9" aria-hidden="true" tabindex="-1"></a>actors: Actor <span class="op">=</span> <span class="cf">await</span> <span class="va">self</span>.my_service.sakila.actor.create(</span>
<span id="cb109-10"><a href="#cb109-10" aria-hidden="true" tabindex="-1"></a> data<span class="op">=</span>[</span>
<span id="cb109-11"><a href="#cb109-11" aria-hidden="true" tabindex="-1"></a> {<span class="st">"first_name"</span>: <span class="st">"Foo"</span>, <span class="st">"last_name"</span>: <span class="st">"Bar"</span>, <span class="st">"actor_id"</span>: <span class="dv">345</span>},</span>
<span id="cb109-12"><a href="#cb109-12" aria-hidden="true" tabindex="-1"></a> {<span class="st">"first_name"</span>: <span class="st">"Bruh"</span>, <span class="st">"last_name"</span>: <span class="st">"Baz"</span>, <span class="st">"actor_id"</span>: <span class="dv">346</span>},</span>
<span id="cb109-13"><a href="#cb109-13" aria-hidden="true" tabindex="-1"></a> ]</span>
<span id="cb109-14"><a href="#cb109-14" aria-hidden="true" tabindex="-1"></a>)</span>
<span id="cb109-15"><a href="#cb109-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb109-16"><a href="#cb109-16" aria-hidden="true" tabindex="-1"></a>actors_updated: Actor <span class="op">=</span> <span class="cf">await</span> <span class="va">self</span>.my_service.sakila.actor.update(</span>
<span id="cb109-17"><a href="#cb109-17" aria-hidden="true" tabindex="-1"></a> data<span class="op">=</span>[</span>
<span id="cb109-18"><a href="#cb109-18" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb109-19"><a href="#cb109-19" aria-hidden="true" tabindex="-1"></a> <span class="st">"actor_id"</span>: cast(<span class="bu">int</span>, actors[<span class="dv">0</span>].actor_id),</span>
<span id="cb109-20"><a href="#cb109-20" aria-hidden="true" tabindex="-1"></a> <span class="st">"first_name"</span>: <span class="st">"Rodolfo"</span>,</span>
<span id="cb109-21"><a href="#cb109-21" aria-hidden="true" tabindex="-1"></a> <span class="st">"last_name"</span>: <span class="st">"Smith"</span>,</span>
<span id="cb109-22"><a href="#cb109-22" aria-hidden="true" tabindex="-1"></a> <span class="st">"last_update"</span>: <span class="bu">str</span>(datetime.now()),</span>
<span id="cb109-23"><a href="#cb109-23" aria-hidden="true" tabindex="-1"></a> },</span>
<span id="cb109-24"><a href="#cb109-24" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb109-25"><a href="#cb109-25" aria-hidden="true" tabindex="-1"></a> <span class="st">"actor_id"</span>: cast(<span class="bu">int</span>, actors[<span class="dv">1</span>].actor_id),</span>
<span id="cb109-26"><a href="#cb109-26" aria-hidden="true" tabindex="-1"></a> <span class="st">"first_name"</span>: <span class="st">"Ma"</span>,</span>
<span id="cb109-27"><a href="#cb109-27" aria-hidden="true" tabindex="-1"></a> <span class="st">"last_name"</span>: <span class="st">"Yeung"</span>,</span>
<span id="cb109-28"><a href="#cb109-28" aria-hidden="true" tabindex="-1"></a> <span class="st">"last_update"</span>: <span class="bu">str</span>(datetime.now()),</span>
<span id="cb109-29"><a href="#cb109-29" aria-hidden="true" tabindex="-1"></a> },</span>
<span id="cb109-30"><a href="#cb109-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb109-31"><a href="#cb109-31" aria-hidden="true" tabindex="-1"></a> ]</span>
<span id="cb109-32"><a href="#cb109-32" aria-hidden="true" tabindex="-1"></a> )</span>
<span id="cb109-33"><a href="#cb109-33" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb109-34"><a href="#cb109-34" aria-hidden="true" tabindex="-1"></a><span class="cf">assert</span> actors_updated[<span class="dv">0</span>].first_name <span class="op">==</span> <span class="st">"Rodolfo"</span></span>
<span id="cb109-35"><a href="#cb109-35" aria-hidden="true" tabindex="-1"></a><span class="cf">assert</span> actors_updated[<span class="dv">0</span>].last_name <span class="op">==</span> <span class="st">"Smith"</span></span>
<span id="cb109-36"><a href="#cb109-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb109-37"><a href="#cb109-37" aria-hidden="true" tabindex="-1"></a><span class="cf">assert</span> actors_updated[<span class="dv">1</span>].first_name <span class="op">==</span> <span class="st">"Ma"</span></span>
<span id="cb109-38"><a href="#cb109-38" aria-hidden="true" tabindex="-1"></a><span class="cf">assert</span> actors_updated[<span class="dv">1</span>].last_name <span class="op">==</span> <span class="st">"Yeung"</span></span></code></pre></div>
<h2 data-number="6.5" id="rest-documents"><span
class="header-section-number">6.5</span> REST
Documents</h2>
<p>A <em>REST document</em> behaves like a <a
href="https://docs.python.org/3/library/dataclasses.html">Python
data class</a> instance, and implements an extended
interface which includes the <code>update</code> and
<code>delete</code> methods.</p>
<blockquote>
<p>Python data classes defining REST documents are
public elements of the Service module, however, we
advise you to not produce (instantiate) REST documents
directly. Instead, we recommend doing so indirectly; by
calling specific Python SDK commands such as
<code>find*()</code> or <code>create*()</code>. See <a
href="#rest-views">REST Views</a> to know more about
these commands.</p>
</blockquote>
<h3 data-number="6.5.1" id="document-update-py"><span
class="header-section-number">6.5.1</span>
Document.update</h3>
<p><code>update</code> updates the REST document
represented by the data class instance.</p>
<h4 data-number="6.5.1.1"
id="options-update---document"><span
class="header-section-number">6.5.1.1</span> Options
(update - document)</h4>
<p>No options are implemented because the data required
to complete the operation is assumed to be already
included in the data class instance itself.</p>
<h4 data-number="6.5.1.2"
id="return-type-update---document"><span
class="header-section-number">6.5.1.2</span> Return Type
(update - document)</h4>
<p><code>None</code>.</p>
<h4 data-number="6.5.1.3"
id="example-update---document"><span
class="header-section-number">6.5.1.3</span> Example
(update - document)</h4>
<div class="sourceCode" id="cb110"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb110-1"><a href="#cb110-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> asyncio</span>
<span id="cb110-2"><a href="#cb110-2" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> datetime <span class="im">import</span> datetime</span>
<span id="cb110-3"><a href="#cb110-3" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> typing <span class="im">import</span> Optional</span>
<span id="cb110-4"><a href="#cb110-4" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python.my_service <span class="im">import</span> (</span>
<span id="cb110-5"><a href="#cb110-5" aria-hidden="true" tabindex="-1"></a> IMyServiceSakilaActor <span class="im">as</span> Actor,</span>
<span id="cb110-6"><a href="#cb110-6" aria-hidden="true" tabindex="-1"></a> MyService,</span>
<span id="cb110-7"><a href="#cb110-7" aria-hidden="true" tabindex="-1"></a> MrsDocumentNotFoundError,</span>
<span id="cb110-8"><a href="#cb110-8" aria-hidden="true" tabindex="-1"></a>)</span>
<span id="cb110-9"><a href="#cb110-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb110-10"><a href="#cb110-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb110-11"><a href="#cb110-11" aria-hidden="true" tabindex="-1"></a><span class="cf">async</span> <span class="kw">def</span> get_actor_document_by_id(service: MyService, doc_id: <span class="bu">int</span>) <span class="op">-></span> Actor:</span>
<span id="cb110-12"><a href="#cb110-12" aria-hidden="true" tabindex="-1"></a> <span class="cf">try</span>:</span>
<span id="cb110-13"><a href="#cb110-13" aria-hidden="true" tabindex="-1"></a> actor: Actor <span class="op">=</span> <span class="cf">await</span> service.sakila.actor.find_first_or_throw(</span>
<span id="cb110-14"><a href="#cb110-14" aria-hidden="true" tabindex="-1"></a> where<span class="op">=</span>{<span class="st">"actor_id"</span>: doc_id}</span>
<span id="cb110-15"><a href="#cb110-15" aria-hidden="true" tabindex="-1"></a> )</span>
<span id="cb110-16"><a href="#cb110-16" aria-hidden="true" tabindex="-1"></a> <span class="cf">except</span> MrsDocumentNotFoundError:</span>
<span id="cb110-17"><a href="#cb110-17" aria-hidden="true" tabindex="-1"></a> <span class="cf">raise</span> MrsDocumentNotFoundError(msg<span class="op">=</span><span class="ss">f"No actor document exists matching actor_id=</span><span class="sc">{</span>doc_id<span class="sc">}</span><span class="ss">"</span>)</span>
<span id="cb110-18"><a href="#cb110-18" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> actor</span>
<span id="cb110-19"><a href="#cb110-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb110-20"><a href="#cb110-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb110-21"><a href="#cb110-21" aria-hidden="true" tabindex="-1"></a><span class="cf">async</span> <span class="kw">def</span> main() <span class="op">-></span> <span class="va">None</span>:</span>
<span id="cb110-22"><a href="#cb110-22" aria-hidden="true" tabindex="-1"></a> <span class="co"># Create service</span></span>
<span id="cb110-23"><a href="#cb110-23" aria-hidden="true" tabindex="-1"></a> my_service <span class="op">=</span> MyService()</span>
<span id="cb110-24"><a href="#cb110-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb110-25"><a href="#cb110-25" aria-hidden="true" tabindex="-1"></a> <span class="co"># Get a document</span></span>
<span id="cb110-26"><a href="#cb110-26" aria-hidden="true" tabindex="-1"></a> doc_id <span class="op">=</span> <span class="dv">3</span></span>
<span id="cb110-27"><a href="#cb110-27" aria-hidden="true" tabindex="-1"></a> actor <span class="op">=</span> <span class="cf">await</span> get_actor_document_by_id(service<span class="op">=</span>my_service, doc_id<span class="op">=</span>doc_id)</span>
<span id="cb110-28"><a href="#cb110-28" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"Before:"</span>, actor)</span>
<span id="cb110-29"><a href="#cb110-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb110-30"><a href="#cb110-30" aria-hidden="true" tabindex="-1"></a> <span class="co"># Modify the data class instance representing a REST document</span></span>
<span id="cb110-31"><a href="#cb110-31" aria-hidden="true" tabindex="-1"></a> actor.first_name <span class="op">=</span> <span class="st">"DESIRE"</span></span>
<span id="cb110-32"><a href="#cb110-32" aria-hidden="true" tabindex="-1"></a> actor.last_name <span class="op">=</span> <span class="st">"LEE"</span></span>
<span id="cb110-33"><a href="#cb110-33" aria-hidden="true" tabindex="-1"></a> actor.last_update <span class="op">=</span> <span class="bu">str</span>(datetime.now())</span>
<span id="cb110-34"><a href="#cb110-34" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb110-35"><a href="#cb110-35" aria-hidden="true" tabindex="-1"></a> <span class="co"># Commit an update</span></span>
<span id="cb110-36"><a href="#cb110-36" aria-hidden="true" tabindex="-1"></a> <span class="cf">await</span> actor.update()</span>
<span id="cb110-37"><a href="#cb110-37" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb110-38"><a href="#cb110-38" aria-hidden="true" tabindex="-1"></a> <span class="co"># Peak the REST document to see if it was updated accordingly</span></span>
<span id="cb110-39"><a href="#cb110-39" aria-hidden="true" tabindex="-1"></a> actor_after <span class="op">=</span> <span class="cf">await</span> get_actor_document_by_id(service<span class="op">=</span>my_service, doc_id<span class="op">=</span>doc_id)</span>
<span id="cb110-40"><a href="#cb110-40" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"After:"</span>, actor_after)</span>
<span id="cb110-41"><a href="#cb110-41" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb110-42"><a href="#cb110-42" aria-hidden="true" tabindex="-1"></a> <span class="co"># Before: IMyServiceSakilaActor(last_name='CHASE', last_update='2023-04-13 15:11:22.000000', first_name='ED', actor_id=3)</span></span>
<span id="cb110-43"><a href="#cb110-43" aria-hidden="true" tabindex="-1"></a> <span class="co"># After: IMyServiceSakilaActor(last_name='LEE', last_update='2025-01-09 13:07:50.000000', first_name='DESIRE', actor_id=3)</span></span>
<span id="cb110-44"><a href="#cb110-44" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb110-45"><a href="#cb110-45" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb110-46"><a href="#cb110-46" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">"__main__"</span>:</span>
<span id="cb110-47"><a href="#cb110-47" aria-hidden="true" tabindex="-1"></a> asyncio.run(main())</span></code></pre></div>
<h3 data-number="6.5.2" id="document-delete-py"><span
class="header-section-number">6.5.2</span>
Document.delete</h3>
<p><code>delete</code> deletes the resource represented
by the data class instance.</p>
<h4 data-number="6.5.2.1"
id="options-delete---document"><span
class="header-section-number">6.5.2.1</span> Options
(delete - document)</h4>
<p>No options are implemented because the data required
to complete the operation is assumed to be already
included in the data class instance itself.</p>
<h4 data-number="6.5.2.2"
id="return-type-delete---document"><span
class="header-section-number">6.5.2.2</span> Return Type
(delete - document)</h4>
<p><code>True</code> if the document was deleted
successfully or <code>False</code> otherwise.</p>
<h4 data-number="6.5.2.3"
id="example-delete---document"><span
class="header-section-number">6.5.2.3</span> Example
(delete - document)</h4>
<div class="sourceCode" id="cb111"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb111-1"><a href="#cb111-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> asyncio</span>
<span id="cb111-2"><a href="#cb111-2" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> typing <span class="im">import</span> Optional, cast</span>
<span id="cb111-3"><a href="#cb111-3" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python.my_service <span class="im">import</span> (</span>
<span id="cb111-4"><a href="#cb111-4" aria-hidden="true" tabindex="-1"></a> IMyServiceSakilaActor <span class="im">as</span> Actor,</span>
<span id="cb111-5"><a href="#cb111-5" aria-hidden="true" tabindex="-1"></a> MyService,</span>
<span id="cb111-6"><a href="#cb111-6" aria-hidden="true" tabindex="-1"></a>)</span>
<span id="cb111-7"><a href="#cb111-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb111-8"><a href="#cb111-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb111-9"><a href="#cb111-9" aria-hidden="true" tabindex="-1"></a><span class="cf">async</span> <span class="kw">def</span> main():</span>
<span id="cb111-10"><a href="#cb111-10" aria-hidden="true" tabindex="-1"></a> <span class="co"># Create service</span></span>
<span id="cb111-11"><a href="#cb111-11" aria-hidden="true" tabindex="-1"></a> my_service <span class="op">=</span> MyService()</span>
<span id="cb111-12"><a href="#cb111-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb111-13"><a href="#cb111-13" aria-hidden="true" tabindex="-1"></a> <span class="co"># Create a document</span></span>
<span id="cb111-14"><a href="#cb111-14" aria-hidden="true" tabindex="-1"></a> <span class="co">#</span></span>
<span id="cb111-15"><a href="#cb111-15" aria-hidden="true" tabindex="-1"></a> <span class="co"># The `actor_id` and `last_update` columns from the `sakila`</span></span>
<span id="cb111-16"><a href="#cb111-16" aria-hidden="true" tabindex="-1"></a> <span class="co"># table on the sample [sakila database](https://dev.mysql.com/doc/sakila/en/)</span></span>
<span id="cb111-17"><a href="#cb111-17" aria-hidden="true" tabindex="-1"></a> <span class="co"># are automatically generated on each insert, which means they can be omitted.</span></span>
<span id="cb111-18"><a href="#cb111-18" aria-hidden="true" tabindex="-1"></a> actor <span class="op">=</span> <span class="cf">await</span> my_service.sakila.actor.create(</span>
<span id="cb111-19"><a href="#cb111-19" aria-hidden="true" tabindex="-1"></a> {<span class="st">"first_name"</span>: <span class="st">"GRACO"</span>, <span class="st">"last_name"</span>: <span class="st">"WALKER"</span>}</span>
<span id="cb111-20"><a href="#cb111-20" aria-hidden="true" tabindex="-1"></a> )</span>
<span id="cb111-21"><a href="#cb111-21" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(actor)</span>
<span id="cb111-22"><a href="#cb111-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb111-23"><a href="#cb111-23" aria-hidden="true" tabindex="-1"></a> <span class="co"># Commit a delete</span></span>
<span id="cb111-24"><a href="#cb111-24" aria-hidden="true" tabindex="-1"></a> <span class="cf">await</span> actor.delete()</span>
<span id="cb111-25"><a href="#cb111-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb111-26"><a href="#cb111-26" aria-hidden="true" tabindex="-1"></a> actor_after: Optional[Actor] <span class="op">=</span> <span class="cf">await</span> my_service.sakila.actor.find_first(</span>
<span id="cb111-27"><a href="#cb111-27" aria-hidden="true" tabindex="-1"></a> where<span class="op">=</span>{<span class="st">"actor_id"</span>: cast(<span class="bu">int</span>, actor.actor_id)}</span>
<span id="cb111-28"><a href="#cb111-28" aria-hidden="true" tabindex="-1"></a> )</span>
<span id="cb111-29"><a href="#cb111-29" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"deleted?"</span>, actor_after <span class="kw">is</span> <span class="va">None</span>)</span>
<span id="cb111-30"><a href="#cb111-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb111-31"><a href="#cb111-31" aria-hidden="true" tabindex="-1"></a> <span class="co"># IMyServiceSakilaActor(last_name='WALKER', last_update='2025-01-09 13:31:16.000000', first_name='GRACO', actor_id=37171)</span></span>
<span id="cb111-32"><a href="#cb111-32" aria-hidden="true" tabindex="-1"></a> <span class="co"># deleted? True</span></span>
<span id="cb111-33"><a href="#cb111-33" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb111-34"><a href="#cb111-34" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb111-35"><a href="#cb111-35" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">"__main__"</span>:</span>
<span id="cb111-36"><a href="#cb111-36" aria-hidden="true" tabindex="-1"></a> asyncio.run(main())</span></code></pre></div>
<h2 data-number="6.6" id="rest-routines"><span
class="header-section-number">6.6</span> REST
Routines</h2>
<h3 data-number="6.6.1" id="function-call-py"><span
class="header-section-number">6.6.1</span> Function.call
</h3>
<p><code>call</code> is used to execute a REST routine
(<code>FUNCTION</code> or <code>PROCEDURE</code>). In
the case of a <code>FUNCTION</code>, the set of
parameters (and corresponding values) as specified by
the database routine are provided as corresponding
keyword arguments. If the REST routine has an associated
Async Task, the first parameter is, instead, a
positional argument that uses a Python <code>dict</code>
to specify additional task-specific execution
options.</p>
<blockquote>
<p>For the sake of avoiding conflict with keyword
argument names, an arbitrary number of positional
arguments are enabled. The recommended treat is to pass
only one options dictionary, as the first positional
argument. If you, intentionally or not, pass more than
one positional argument, the option value from the later
dictionary in the sequence takes precedence.</p>
</blockquote>
<h4 data-number="6.6.1.1" id="options-call"><span
class="header-section-number">6.6.1.1</span> Options
(call)</h4>
<table>
<caption>REST Function/Procedure Options
(call)</caption>
<colgroup>
<col style="width: 9%" />
<col style="width: 9%" />
<col style="width: 9%" />
<col style="width: 9%" />
<col style="width: 63%" />
</colgroup>
<thead>
<tr class="header">
<th>Option Name</th>
<th>Data Type</th>
<th>Required</th>
<th>Default</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>refresh_rate</td>
<td><code>float</code></td>
<td>No</td>
<td><code>2.0</code></td>
<td>Rate at which the underlying implementation checks
for status updates of the execution. Value in
<strong>seconds</strong>. An exception is raised if
<code>refresh_rate</code> is lower than 0.5 seconds.
(available only if the routine has an associated Async
Task)</td>
</tr>
<tr class="even">
<td>progress</td>
<td><code>Callable[[IMrsRunningTaskReport], Awaitable[None]]</code></td>
<td>No</td>
<td><code>None</code></td>
<td>Callback function that gets executed (with the
details provided by the status update) while the status
of the execution remains in <code>RUNNING</code> state.
By default, no progress is carried on.</td>
</tr>
<tr class="odd">
<td>timeout</td>
<td><code>float</code></td>
<td>No</td>
<td><code>None</code></td>
<td>Maximum time to wait for the execution to complete.
If this threshold is reached, the ongoing task is killed
and <code>MrsTaskTimeOutError</code> exception is
raised. By default, no timeout is enforced. (available
only if the routine has an associated Async Task)</td>
</tr>
</tbody>
</table>
<h4 data-number="6.6.1.2" id="return-type-call"><span
class="header-section-number">6.6.1.2</span> Return Type
(call)</h4>
<p>The Python data type returned by
<code><func_name>(...)</code> depends on the data
type returned by the MySQL function.</p>
<blockquote>
<p>For instance, the Python data type <code>int</code>
must be expected for MySQL functions declared to return
<code>TINYINT</code>, <code>SMALLINT</code>,
<code>MEDIUMINT</code>, <code>INT</code> and
<code>BIGINT</code>.</p>
</blockquote>
<h4 data-number="6.6.1.3" id="exceptions-call"><span
class="header-section-number">6.6.1.3</span> Exceptions
(call)</h4>
<p>For REST routines with an associated asynchronous
task, <code>call</code> can raise exceptions as
follows:</p>
<table>
<colgroup>
<col style="width: 12%" />
<col style="width: 87%" />
</colgroup>
<thead>
<tr class="header">
<th>Exception</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>MrsTaskExecutionError</code></td>
<td>When the status update reports back an
<code>ERROR</code> event.</td>
</tr>
<tr class="even">
<td><code>MrsTaskExecutionCancelledError</code></td>
<td>When the status update reports back a
<code>CANCELLED</code> event.</td>
</tr>
<tr class="odd">
<td><code>MrsTaskTimeOutError</code></td>
<td>When the specified <code>timeout</code> threshold is
reached.</td>
</tr>
</tbody>
</table>
<h4 data-number="6.6.1.4" id="example-call"><span
class="header-section-number">6.6.1.4</span> Example
(call)</h4>
<div class="sourceCode" id="cb112"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb112-1"><a href="#cb112-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService</span>
<span id="cb112-2"><a href="#cb112-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb112-3"><a href="#cb112-3" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb112-4"><a href="#cb112-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb112-5"><a href="#cb112-5" aria-hidden="true" tabindex="-1"></a>res <span class="op">=</span> <span class="cf">await</span> my_service.sakila.hello_func.call(name<span class="op">=</span><span class="st">"Rui"</span>)</span>
<span id="cb112-6"><a href="#cb112-6" aria-hidden="true" tabindex="-1"></a><span class="co"># print(res) -> Hello, Rui!</span></span>
<span id="cb112-7"><a href="#cb112-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb112-8"><a href="#cb112-8" aria-hidden="true" tabindex="-1"></a>res <span class="op">=</span> <span class="cf">await</span> my_service.sakila.sum_func.call(a<span class="op">=</span><span class="dv">3</span>, b<span class="op">=</span><span class="dv">2</span>)</span>
<span id="cb112-9"><a href="#cb112-9" aria-hidden="true" tabindex="-1"></a><span class="co"># print(res) -> 5</span></span>
<span id="cb112-10"><a href="#cb112-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb112-11"><a href="#cb112-11" aria-hidden="true" tabindex="-1"></a>res <span class="op">=</span> <span class="cf">await</span> my_service.sakila.my_birthday_func.call()</span>
<span id="cb112-12"><a href="#cb112-12" aria-hidden="true" tabindex="-1"></a><span class="co"># print(res) -> 2024-07-18 00:00:00</span></span></code></pre></div>
<p>where <code>hello_func</code>, <code>sum_func</code>
and <code>my_birthday_func</code> are:</p>
<div class="sourceCode" id="cb113"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb113-1"><a href="#cb113-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- one input</span></span>
<span id="cb113-2"><a href="#cb113-2" aria-hidden="true" tabindex="-1"></a>mysql<span class="op">></span> <span class="kw">CREATE</span> <span class="kw">FUNCTION</span> hello_func (name <span class="dt">CHAR</span>(<span class="dv">20</span>))</span>
<span id="cb113-3"><a href="#cb113-3" aria-hidden="true" tabindex="-1"></a><span class="op">></span> RETURNS <span class="dt">CHAR</span>(<span class="dv">50</span>) DETERMINISTIC</span>
<span id="cb113-4"><a href="#cb113-4" aria-hidden="true" tabindex="-1"></a><span class="op">></span> <span class="kw">RETURN</span> <span class="fu">CONCAT</span>(<span class="st">'Hello, '</span>, name, <span class="st">'!'</span>);</span>
<span id="cb113-5"><a href="#cb113-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb113-6"><a href="#cb113-6" aria-hidden="true" tabindex="-1"></a><span class="co">-- many input</span></span>
<span id="cb113-7"><a href="#cb113-7" aria-hidden="true" tabindex="-1"></a>mysql<span class="op">></span> <span class="kw">CREATE</span> <span class="kw">FUNCTION</span> sum_func (a <span class="dt">INT</span>, b <span class="dt">INT</span>)</span>
<span id="cb113-8"><a href="#cb113-8" aria-hidden="true" tabindex="-1"></a><span class="op">></span> RETURNS <span class="dt">INT</span> DETERMINISTIC</span>
<span id="cb113-9"><a href="#cb113-9" aria-hidden="true" tabindex="-1"></a><span class="op">></span> <span class="kw">RETURN</span> a <span class="op">+</span> b;</span>
<span id="cb113-10"><a href="#cb113-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb113-11"><a href="#cb113-11" aria-hidden="true" tabindex="-1"></a><span class="co">-- no input</span></span>
<span id="cb113-12"><a href="#cb113-12" aria-hidden="true" tabindex="-1"></a>mysql<span class="op">></span> <span class="kw">CREATE</span> <span class="kw">FUNCTION</span> my_birthday_func ()</span>
<span id="cb113-13"><a href="#cb113-13" aria-hidden="true" tabindex="-1"></a><span class="op">></span> RETURNS DATETIME DETERMINISTIC</span>
<span id="cb113-14"><a href="#cb113-14" aria-hidden="true" tabindex="-1"></a><span class="op">></span> <span class="kw">RETURN</span> CURDATE();</span></code></pre></div>
<h3 data-number="6.6.2" id="function-start-py"><span
class="header-section-number">6.6.2</span>
Function.start</h3>
<p><code>start()</code> is used to start a REST routine
(<code>FUNCTION</code> or <code>PROCEDURE</code>), with
an associated Async Task, without waiting for it to
finish.</p>
<h4 data-number="6.6.2.1" id="options-start"><span
class="header-section-number">6.6.2.1</span> Options
(start)</h4>
<p><code>start()</code> accepts the same set of options
as <code>call()</code>, see <a
href="#functioncall-py">Function.call</a> for more
details.</p>
<h4 data-number="6.6.2.2" id="return-type-start"><span
class="header-section-number">6.6.2.2</span> Return Type
(start)</h4>
<p>A <a href="#async-tasks">Task</a> instance.</p>
<h4 data-number="6.6.2.3" id="example-start"><span
class="header-section-number">6.6.2.3</span> Example
(start)</h4>
<div class="sourceCode" id="cb114"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb114-1"><a href="#cb114-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService</span>
<span id="cb114-2"><a href="#cb114-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb114-3"><a href="#cb114-3" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb114-4"><a href="#cb114-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb114-5"><a href="#cb114-5" aria-hidden="true" tabindex="-1"></a>task <span class="op">=</span> <span class="cf">await</span> my_service.sakila.delayed_hello_func.start({<span class="st">"refresh_rate"</span>: <span class="fl">5.0</span>}, name<span class="op">=</span><span class="st">"Rui"</span>)</span></code></pre></div>
<p>where <code>delayed_hello_func</code> is:</p>
<div class="sourceCode" id="cb115"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb115-1"><a href="#cb115-1" aria-hidden="true" tabindex="-1"></a>mysql<span class="op">></span> DELIMITER $$</span>
<span id="cb115-2"><a href="#cb115-2" aria-hidden="true" tabindex="-1"></a>mysql<span class="op">></span> <span class="kw">CREATE</span> <span class="kw">FUNCTION</span> delayed_hello_func (name <span class="dt">CHAR</span>(<span class="dv">20</span>))</span>
<span id="cb115-3"><a href="#cb115-3" aria-hidden="true" tabindex="-1"></a><span class="op">></span> RETURNS <span class="dt">CHAR</span>(<span class="dv">50</span>) DETERMINISTIC</span>
<span id="cb115-4"><a href="#cb115-4" aria-hidden="true" tabindex="-1"></a><span class="op">></span> SQL SECURITY INVOKER</span>
<span id="cb115-5"><a href="#cb115-5" aria-hidden="true" tabindex="-1"></a><span class="op">></span> <span class="cf">BEGIN</span></span>
<span id="cb115-6"><a href="#cb115-6" aria-hidden="true" tabindex="-1"></a><span class="op">></span> DO SLEEP(<span class="dv">5</span>);</span>
<span id="cb115-7"><a href="#cb115-7" aria-hidden="true" tabindex="-1"></a><span class="op">></span> <span class="kw">RETURN</span> <span class="fu">CONCAT</span>(<span class="st">'Hello, '</span>, name, <span class="st">'!'</span>);</span>
<span id="cb115-8"><a href="#cb115-8" aria-hidden="true" tabindex="-1"></a><span class="op">></span> <span class="cf">END</span> $$</span></code></pre></div>
<h3 data-number="6.6.3" id="procedure-call-py"><span
class="header-section-number">6.6.3</span>
Procedure.call</h3>
<p><code>call</code> is used to execute a REST routine
(<code>FUNCTION</code> or <code>PROCEDURE</code>). In
the case of a <code>PROCEDURE</code>, the set of
<code>IN</code>/<code>INOUT</code> parameters (and
corresponding values) as specified by the database
routine are provided as corresponding keyword arguments.
If the REST routine has an associated Async Task, the
first parameter is, instead, a positional argument that
uses a Python <code>dict</code> to specify additional
task-specific execution options.</p>
<blockquote>
<p>For the sake of avoiding conflict with keyword
argument names, an arbitrary number of positional
arguments are enabled. The recommended treat is to pass
only one options dictionary, as the first positional
argument. If you, intentionally or not, pass more than
one positional argument, the option value from the later
dictionary in the sequence takes precedence</p>
</blockquote>
<h4 data-number="6.6.3.1" id="options-call-1"><span
class="header-section-number">6.6.3.1</span> Options
(call)</h4>
<p>Input parameters aren’t mandatory, meaning you are
free to not provide them.</p>
<p>In case of being provided, input parameters can also
be assigned a null value when calling the procedure, in
other words, you can set any parameters to
<code>None</code>.</p>
<p>As for additional options, see <a
href="#functioncall-py">Function.call</a> for more
details.</p>
<h4 data-number="6.6.3.2" id="return-type-call-1"><span
class="header-section-number">6.6.3.2</span> Return Type
(call)</h4>
<p>A data class object representing a REST result set.
This object includes the following attributes:</p>
<ul>
<li><p><code>out_parameters</code>: Dictionary with
fields for each <code>OUT</code>/<code>INOUT</code>
parameter declared as part of the MySQL procedure that
produces an actual value. If a parameter is not used to
return a value, the field will not be present in the
dictionary.</p></li>
<li><p><code>result_sets</code>: List of result set
types generated when executing one or more SELECT
statements as part of the procedure body. Each result
set type can include one or more items.</p></li>
</ul>
<h4 data-number="6.6.3.3" id="example-call-1"><span
class="header-section-number">6.6.3.3</span> Example
(call)</h4>
<p>Consider the following dummy procedures:</p>
<div class="sourceCode" id="cb116"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb116-1"><a href="#cb116-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- Assuming the database `mrs_tests` exists</span></span>
<span id="cb116-2"><a href="#cb116-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- You can use the MySQL Client console to run this script</span></span>
<span id="cb116-3"><a href="#cb116-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb116-4"><a href="#cb116-4" aria-hidden="true" tabindex="-1"></a>DELIMITER <span class="op">//</span></span>
<span id="cb116-5"><a href="#cb116-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb116-6"><a href="#cb116-6" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> <span class="kw">PROCEDURE</span> mrs_tests.mirror_proc (INOUT channel <span class="dt">CHAR</span>(<span class="dv">4</span>))</span>
<span id="cb116-7"><a href="#cb116-7" aria-hidden="true" tabindex="-1"></a><span class="cf">BEGIN</span></span>
<span id="cb116-8"><a href="#cb116-8" aria-hidden="true" tabindex="-1"></a> <span class="kw">SELECT</span> <span class="kw">REVERSE</span>(channel) <span class="kw">INTO</span> channel;</span>
<span id="cb116-9"><a href="#cb116-9" aria-hidden="true" tabindex="-1"></a><span class="cf">END</span><span class="op">//</span></span>
<span id="cb116-10"><a href="#cb116-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb116-11"><a href="#cb116-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb116-12"><a href="#cb116-12" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> <span class="kw">PROCEDURE</span> mrs_tests.twice_proc (<span class="kw">IN</span> <span class="dt">number</span> <span class="dt">INT</span>, <span class="kw">OUT</span> number_twice <span class="dt">INT</span>)</span>
<span id="cb116-13"><a href="#cb116-13" aria-hidden="true" tabindex="-1"></a><span class="cf">BEGIN</span></span>
<span id="cb116-14"><a href="#cb116-14" aria-hidden="true" tabindex="-1"></a> <span class="kw">SELECT</span> <span class="dt">number</span><span class="op">*</span><span class="dv">2</span> <span class="kw">INTO</span> number_twice;</span>
<span id="cb116-15"><a href="#cb116-15" aria-hidden="true" tabindex="-1"></a><span class="cf">END</span><span class="op">//</span></span>
<span id="cb116-16"><a href="#cb116-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb116-17"><a href="#cb116-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb116-18"><a href="#cb116-18" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> <span class="kw">PROCEDURE</span> mrs_tests.sample_proc(</span>
<span id="cb116-19"><a href="#cb116-19" aria-hidden="true" tabindex="-1"></a> <span class="kw">IN</span> arg1 <span class="dt">CHAR</span>(<span class="dv">5</span>), INOUT arg2 <span class="dt">CHAR</span>(<span class="dv">5</span>), <span class="kw">OUT</span> arg3 <span class="dt">FLOAT</span></span>
<span id="cb116-20"><a href="#cb116-20" aria-hidden="true" tabindex="-1"></a>)</span>
<span id="cb116-21"><a href="#cb116-21" aria-hidden="true" tabindex="-1"></a><span class="cf">BEGIN</span></span>
<span id="cb116-22"><a href="#cb116-22" aria-hidden="true" tabindex="-1"></a> <span class="kw">SELECT</span> <span class="ot">"foo"</span> <span class="kw">as</span> name, <span class="dv">42</span> <span class="kw">as</span> age;</span>
<span id="cb116-23"><a href="#cb116-23" aria-hidden="true" tabindex="-1"></a> <span class="kw">SELECT</span> <span class="ot">"bar"</span> <span class="kw">as</span> something;</span>
<span id="cb116-24"><a href="#cb116-24" aria-hidden="true" tabindex="-1"></a><span class="cf">END</span><span class="op">//</span></span>
<span id="cb116-25"><a href="#cb116-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb116-26"><a href="#cb116-26" aria-hidden="true" tabindex="-1"></a>DELIMITER ;</span></code></pre></div>
<p>Use command <code>call()</code> to call a REST
procedure in the Python SDK.</p>
<div class="sourceCode" id="cb117"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb117-1"><a href="#cb117-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService</span>
<span id="cb117-2"><a href="#cb117-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb117-3"><a href="#cb117-3" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb117-4"><a href="#cb117-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb117-5"><a href="#cb117-5" aria-hidden="true" tabindex="-1"></a>procedure_result <span class="op">=</span> <span class="cf">await</span> my_service.mrs_tests.mirror_proc.call(channel<span class="op">=</span><span class="st">"roma"</span>)</span>
<span id="cb117-6"><a href="#cb117-6" aria-hidden="true" tabindex="-1"></a><span class="bu">print</span>(procedure_result)</span>
<span id="cb117-7"><a href="#cb117-7" aria-hidden="true" tabindex="-1"></a><span class="co"># IMrsProcedureResponse(</span></span>
<span id="cb117-8"><a href="#cb117-8" aria-hidden="true" tabindex="-1"></a><span class="co"># result_sets=[],</span></span>
<span id="cb117-9"><a href="#cb117-9" aria-hidden="true" tabindex="-1"></a><span class="co"># out_parameters={"channel": "amor"}</span></span>
<span id="cb117-10"><a href="#cb117-10" aria-hidden="true" tabindex="-1"></a><span class="co"># )</span></span>
<span id="cb117-11"><a href="#cb117-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb117-12"><a href="#cb117-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb117-13"><a href="#cb117-13" aria-hidden="true" tabindex="-1"></a>procedure_result <span class="op">=</span> <span class="cf">await</span> my_service.mrs_tests.twice_proc.call(number<span class="op">=</span><span class="dv">13</span>)</span>
<span id="cb117-14"><a href="#cb117-14" aria-hidden="true" tabindex="-1"></a><span class="bu">print</span>(procedure_result)</span>
<span id="cb117-15"><a href="#cb117-15" aria-hidden="true" tabindex="-1"></a><span class="co"># IMrsProcedureResponse(</span></span>
<span id="cb117-16"><a href="#cb117-16" aria-hidden="true" tabindex="-1"></a><span class="co"># result_sets=[],</span></span>
<span id="cb117-17"><a href="#cb117-17" aria-hidden="true" tabindex="-1"></a><span class="co"># out_parameters={"number_twice": 26}</span></span>
<span id="cb117-18"><a href="#cb117-18" aria-hidden="true" tabindex="-1"></a><span class="co"># )</span></span>
<span id="cb117-19"><a href="#cb117-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb117-20"><a href="#cb117-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb117-21"><a href="#cb117-21" aria-hidden="true" tabindex="-1"></a><span class="co"># Note how `arg1` is not provided, and `arg2` is set to null.</span></span>
<span id="cb117-22"><a href="#cb117-22" aria-hidden="true" tabindex="-1"></a>procedure_result <span class="op">=</span> <span class="cf">await</span> my_service.mrs_tests.sample_proc.call(arg2<span class="op">=</span><span class="va">None</span>)</span>
<span id="cb117-23"><a href="#cb117-23" aria-hidden="true" tabindex="-1"></a><span class="bu">print</span>(procedure_result)</span>
<span id="cb117-24"><a href="#cb117-24" aria-hidden="true" tabindex="-1"></a><span class="co"># IMrsProcedureResponse(</span></span>
<span id="cb117-25"><a href="#cb117-25" aria-hidden="true" tabindex="-1"></a><span class="co"># result_sets=[</span></span>
<span id="cb117-26"><a href="#cb117-26" aria-hidden="true" tabindex="-1"></a><span class="co"># MrsProcedureResultSet(</span></span>
<span id="cb117-27"><a href="#cb117-27" aria-hidden="true" tabindex="-1"></a><span class="co"># type="items0",</span></span>
<span id="cb117-28"><a href="#cb117-28" aria-hidden="true" tabindex="-1"></a><span class="co"># items=[{"name": "foo", "age": 42}],</span></span>
<span id="cb117-29"><a href="#cb117-29" aria-hidden="true" tabindex="-1"></a><span class="co"># ),</span></span>
<span id="cb117-30"><a href="#cb117-30" aria-hidden="true" tabindex="-1"></a><span class="co"># MrsProcedureResultSet(</span></span>
<span id="cb117-31"><a href="#cb117-31" aria-hidden="true" tabindex="-1"></a><span class="co"># type="items1",</span></span>
<span id="cb117-32"><a href="#cb117-32" aria-hidden="true" tabindex="-1"></a><span class="co"># items=[{"something": "bar"}],</span></span>
<span id="cb117-33"><a href="#cb117-33" aria-hidden="true" tabindex="-1"></a><span class="co"># ),</span></span>
<span id="cb117-34"><a href="#cb117-34" aria-hidden="true" tabindex="-1"></a><span class="co"># ],</span></span>
<span id="cb117-35"><a href="#cb117-35" aria-hidden="true" tabindex="-1"></a><span class="co"># out_parameters={'arg2': None, 'arg3': None}</span></span>
<span id="cb117-36"><a href="#cb117-36" aria-hidden="true" tabindex="-1"></a><span class="co"># )</span></span></code></pre></div>
<p>The first two procedures do not generate result sets,
however the third one does. By omission, result sets are
untyped meaning generic type names are used for the
result sets.</p>
<p>If you want a typed result set, meaning you wish to
specify a type, you can do so at the MRS procedure level
via the MySQL Shell:</p>
<div class="sourceCode" id="cb118"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb118-1"><a href="#cb118-1" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> <span class="kw">OR</span> <span class="kw">REPLACE</span> REST <span class="kw">PROCEDURE</span> <span class="op">/</span>sampleProc</span>
<span id="cb118-2"><a href="#cb118-2" aria-hidden="true" tabindex="-1"></a> <span class="kw">ON</span> SERVICE <span class="op">/</span>myService <span class="kw">SCHEMA</span> <span class="op">/</span>mrsTests</span>
<span id="cb118-3"><a href="#cb118-3" aria-hidden="true" tabindex="-1"></a> <span class="kw">AS</span> mrs_tests.sample_proc</span>
<span id="cb118-4"><a href="#cb118-4" aria-hidden="true" tabindex="-1"></a> RESULT IMyServiceMrsTestsSampleProcResultSet1 {</span>
<span id="cb118-5"><a href="#cb118-5" aria-hidden="true" tabindex="-1"></a> name: name @DATATYPE(<span class="ot">"CHAR(3)"</span>),</span>
<span id="cb118-6"><a href="#cb118-6" aria-hidden="true" tabindex="-1"></a> age: age @DATATYPE(<span class="ot">"TINYINT"</span>)</span>
<span id="cb118-7"><a href="#cb118-7" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb118-8"><a href="#cb118-8" aria-hidden="true" tabindex="-1"></a> RESULT IMyServiceMrsTestsSampleProcResultSet2 {</span>
<span id="cb118-9"><a href="#cb118-9" aria-hidden="true" tabindex="-1"></a> something: something @DATATYPE(<span class="ot">"CHAR(3)"</span>)</span>
<span id="cb118-10"><a href="#cb118-10" aria-hidden="true" tabindex="-1"></a> };</span></code></pre></div>
<p>Calling the REST procedure again from the Python SDK
leads to:</p>
<div class="sourceCode" id="cb119"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb119-1"><a href="#cb119-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService</span>
<span id="cb119-2"><a href="#cb119-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb119-3"><a href="#cb119-3" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb119-4"><a href="#cb119-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb119-5"><a href="#cb119-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb119-6"><a href="#cb119-6" aria-hidden="true" tabindex="-1"></a><span class="co"># Note how `arg1` is not provided, and `arg2` is set to null.</span></span>
<span id="cb119-7"><a href="#cb119-7" aria-hidden="true" tabindex="-1"></a>procedure_result <span class="op">=</span> <span class="cf">await</span> my_service.mrs_tests.sample_proc.call(arg2<span class="op">=</span><span class="va">None</span>)</span>
<span id="cb119-8"><a href="#cb119-8" aria-hidden="true" tabindex="-1"></a><span class="co"># print(procedure_result.result_sets)</span></span>
<span id="cb119-9"><a href="#cb119-9" aria-hidden="true" tabindex="-1"></a><span class="co"># [</span></span>
<span id="cb119-10"><a href="#cb119-10" aria-hidden="true" tabindex="-1"></a><span class="co"># MrsProcedureResultSet(</span></span>
<span id="cb119-11"><a href="#cb119-11" aria-hidden="true" tabindex="-1"></a><span class="co"># type="IMyServiceMrsTestsSampleProcResultSet1",</span></span>
<span id="cb119-12"><a href="#cb119-12" aria-hidden="true" tabindex="-1"></a><span class="co"># items=[{"name": "foo", "age": 42}],</span></span>
<span id="cb119-13"><a href="#cb119-13" aria-hidden="true" tabindex="-1"></a><span class="co"># ),</span></span>
<span id="cb119-14"><a href="#cb119-14" aria-hidden="true" tabindex="-1"></a><span class="co"># MrsProcedureResultSet(</span></span>
<span id="cb119-15"><a href="#cb119-15" aria-hidden="true" tabindex="-1"></a><span class="co"># type="IMyServiceMrsTestsSampleProcResultSet2",</span></span>
<span id="cb119-16"><a href="#cb119-16" aria-hidden="true" tabindex="-1"></a><span class="co"># items=[{"something": "bar"}],</span></span>
<span id="cb119-17"><a href="#cb119-17" aria-hidden="true" tabindex="-1"></a><span class="co"># ),</span></span>
<span id="cb119-18"><a href="#cb119-18" aria-hidden="true" tabindex="-1"></a><span class="co"># ],</span></span></code></pre></div>
<h3 data-number="6.6.4" id="procedure-start-py"><span
class="header-section-number">6.6.4</span>
Procedure.start</h3>
<p>See <a href="#functionstart-py">Function.start</a>
for more details.</p>
<h4 data-number="6.6.4.1" id="options-start-1"><span
class="header-section-number">6.6.4.1</span> Options
(start)</h4>
<p><code>start()</code> accepts the same set of options
as <code>call()</code>, see <a
href="#procedurecall-py">Procedure.call</a> for more
details.</p>
<h4 data-number="6.6.4.2" id="return-type-start-1"><span
class="header-section-number">6.6.4.2</span> Return Type
(start)</h4>
<p>A <a href="#async-tasks">Task</a> instance.</p>
<h4 data-number="6.6.4.3" id="example-start-1"><span
class="header-section-number">6.6.4.3</span> Example
(start)</h4>
<div class="sourceCode" id="cb120"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb120-1"><a href="#cb120-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService</span>
<span id="cb120-2"><a href="#cb120-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb120-3"><a href="#cb120-3" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb120-4"><a href="#cb120-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb120-5"><a href="#cb120-5" aria-hidden="true" tabindex="-1"></a>task <span class="op">=</span> <span class="cf">await</span> my_service.sakila.delayed_hello_proc.start({<span class="st">"refresh_rate"</span>: <span class="fl">5.0</span>}, name<span class="op">=</span><span class="st">"Rui"</span>)</span></code></pre></div>
<p>where <code>delayed_hello_proc</code> is:</p>
<div class="sourceCode" id="cb121"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb121-1"><a href="#cb121-1" aria-hidden="true" tabindex="-1"></a>mysql<span class="op">></span> DELIMITER $$</span>
<span id="cb121-2"><a href="#cb121-2" aria-hidden="true" tabindex="-1"></a>mysql<span class="op">></span> <span class="kw">CREATE</span> <span class="kw">FUNCTION</span> delayed_hello_proc (name <span class="dt">CHAR</span>(<span class="dv">20</span>), <span class="kw">out</span> salute <span class="dt">CHAR</span>(<span class="dv">40</span>))</span>
<span id="cb121-3"><a href="#cb121-3" aria-hidden="true" tabindex="-1"></a><span class="op">></span> RETURNS <span class="dt">CHAR</span>(<span class="dv">50</span>) DETERMINISTIC</span>
<span id="cb121-4"><a href="#cb121-4" aria-hidden="true" tabindex="-1"></a><span class="op">></span> SQL SECURITY INVOKER</span>
<span id="cb121-5"><a href="#cb121-5" aria-hidden="true" tabindex="-1"></a><span class="op">></span> <span class="cf">BEGIN</span></span>
<span id="cb121-6"><a href="#cb121-6" aria-hidden="true" tabindex="-1"></a><span class="op">></span> DO SLEEP(<span class="dv">5</span>);</span>
<span id="cb121-7"><a href="#cb121-7" aria-hidden="true" tabindex="-1"></a><span class="op">></span> <span class="kw">SELECT</span> <span class="fu">CONCAT</span>(<span class="st">'Hello, '</span>, name, <span class="st">'!'</span>) <span class="kw">INTO</span> salute;</span>
<span id="cb121-8"><a href="#cb121-8" aria-hidden="true" tabindex="-1"></a><span class="op">></span> <span class="cf">END</span> $$</span></code></pre></div>
<h2 data-number="6.7" id="async-tasks"><span
class="header-section-number">6.7</span> Async
Tasks</h2>
<p>Asynchronous Tasks are an MRS construct used to
manage the life-cycle of a long-running procedure which
clients can poll to monitor for status updates. From the
client-standpoint, a Task can produce the following type
of events (status updates):</p>
<ul>
<li><code>SCHEDULED</code> starting the routine
schedules a new task</li>
<li><code>RUNNING</code> progress status updates whilst
the procedure is running</li>
<li><code>COMPLETE</code> result produced by the routine
after it finishes</li>
<li><code>TIMEOUT</code> if the routine does not produce
a result before a given timeout</li>
<li><code>ERROR</code> runtime error whilst executing
the routine</li>
<li><code>CANCELLED</code> when the associated
asynchronous task is killed before the routine
finishes</li>
</ul>
<h3 data-number="6.7.1" id="task-watch-py"><span
class="header-section-number">6.7.1</span> Task.watch
</h3>
<p><code>watch</code> is used to monitor the status of a
REST routine (<code>FUNCTION</code> or
<code>PROCEDURE</code>) with an associated Async
Task.</p>
<h4 data-number="6.7.1.1" id="return-type-watch"><span
class="header-section-number">6.7.1.1</span> Return Type
(watch)</h4>
<p>An <a
href="https://peps.python.org/pep-0525/">Asynchronous
Generator</a> instance which produces status update
reports with details about the execution context of the
REST routine.</p>
<h4 data-number="6.7.1.2" id="example-watch"><span
class="header-section-number">6.7.1.2</span> Example
(watch)</h4>
<div class="sourceCode" id="cb122"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb122-1"><a href="#cb122-1" aria-hidden="true" tabindex="-1"></a>task <span class="op">=</span> <span class="cf">await</span> my_service.my_db.delayed_hello_func.start({<span class="st">"refresh_rate"</span>: <span class="fl">3.0</span>}, name<span class="op">=</span><span class="st">"Rui"</span>)</span>
<span id="cb122-2"><a href="#cb122-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb122-3"><a href="#cb122-3" aria-hidden="true" tabindex="-1"></a><span class="cf">async</span> <span class="cf">for</span> report <span class="kw">in</span> task.watch():</span>
<span id="cb122-4"><a href="#cb122-4" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> report.status <span class="op">==</span> <span class="st">"RUNNING"</span>:</span>
<span id="cb122-5"><a href="#cb122-5" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(report.progress)</span>
<span id="cb122-6"><a href="#cb122-6" aria-hidden="true" tabindex="-1"></a> <span class="cf">elif</span> report.status <span class="op">===</span> <span class="st">"ERROR"</span>:</span>
<span id="cb122-7"><a href="#cb122-7" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(report.message)</span></code></pre></div>
<h3 data-number="6.7.2" id="task-kill-py"><span
class="header-section-number">6.7.2</span> Task.kill
</h3>
<p><code>kill</code> is used to kill the underlying
Async Task of a REST routine (<code>FUNCTION</code> or
<code>PROCEDURE</code>) and cancel its execution.</p>
<h4 data-number="6.7.2.1" id="example-kill"><span
class="header-section-number">6.7.2.1</span> Example
(kill)</h4>
<div class="sourceCode" id="cb123"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb123-1"><a href="#cb123-1" aria-hidden="true" tabindex="-1"></a>task <span class="op">=</span> <span class="cf">await</span> my_service.my_db.delayed_hello_func.start({ <span class="st">"timeout"</span>: <span class="dv">4</span> }, name<span class="op">=</span><span class="st">"Rui"</span>)</span>
<span id="cb123-2"><a href="#cb123-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb123-3"><a href="#cb123-3" aria-hidden="true" tabindex="-1"></a><span class="cf">async</span> <span class="cf">for</span> report <span class="kw">in</span> task.watch():</span>
<span id="cb123-4"><a href="#cb123-4" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> report.status <span class="op">==</span> <span class="st">"TIMEOUT"</span>:</span>
<span id="cb123-5"><a href="#cb123-5" aria-hidden="true" tabindex="-1"></a> <span class="cf">await</span> task.kill()</span>
<span id="cb123-6"><a href="#cb123-6" aria-hidden="true" tabindex="-1"></a> <span class="cf">elif</span> report.status <span class="op">===</span> <span class="st">"CANCELLED"</span>:</span>
<span id="cb123-7"><a href="#cb123-7" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(report.message)</span></code></pre></div>
<!-- Copyright (c) 2023, 2026, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2.0,
as published by the Free Software Foundation.
This program is designed to work with certain software (including
but not limited to OpenSSL) that is licensed under separate terms, as
designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have either included with
the program or referenced in the documentation.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
the GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -->
<h1 data-number="7"
id="checking-for-null-column-values"><span
class="header-section-number">7</span> Checking for NULL
Column Values</h1>
<p>MySQL supports <code>NOT NULL</code> constraints
which ensure that the value in a given column cannot be
NULL. By omission though, a column can hold
<code>NULL</code> values. With the MySQL REST Service,
records containing columns with NULL values can be
included in or excluded from the result set using the
<code>$null</code> or <code>$notnull</code>
operators.</p>
<p>The TypeScript MRS SDK provides a special syntax for
filtering records in a result set by a given field when
it contains (or not) a <code>NULL</code> value. With a
setup using the <a
href="https://dev.mysql.com/doc/sakila/en/">Sakila
Sample Database</a> where the schema is available under
a REST service called <code>myService</code>, filtering
records by <code>NULL</code> column values can be done
as follows:</p>
<div class="sourceCode" id="cb124"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb124-1"><a href="#cb124-1" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">address</span><span class="op">.</span><span class="fu">find</span>({ select<span class="op">:</span> [<span class="st">"address"</span><span class="op">,</span> <span class="st">"address2"</span>]<span class="op">,</span> where<span class="op">:</span> { address2<span class="op">:</span> <span class="dt">null</span> } })</span>
<span id="cb124-2"><a href="#cb124-2" aria-hidden="true" tabindex="-1"></a>[</span>
<span id="cb124-3"><a href="#cb124-3" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb124-4"><a href="#cb124-4" aria-hidden="true" tabindex="-1"></a> <span class="st">"address"</span><span class="op">:</span> <span class="st">"47 MySakila Drive"</span><span class="op">,</span></span>
<span id="cb124-5"><a href="#cb124-5" aria-hidden="true" tabindex="-1"></a> <span class="st">"address2"</span><span class="op">:</span> null<span class="op">,</span></span>
<span id="cb124-6"><a href="#cb124-6" aria-hidden="true" tabindex="-1"></a> }<span class="op">,</span></span>
<span id="cb124-7"><a href="#cb124-7" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb124-8"><a href="#cb124-8" aria-hidden="true" tabindex="-1"></a> <span class="st">"address"</span><span class="op">:</span> <span class="st">"28 MySQL Boulevard"</span><span class="op">,</span></span>
<span id="cb124-9"><a href="#cb124-9" aria-hidden="true" tabindex="-1"></a> <span class="st">"address2"</span><span class="op">:</span> null<span class="op">,</span></span>
<span id="cb124-10"><a href="#cb124-10" aria-hidden="true" tabindex="-1"></a> }<span class="op">,</span></span>
<span id="cb124-11"><a href="#cb124-11" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb124-12"><a href="#cb124-12" aria-hidden="true" tabindex="-1"></a> <span class="st">"address"</span><span class="op">:</span> <span class="st">"23 Workhaven Lane"</span><span class="op">,</span></span>
<span id="cb124-13"><a href="#cb124-13" aria-hidden="true" tabindex="-1"></a> <span class="st">"address2"</span><span class="op">:</span> null<span class="op">,</span></span>
<span id="cb124-14"><a href="#cb124-14" aria-hidden="true" tabindex="-1"></a> }<span class="op">,</span></span>
<span id="cb124-15"><a href="#cb124-15" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb124-16"><a href="#cb124-16" aria-hidden="true" tabindex="-1"></a> <span class="st">"address"</span><span class="op">:</span> <span class="st">"1411 Lillydale Drive"</span><span class="op">,</span></span>
<span id="cb124-17"><a href="#cb124-17" aria-hidden="true" tabindex="-1"></a> <span class="st">"address2"</span><span class="op">:</span> null<span class="op">,</span></span>
<span id="cb124-18"><a href="#cb124-18" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb124-19"><a href="#cb124-19" aria-hidden="true" tabindex="-1"></a>]</span></code></pre></div>
<p>In the same way, filtering records where a given
column does not contain <code>NULL</code> can be done as
follows:</p>
<div class="sourceCode" id="cb125"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb125-1"><a href="#cb125-1" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">actor</span><span class="op">.</span><span class="fu">findFirst</span>({ select<span class="op">:</span> [<span class="st">"address"</span><span class="op">,</span> <span class="st">"address2"</span>]<span class="op">,</span> where<span class="op">:</span> { address2<span class="op">:</span> { not<span class="op">:</span> <span class="dt">null</span> } } })</span>
<span id="cb125-2"><a href="#cb125-2" aria-hidden="true" tabindex="-1"></a>{</span>
<span id="cb125-3"><a href="#cb125-3" aria-hidden="true" tabindex="-1"></a> <span class="st">"address"</span><span class="op">:</span> <span class="st">"1913 Hanoi Way"</span><span class="op">,</span></span>
<span id="cb125-4"><a href="#cb125-4" aria-hidden="true" tabindex="-1"></a> <span class="st">"address2"</span><span class="op">:</span> <span class="st">""</span><span class="op">,</span></span>
<span id="cb125-5"><a href="#cb125-5" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>Attempting to apply such a filter to a field that
maps to a column with a <code>NOT NULL</code> constraint
should yield a TypeScript compilation error:</p>
<div class="sourceCode" id="cb126"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb126-1"><a href="#cb126-1" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">actor</span><span class="op">.</span><span class="fu">findFirst</span>({ where<span class="op">:</span> { address<span class="op">:</span> <span class="dt">null</span> } })</span></code></pre></div>
<pre><code>Type 'null' is not assignable to type 'string | DataFilterField<IMyServiceSakilaAddressParams, string | undefined> | ComparisonOpExpr<string | undefined>[] | undefined'.</code></pre>
<!-- Copyright (c) 2023, 2026, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2.0,
as published by the Free Software Foundation.
This program is designed to work with certain software (including
but not limited to OpenSSL) that is licensed under separate terms, as
designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have either included with
the program or referenced in the documentation.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
the GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -->
<h1 data-number="8" id="working-with-data-types"><span
class="header-section-number">8</span> Working with Data
Types</h1>
<p>MySQL supports and extensive list of data types that
cannot be directly mapped development language native
datatypes in many cases. This section discusses how to
handles those MySQL datatypes in the Client SDK. The
conversion rules apply consistently across REST View
fields, REST Procedure input and output parameters and
REST function input parameters and results.</p>
<h2 data-number="8.1" id="spatial-data-types"><span
class="header-section-number">8.1</span> Spatial Data
Types</h2>
<p>MySQL supports an extended SQL environment, based on
the conventions established by the OpenGIS Geometry
Model, that enables a set of spatial column data types
to hold geometry values. Some of them hold single
values:</p>
<ul>
<li><code>POINT</code></li>
<li><code>LINESTRING</code></li>
<li><code>POLYGON</code></li>
</ul>
<p>On the other hand, there are spatial data types that
are meant to hold collections of geometry values:</p>
<ul>
<li><code>MULTIPOINT</code></li>
<li><code>MULTILINESTRING</code></li>
<li><code>MULTIPOLYGON</code></li>
<li><code>GEOMETRYCOLLECTION</code></li>
</ul>
<p><code>GEOMETRYCOLLECTION</code> can store a
collection of objects of any type. The other collection
types (<code>MULTIPOINT</code>,
<code>MULTILINESTRING</code>, and
<code>MULTIPOLYGON</code>) restrict collection members
to those having a particular geometry type.</p>
<p>Additionally, there is a <code>GEOMETRY</code> data
type that is meant to hold any kind of value for the
data types described above.</p>
<h3 data-number="8.1.1" id="typescript-sdk"><span
class="header-section-number">8.1.1</span> TypeScript
SDK</h3>
<p>MySQL Rest Service (MRS) TypeScript SDK expects a
GeoJSON-like object for representing, operating on, or
manipulating spatial data.</p>
<p>For instance, with a setup using the <a
href="https://dev.mysql.com/doc/sakila/en/">Sakila
Sample Database</a> where the schema is available under
a REST service called <code>myService</code>, when
inserting records into the <code>address</code> table,
you can use a GeoJSON-like object to specify the value
for the <code>location</code> column, which has a
generic <code>GEOMETRY</code> data type, as described in
the following sections.</p>
<p><strong><em>Upstream Commands</em></strong></p>
<h4 data-number="8.1.1.1" id="create"><span
class="header-section-number">8.1.1.1</span> Create</h4>
<div class="sourceCode" id="cb128"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb128-1"><a href="#cb128-1" aria-hidden="true" tabindex="-1"></a><span class="co">// GeoJSON</span></span>
<span id="cb128-2"><a href="#cb128-2" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">address</span><span class="op">.</span><span class="fu">create</span>({ data<span class="op">:</span> {</span>
<span id="cb128-3"><a href="#cb128-3" aria-hidden="true" tabindex="-1"></a> location<span class="op">:</span> {</span>
<span id="cb128-4"><a href="#cb128-4" aria-hidden="true" tabindex="-1"></a> type<span class="op">:</span> <span class="st">"Point"</span><span class="op">,</span></span>
<span id="cb128-5"><a href="#cb128-5" aria-hidden="true" tabindex="-1"></a> coordinates<span class="op">:</span> [<span class="fl">11.11</span><span class="op">,</span> <span class="fl">12.22</span>]</span>
<span id="cb128-6"><a href="#cb128-6" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb128-7"><a href="#cb128-7" aria-hidden="true" tabindex="-1"></a>}})</span></code></pre></div>
<h4 data-number="8.1.1.2" id="update"><span
class="header-section-number">8.1.1.2</span> Update</h4>
<p>The same convention should also apply when updating
records on the same table.</p>
<div class="sourceCode" id="cb129"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb129-1"><a href="#cb129-1" aria-hidden="true" tabindex="-1"></a><span class="co">// GeoJSON</span></span>
<span id="cb129-2"><a href="#cb129-2" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">address</span><span class="op">.</span><span class="fu">update</span>({</span>
<span id="cb129-3"><a href="#cb129-3" aria-hidden="true" tabindex="-1"></a> where<span class="op">:</span> {</span>
<span id="cb129-4"><a href="#cb129-4" aria-hidden="true" tabindex="-1"></a> address_id<span class="op">:</span> <span class="dv">1</span></span>
<span id="cb129-5"><a href="#cb129-5" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb129-6"><a href="#cb129-6" aria-hidden="true" tabindex="-1"></a> data<span class="op">:</span> {</span>
<span id="cb129-7"><a href="#cb129-7" aria-hidden="true" tabindex="-1"></a> location<span class="op">:</span> {</span>
<span id="cb129-8"><a href="#cb129-8" aria-hidden="true" tabindex="-1"></a> type<span class="op">:</span> <span class="st">"Point"</span><span class="op">,</span></span>
<span id="cb129-9"><a href="#cb129-9" aria-hidden="true" tabindex="-1"></a> coordinates<span class="op">:</span> [<span class="fl">11.11</span><span class="op">,</span> <span class="fl">12.22</span>]</span>
<span id="cb129-10"><a href="#cb129-10" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb129-11"><a href="#cb129-11" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb129-12"><a href="#cb129-12" aria-hidden="true" tabindex="-1"></a>})</span>
<span id="cb129-13"><a href="#cb129-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb129-14"><a href="#cb129-14" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">sakila</span><span class="op">.</span><span class="at">address</span><span class="op">.</span><span class="fu">updateMany</span>({</span>
<span id="cb129-15"><a href="#cb129-15" aria-hidden="true" tabindex="-1"></a> where<span class="op">:</span> [{</span>
<span id="cb129-16"><a href="#cb129-16" aria-hidden="true" tabindex="-1"></a> address_id<span class="op">:</span> <span class="dv">1</span></span>
<span id="cb129-17"><a href="#cb129-17" aria-hidden="true" tabindex="-1"></a> }<span class="op">,</span> {</span>
<span id="cb129-18"><a href="#cb129-18" aria-hidden="true" tabindex="-1"></a> address_id<span class="op">:</span> <span class="dv">2</span></span>
<span id="cb129-19"><a href="#cb129-19" aria-hidden="true" tabindex="-1"></a> }]<span class="op">,</span></span>
<span id="cb129-20"><a href="#cb129-20" aria-hidden="true" tabindex="-1"></a> data<span class="op">:</span> {</span>
<span id="cb129-21"><a href="#cb129-21" aria-hidden="true" tabindex="-1"></a> location<span class="op">:</span> {</span>
<span id="cb129-22"><a href="#cb129-22" aria-hidden="true" tabindex="-1"></a> type<span class="op">:</span> <span class="st">"Point"</span><span class="op">,</span></span>
<span id="cb129-23"><a href="#cb129-23" aria-hidden="true" tabindex="-1"></a> coordinates<span class="op">:</span> [<span class="fl">11.11</span><span class="op">,</span> <span class="fl">12.22</span>]</span>
<span id="cb129-24"><a href="#cb129-24" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb129-25"><a href="#cb129-25" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb129-26"><a href="#cb129-26" aria-hidden="true" tabindex="-1"></a>})</span></code></pre></div>
<h4 data-number="8.1.1.3" id="types-mismatch"><span
class="header-section-number">8.1.1.3</span> Types
Mismatch</h4>
<p>If the column has a narrow data type such as
<code>POINT</code>, instead of the more generic
<code>GEOMETRY</code>, specifying an incompatible type
on the client-side, should yield a compilation error.
For example, assuming a table
<code>mrs_tests</code>.<code>spatial_tests</code>
created as follows:</p>
<div class="sourceCode" id="cb130"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb130-1"><a href="#cb130-1" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> <span class="kw">DATABASE</span> <span class="cf">IF</span> <span class="kw">NOT</span> <span class="kw">EXISTS</span> mrs_tests;</span>
<span id="cb130-2"><a href="#cb130-2" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> <span class="kw">TABLE</span> <span class="cf">IF</span> <span class="kw">NOT</span> <span class="kw">EXISTS</span> mrs_tests.spatial_tests (<span class="kw">id</span> <span class="dt">INT</span> AUTO_INCREMENT <span class="kw">NOT</span> <span class="kw">NULL</span>, ls LINESTRING, <span class="kw">PRIMARY</span> <span class="kw">KEY</span> (<span class="kw">id</span>));</span></code></pre></div>
<p>With the table (and corresponding schema) available
from the same <code>myService</code> REST service,
trying to insert a <code>POINT</code> does not work,
because the column only accepts a
<code>LINESTRING</code>.</p>
<div class="sourceCode" id="cb131"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb131-1"><a href="#cb131-1" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">mrsTests</span><span class="op">.</span><span class="at">spatialTests</span><span class="op">.</span><span class="fu">create</span>({</span>
<span id="cb131-2"><a href="#cb131-2" aria-hidden="true" tabindex="-1"></a> data<span class="op">:</span> {</span>
<span id="cb131-3"><a href="#cb131-3" aria-hidden="true" tabindex="-1"></a> ls<span class="op">:</span> {</span>
<span id="cb131-4"><a href="#cb131-4" aria-hidden="true" tabindex="-1"></a> type<span class="op">:</span> <span class="st">"Point"</span><span class="op">,</span></span>
<span id="cb131-5"><a href="#cb131-5" aria-hidden="true" tabindex="-1"></a> coordinates<span class="op">:</span> [<span class="dv">0</span><span class="op">,</span> <span class="dv">0</span>]</span>
<span id="cb131-6"><a href="#cb131-6" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb131-7"><a href="#cb131-7" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb131-8"><a href="#cb131-8" aria-hidden="true" tabindex="-1"></a>})</span></code></pre></div>
<p>A command like the one above yields a compilation
error.</p>
<blockquote>
<p>Type ‘Point’ is not assignable to type
‘LineString’.</p>
</blockquote>
<p>In the same way, trying to insert or update multiple
values for a single field when the column data type only
allows a single value, or vice-versa, should also yield
a compilation error. For, example, assuming the
<code>mrs_tests.spatial_tests</code> table was created
as follows:</p>
<div class="sourceCode" id="cb132"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb132-1"><a href="#cb132-1" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> <span class="kw">TABLE</span> <span class="cf">IF</span> <span class="kw">NOT</span> <span class="kw">EXISTS</span> mrs_tests.spatial_tests (<span class="kw">id</span> <span class="dt">INT</span> AUTO_INCREMENT <span class="kw">NOT</span> <span class="kw">NULL</span>, ls GEOMETRYCOLLECTION, <span class="kw">PRIMARY</span> <span class="kw">KEY</span> (<span class="kw">id</span>));</span></code></pre></div>
<p>Trying to insert a <code>POINT</code> does not work,
because the column only accepts either a
<code>MULTIPOINT</code>, a <code>MULTILINESTRING</code>
or a <code>MULTIPOLYGON</code>.</p>
<div class="sourceCode" id="cb133"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb133-1"><a href="#cb133-1" aria-hidden="true" tabindex="-1"></a>myService<span class="op">.</span><span class="at">mrsTests</span><span class="op">.</span><span class="at">spatialTests</span><span class="op">.</span><span class="fu">create</span>({</span>
<span id="cb133-2"><a href="#cb133-2" aria-hidden="true" tabindex="-1"></a> data<span class="op">:</span> {</span>
<span id="cb133-3"><a href="#cb133-3" aria-hidden="true" tabindex="-1"></a> ls<span class="op">:</span> {</span>
<span id="cb133-4"><a href="#cb133-4" aria-hidden="true" tabindex="-1"></a> type<span class="op">:</span> <span class="st">"Point"</span><span class="op">,</span></span>
<span id="cb133-5"><a href="#cb133-5" aria-hidden="true" tabindex="-1"></a> coordinates<span class="op">:</span> [<span class="dv">0</span><span class="op">,</span> <span class="dv">0</span>]</span>
<span id="cb133-6"><a href="#cb133-6" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb133-7"><a href="#cb133-7" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb133-8"><a href="#cb133-8" aria-hidden="true" tabindex="-1"></a>})</span></code></pre></div>
<p>In this case, the command yields the following
compilation error:</p>
<blockquote>
<p>Type ‘Point’ is not assignable to type ‘MultiPoint |
MultiLineString | MultiPolygon’.</p>
</blockquote>
<h3 data-number="8.1.2" id="python-sdk"><span
class="header-section-number">8.1.2</span> Python
SDK</h3>
<p>MySQL Rest Service (MRS) Python SDK supports one
format for representing, operating on, or manipulating
spatial data:</p>
<ul>
<li><a
href="https://dev.mysql.com/doc/refman/9.1/en/opengis-geometry-model.html">GeoJSON</a></li>
</ul>
<p>This format can be used when inserting or updating
(upstream operations) a record that contains a field
matching a column of a Spatial data type. Symmetrically,
for downstream operations such as finding records having
spatial fields, such fields are specified as GeoJSON
types.</p>
<p>For instance, with a setup using the <a
href="https://dev.mysql.com/doc/sakila/en/">Sakila
Sample Database</a> where the schema is available under
a REST service called <code>myService</code>, when
inserting records into the <code>address</code> table,
you can work with the value for the
<code>location</code> column, which has a generic
<code>GEOMETRY</code> data type, as described in the
following sections.</p>
<p><strong><em>Upstream Commands</em></strong></p>
<h4 data-number="8.1.2.1" id="create-1"><span
class="header-section-number">8.1.2.1</span> Create</h4>
<p>Inserting a record into the address table in the
Sakila sample database.</p>
<div class="sourceCode" id="cb134"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb134-1"><a href="#cb134-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService, IMyServiceSakilaAddress <span class="im">as</span> Address</span>
<span id="cb134-2"><a href="#cb134-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb134-3"><a href="#cb134-3" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb134-4"><a href="#cb134-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb134-5"><a href="#cb134-5" aria-hidden="true" tabindex="-1"></a>address: Address <span class="op">=</span> <span class="cf">await</span> myService.sakila.address.create(</span>
<span id="cb134-6"><a href="#cb134-6" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb134-7"><a href="#cb134-7" aria-hidden="true" tabindex="-1"></a> <span class="st">"location"</span>: {</span>
<span id="cb134-8"><a href="#cb134-8" aria-hidden="true" tabindex="-1"></a> <span class="st">"type"</span>: <span class="st">"Point"</span>,</span>
<span id="cb134-9"><a href="#cb134-9" aria-hidden="true" tabindex="-1"></a> <span class="st">"coordinates"</span>: [<span class="fl">11.11</span>, <span class="fl">12.22</span>],</span>
<span id="cb134-10"><a href="#cb134-10" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb134-11"><a href="#cb134-11" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb134-12"><a href="#cb134-12" aria-hidden="true" tabindex="-1"></a>)</span></code></pre></div>
<h4 data-number="8.1.2.2" id="update-1"><span
class="header-section-number">8.1.2.2</span> Update</h4>
<p>Updating a record from the address table in the
Sakila sample database.</p>
<div class="sourceCode" id="cb135"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb135-1"><a href="#cb135-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService, IMyServiceSakilaAddress <span class="im">as</span> Address</span>
<span id="cb135-2"><a href="#cb135-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb135-3"><a href="#cb135-3" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb135-4"><a href="#cb135-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb135-5"><a href="#cb135-5" aria-hidden="true" tabindex="-1"></a>address: Address <span class="op">=</span> <span class="cf">await</span> myService.sakila.address.update(</span>
<span id="cb135-6"><a href="#cb135-6" aria-hidden="true" tabindex="-1"></a> data<span class="op">=</span>{</span>
<span id="cb135-7"><a href="#cb135-7" aria-hidden="true" tabindex="-1"></a> <span class="st">"address_id"</span>: <span class="dv">1</span>,</span>
<span id="cb135-8"><a href="#cb135-8" aria-hidden="true" tabindex="-1"></a> <span class="st">"location"</span>: {</span>
<span id="cb135-9"><a href="#cb135-9" aria-hidden="true" tabindex="-1"></a> <span class="st">"type"</span>: <span class="st">"Point"</span>,</span>
<span id="cb135-10"><a href="#cb135-10" aria-hidden="true" tabindex="-1"></a> <span class="st">"coordinates"</span>: [<span class="fl">11.11</span>, <span class="fl">12.22</span>],</span>
<span id="cb135-11"><a href="#cb135-11" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb135-12"><a href="#cb135-12" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb135-13"><a href="#cb135-13" aria-hidden="true" tabindex="-1"></a>)</span></code></pre></div>
<p><strong><em>Downstream Commands</em></strong></p>
<h4 data-number="8.1.2.3" id="find"><span
class="header-section-number">8.1.2.3</span> Find</h4>
<p>Finding a record from the address table in the Sakila
sample database.</p>
<div class="sourceCode" id="cb136"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb136-1"><a href="#cb136-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService, IMyServiceSakilaAddress <span class="im">as</span> Address, MrsDocumentNotFoundError</span>
<span id="cb136-2"><a href="#cb136-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb136-3"><a href="#cb136-3" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb136-4"><a href="#cb136-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb136-5"><a href="#cb136-5" aria-hidden="true" tabindex="-1"></a>doc_id <span class="op">=</span> <span class="dv">1</span></span>
<span id="cb136-6"><a href="#cb136-6" aria-hidden="true" tabindex="-1"></a><span class="cf">try</span>:</span>
<span id="cb136-7"><a href="#cb136-7" aria-hidden="true" tabindex="-1"></a> address: Address <span class="op">=</span> <span class="cf">await</span> myService.sakila.address.find_first_or_throw(</span>
<span id="cb136-8"><a href="#cb136-8" aria-hidden="true" tabindex="-1"></a> where<span class="op">=</span>{<span class="st">"address_id"</span>: doc_id}</span>
<span id="cb136-9"><a href="#cb136-9" aria-hidden="true" tabindex="-1"></a> )</span>
<span id="cb136-10"><a href="#cb136-10" aria-hidden="true" tabindex="-1"></a><span class="cf">except</span> MrsDocumentNotFoundError:</span>
<span id="cb136-11"><a href="#cb136-11" aria-hidden="true" tabindex="-1"></a> <span class="cf">raise</span> MrsDocumentNotFoundError(msg<span class="op">=</span><span class="ss">f"No address document exists matching actor_id=</span><span class="sc">{</span>doc_id<span class="sc">}</span><span class="ss">"</span>)</span>
<span id="cb136-12"><a href="#cb136-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb136-13"><a href="#cb136-13" aria-hidden="true" tabindex="-1"></a><span class="bu">print</span>(address.location)</span>
<span id="cb136-14"><a href="#cb136-14" aria-hidden="true" tabindex="-1"></a><span class="co"># {"type": "Point", "coordinates": [11.11, 12.22]}</span></span></code></pre></div>
<h4 data-number="8.1.2.4" id="types-mismatch-1"><span
class="header-section-number">8.1.2.4</span> Types
Mismatch</h4>
<p>If the column has a narrow data type such as
<code>POINT</code>, instead of the more generic
<code>GEOMETRY</code>, specifying an incompatible type
on the client-side, should yield a mypy (typing system)
error. For example, assuming a table
<code>mrs_tests.spatial_tests</code> created as
follows:</p>
<div class="sourceCode" id="cb137"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb137-1"><a href="#cb137-1" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> <span class="kw">DATABASE</span> <span class="cf">IF</span> <span class="kw">NOT</span> <span class="kw">EXISTS</span> mrs_tests;</span>
<span id="cb137-2"><a href="#cb137-2" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> <span class="kw">TABLE</span> <span class="cf">IF</span> <span class="kw">NOT</span> <span class="kw">EXISTS</span> mrs_tests.spatial_tests (<span class="kw">id</span> <span class="dt">INT</span> AUTO_INCREMENT <span class="kw">NOT</span> <span class="kw">NULL</span>, ls LINESTRING, <span class="kw">PRIMARY</span> <span class="kw">KEY</span> (<span class="kw">id</span>));</span></code></pre></div>
<p>Trying to insert a <code>Point</code> triggers a
typing error, because the column only accepts a
<code>LineString</code>.</p>
<div class="sourceCode" id="cb138"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb138-1"><a href="#cb138-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python.my_service <span class="im">import</span> IMyServiceMrsTestsSpatialTests <span class="im">as</span> SpatialTests</span>
<span id="cb138-2"><a href="#cb138-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb138-3"><a href="#cb138-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb138-4"><a href="#cb138-4" aria-hidden="true" tabindex="-1"></a>my_doc: SpatialTests <span class="op">=</span> <span class="cf">await</span> myService.mrs_tests.spatial_tests.update(</span>
<span id="cb138-5"><a href="#cb138-5" aria-hidden="true" tabindex="-1"></a> data<span class="op">=</span>{</span>
<span id="cb138-6"><a href="#cb138-6" aria-hidden="true" tabindex="-1"></a> <span class="st">"id"</span>: <span class="dv">1</span>,</span>
<span id="cb138-7"><a href="#cb138-7" aria-hidden="true" tabindex="-1"></a> <span class="st">"ls"</span>: {</span>
<span id="cb138-8"><a href="#cb138-8" aria-hidden="true" tabindex="-1"></a> <span class="st">"type"</span>: <span class="st">"Point"</span>,</span>
<span id="cb138-9"><a href="#cb138-9" aria-hidden="true" tabindex="-1"></a> <span class="st">"coordinates"</span>: [<span class="dv">0</span>, <span class="dv">0</span>],</span>
<span id="cb138-10"><a href="#cb138-10" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb138-11"><a href="#cb138-11" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb138-12"><a href="#cb138-12" aria-hidden="true" tabindex="-1"></a>)</span></code></pre></div>
<blockquote>
<p>Type <code>Point</code> is not assignable to type
<code>LineString</code>.</p>
</blockquote>
<p>In the same way, trying to insert or update multiple
values for a single field when the column data type only
allows a single value, or vice-versa, should also yield
a typing error. For example, assuming the table
<code>mrs_tests.spatial_tests</code> was, instead,
created as follows:</p>
<div class="sourceCode" id="cb139"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb139-1"><a href="#cb139-1" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> <span class="kw">TABLE</span> <span class="cf">IF</span> <span class="kw">NOT</span> <span class="kw">EXISTS</span> mrs_tests.spatial_tests (<span class="kw">id</span> <span class="dt">INT</span> AUTO_INCREMENT <span class="kw">NOT</span> <span class="kw">NULL</span>, ls GEOMETRYCOLLECTION, <span class="kw">PRIMARY</span> <span class="kw">KEY</span> (<span class="kw">id</span>));</span></code></pre></div>
<p>Trying to insert a <code>Point</code> triggers a
typing error, because the column only accepts either a
<code>MultiPoint</code>, a <code>MultiLineString</code>
or a <code>MultiPolygon</code>.</p>
<div class="sourceCode" id="cb140"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb140-1"><a href="#cb140-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python.my_service <span class="im">import</span> IMyServiceMrsTestsSpatialTests <span class="im">as</span> SpatialTests</span>
<span id="cb140-2"><a href="#cb140-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb140-3"><a href="#cb140-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb140-4"><a href="#cb140-4" aria-hidden="true" tabindex="-1"></a>my_doc: SpatialTests <span class="op">=</span> <span class="cf">await</span> myService.mrs_tests.spatial_tests.create(</span>
<span id="cb140-5"><a href="#cb140-5" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb140-6"><a href="#cb140-6" aria-hidden="true" tabindex="-1"></a> <span class="st">"ls"</span>: {</span>
<span id="cb140-7"><a href="#cb140-7" aria-hidden="true" tabindex="-1"></a> <span class="st">"type"</span>: <span class="st">"Point"</span>,</span>
<span id="cb140-8"><a href="#cb140-8" aria-hidden="true" tabindex="-1"></a> <span class="st">"coordinates"</span>: [<span class="dv">0</span>, <span class="dv">0</span>],</span>
<span id="cb140-9"><a href="#cb140-9" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb140-10"><a href="#cb140-10" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb140-11"><a href="#cb140-11" aria-hidden="true" tabindex="-1"></a>)</span></code></pre></div>
<blockquote>
<p>Type <code>Point</code> is not assignable to type
<code>MultiPoint</code>, <code>MultiLineString</code> or
<code>MultiPolygon</code>.</p>
</blockquote>
<h2 data-number="8.2"
id="working-with-date-and-time-data-types"><span
class="header-section-number">8.2</span> Working with
Date and Time Data Types</h2>
<p>MySQL supports date and time data types for
representing temporal values:</p>
<ul>
<li><a
href="https://dev.mysql.com/doc/refman/8.4/en/datetime.html">TIMESTAMP</a>
- contain both date and time parts.</li>
<li><a
href="https://dev.mysql.com/doc/refman/8.4/en/datetime.html">DATETIME</a>
- contain both date and time parts.</li>
<li><a
href="https://dev.mysql.com/doc/refman/8.4/en/datetime.html">DATE</a>
- contain date part but no time part.</li>
<li><a
href="https://dev.mysql.com/doc/refman/8.4/en/time.html">TIME</a>
- contain time but not date part.</li>
<li><a
href="https://dev.mysql.com/doc/refman/8.4/en/year.html">YEAR</a>
- represent year values.</li>
</ul>
<p>Visit the <a
href="https://dev.mysql.com/doc/refman/8.4/en/date-and-time-types.html">official
documentation</a> to know more about these MySQL data
types.</p>
<h3 data-number="8.2.1" id="python-sdk-1"><span
class="header-section-number">8.2.1</span> Python
SDK</h3>
<p>MySQL Rest Service (MRS) Python SDK utilizes the
following client-side data types for representing,
operating on, or manipulating MySQL date and time
data:</p>
<table>
<caption>MRS Python SDK data type mapping</caption>
<colgroup>
<col style="width: 52%" />
<col style="width: 47%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: center;">MySQL data type</th>
<th style="text-align: center;">MRS Python SDK data
type</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: center;">TIMESTAMP</td>
<td style="text-align: center;"><a
href="https://docs.python.org/3/library/datetime.html#datetime.datetime"><code>datetime.datetime</code></a></td>
</tr>
<tr class="even">
<td style="text-align: center;">DATETIME</td>
<td style="text-align: center;"><a
href="https://docs.python.org/3/library/datetime.html#datetime.datetime"><code>datetime.datetime</code></a></td>
</tr>
<tr class="odd">
<td style="text-align: center;">DATE</td>
<td style="text-align: center;"><a
href="https://docs.python.org/3/library/datetime.html#datetime.date"><code>datetime.date</code></a></td>
</tr>
<tr class="even">
<td style="text-align: center;">TIME</td>
<td style="text-align: center;"><a
href="https://docs.python.org/3/library/datetime.html#datetime.timedelta"><code>datetime.timedelta</code></a></td>
</tr>
<tr class="odd">
<td style="text-align: center;">YEAR</td>
<td style="text-align: center;"><code>int</code></td>
</tr>
</tbody>
</table>
<p>The MRS Python SDK data types shall be used when
inserting or updating (upstream operations) a record
that contains a field matching a column of a <em>date
and time</em> data type. Symmetrically, for downstream
operations such as finding records having <em>date and
time</em> fields, such fields are specified with MRS
Python SDK data types according to the above
equivalences.</p>
<p>In the following sections, fictional but relevant
examples are presented to showcase the usage of MySQL
Date and Time data types via the MRS Python SDK.</p>
<blockquote>
<p>The examples assume a sample database named
<code>mrs_tests</code> exists.</p>
</blockquote>
<h4 data-number="8.2.1.1" id="example---view"><span
class="header-section-number">8.2.1.1</span> Example -
View</h4>
<p>Consider the following sample table:</p>
<div class="sourceCode" id="cb141"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb141-1"><a href="#cb141-1" aria-hidden="true" tabindex="-1"></a><span class="co">/*</span></span>
<span id="cb141-2"><a href="#cb141-2" aria-hidden="true" tabindex="-1"></a><span class="co">Sample table including a column for each date and time data type.</span></span>
<span id="cb141-3"><a href="#cb141-3" aria-hidden="true" tabindex="-1"></a><span class="co">*/</span></span>
<span id="cb141-4"><a href="#cb141-4" aria-hidden="true" tabindex="-1"></a><span class="kw">DROP</span> <span class="kw">TABLE</span> <span class="cf">IF</span> <span class="kw">EXISTS</span> mrs_tests.table_date_and_time;</span>
<span id="cb141-5"><a href="#cb141-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb141-6"><a href="#cb141-6" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> <span class="kw">TABLE</span> mrs_tests.table_date_and_time (</span>
<span id="cb141-7"><a href="#cb141-7" aria-hidden="true" tabindex="-1"></a> idx <span class="dt">SMALLINT</span> UNSIGNED <span class="kw">NOT</span> <span class="kw">NULL</span> AUTO_INCREMENT,</span>
<span id="cb141-8"><a href="#cb141-8" aria-hidden="true" tabindex="-1"></a> ts <span class="dt">TIMESTAMP</span> <span class="kw">DEFAULT</span> <span class="fu">CURRENT_TIMESTAMP</span> <span class="kw">ON</span> <span class="kw">UPDATE</span> <span class="fu">CURRENT_TIMESTAMP</span>,</span>
<span id="cb141-9"><a href="#cb141-9" aria-hidden="true" tabindex="-1"></a> dt DATETIME(<span class="dv">6</span>),</span>
<span id="cb141-10"><a href="#cb141-10" aria-hidden="true" tabindex="-1"></a> d <span class="dt">DATE</span>,</span>
<span id="cb141-11"><a href="#cb141-11" aria-hidden="true" tabindex="-1"></a> t <span class="dt">TIME</span>(<span class="dv">6</span>),</span>
<span id="cb141-12"><a href="#cb141-12" aria-hidden="true" tabindex="-1"></a> y <span class="dt">YEAR</span>,</span>
<span id="cb141-13"><a href="#cb141-13" aria-hidden="true" tabindex="-1"></a> <span class="kw">PRIMARY</span> <span class="kw">KEY</span> (idx)</span>
<span id="cb141-14"><a href="#cb141-14" aria-hidden="true" tabindex="-1"></a>);</span>
<span id="cb141-15"><a href="#cb141-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb141-16"><a href="#cb141-16" aria-hidden="true" tabindex="-1"></a><span class="kw">INSERT</span> <span class="kw">INTO</span> mrs_tests.table_date_and_time (dt, dt_shorter, d, t, y) <span class="kw">VALUES</span></span>
<span id="cb141-17"><a href="#cb141-17" aria-hidden="true" tabindex="-1"></a> (<span class="ot">"2023-07-30 14:59:01"</span>, <span class="ot">"2023-07-30 14:59:01"</span>, <span class="ot">"1987-12-09"</span>, <span class="ot">"119:10:0.100023"</span>, <span class="dv">1999</span>),</span>
<span id="cb141-18"><a href="#cb141-18" aria-hidden="true" tabindex="-1"></a> (<span class="ot">"2025-02-27 09:41:25.000678"</span>, <span class="ot">"2025-02-27 09:41:25.000678"</span>, <span class="ot">"2010-01-01"</span>, <span class="ot">"099:35:0.60003"</span>, <span class="dv">2005</span>);</span></code></pre></div>
<p>After you have added the corresponding schema
(<code>mrs_tests</code>) and view
(<code>table_date_and_time</code>) objects to the MRS
service (let’s say <code>my_service</code>), you can
start using the MRS Python SDK.</p>
<p><strong><em>Upstream Commands</em></strong></p>
<h5 data-number="8.2.1.1.1" id="create-2"><span
class="header-section-number">8.2.1.1.1</span>
Create</h5>
<p>Inserting a record into the
<code>table_date_and_time</code> table in the
<code>mrs_tests</code> sample database.</p>
<div class="sourceCode" id="cb142"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb142-1"><a href="#cb142-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> datetime</span>
<span id="cb142-2"><a href="#cb142-2" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService</span>
<span id="cb142-3"><a href="#cb142-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb142-4"><a href="#cb142-4" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb142-5"><a href="#cb142-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb142-6"><a href="#cb142-6" aria-hidden="true" tabindex="-1"></a>doc <span class="op">=</span> <span class="cf">await</span> my_service.mrs_tests.table_date_and_time.create(</span>
<span id="cb142-7"><a href="#cb142-7" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb142-8"><a href="#cb142-8" aria-hidden="true" tabindex="-1"></a> <span class="st">"dt"</span>: datetime.datetime.now(),</span>
<span id="cb142-9"><a href="#cb142-9" aria-hidden="true" tabindex="-1"></a> <span class="st">"d"</span>: datetime.date(<span class="dv">2020</span>, <span class="dv">10</span>, <span class="dv">20</span>),</span>
<span id="cb142-10"><a href="#cb142-10" aria-hidden="true" tabindex="-1"></a> <span class="st">"t"</span>: datetime.timedelta(days<span class="op">=</span><span class="dv">31</span>, microseconds<span class="op">=</span><span class="dv">202023</span>),</span>
<span id="cb142-11"><a href="#cb142-11" aria-hidden="true" tabindex="-1"></a> <span class="st">"y"</span>: <span class="dv">1976</span>,</span>
<span id="cb142-12"><a href="#cb142-12" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb142-13"><a href="#cb142-13" aria-hidden="true" tabindex="-1"></a>)</span></code></pre></div>
<blockquote>
<p>If you wanted field <code>d</code> to be
<code>NULL</code>, for instance, you would have to use
<code>None</code> instead of
<code>datetime.date(...)</code>.</p>
</blockquote>
<h5 data-number="8.2.1.1.2" id="update-2"><span
class="header-section-number">8.2.1.1.2</span>
Update</h5>
<p>Updating a record from the
<code>table_date_and_time</code> table in the
<code>mrs_tests</code> sample database.</p>
<div class="sourceCode" id="cb143"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb143-1"><a href="#cb143-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> datetime</span>
<span id="cb143-2"><a href="#cb143-2" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService</span>
<span id="cb143-3"><a href="#cb143-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb143-4"><a href="#cb143-4" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb143-5"><a href="#cb143-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb143-6"><a href="#cb143-6" aria-hidden="true" tabindex="-1"></a>doc <span class="op">=</span> <span class="cf">await</span> my_service.mrs_tests.table_date_and_time.update(</span>
<span id="cb143-7"><a href="#cb143-7" aria-hidden="true" tabindex="-1"></a> data<span class="op">=</span>{</span>
<span id="cb143-8"><a href="#cb143-8" aria-hidden="true" tabindex="-1"></a> <span class="st">"idx"</span>: <span class="dv">1</span>,</span>
<span id="cb143-9"><a href="#cb143-9" aria-hidden="true" tabindex="-1"></a> <span class="st">"t"</span>: datetime.timedelta(days<span class="op">=</span><span class="dv">4</span>, hours<span class="op">=</span><span class="dv">4</span>, minutes<span class="op">=</span><span class="dv">1</span>, seconds<span class="op">=</span><span class="dv">1</span>),</span>
<span id="cb143-10"><a href="#cb143-10" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb143-11"><a href="#cb143-11" aria-hidden="true" tabindex="-1"></a>)</span></code></pre></div>
<p><strong><em>Downstream Commands</em></strong></p>
<h5 data-number="8.2.1.1.3" id="find-1"><span
class="header-section-number">8.2.1.1.3</span> Find</h5>
<p>Finding a record from the
<code>table_date_and_time</code> table in the
<code>mrs_tests</code> sample database.</p>
<div class="sourceCode" id="cb144"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb144-1"><a href="#cb144-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> datetime</span>
<span id="cb144-2"><a href="#cb144-2" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService</span>
<span id="cb144-3"><a href="#cb144-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb144-4"><a href="#cb144-4" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb144-5"><a href="#cb144-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb144-6"><a href="#cb144-6" aria-hidden="true" tabindex="-1"></a>doc <span class="op">=</span> <span class="cf">await</span> my_service.mrs_tests.table_date_and_time.find_first(</span>
<span id="cb144-7"><a href="#cb144-7" aria-hidden="true" tabindex="-1"></a> where<span class="op">=</span>{</span>
<span id="cb144-8"><a href="#cb144-8" aria-hidden="true" tabindex="-1"></a> <span class="st">"AND"</span>: [</span>
<span id="cb144-9"><a href="#cb144-9" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb144-10"><a href="#cb144-10" aria-hidden="true" tabindex="-1"></a> <span class="st">"dt"</span>: {</span>
<span id="cb144-11"><a href="#cb144-11" aria-hidden="true" tabindex="-1"></a> <span class="st">"lt"</span>: datetime.datetime.fromisoformat(</span>
<span id="cb144-12"><a href="#cb144-12" aria-hidden="true" tabindex="-1"></a> <span class="st">"2023-07-30 15:59:01"</span></span>
<span id="cb144-13"><a href="#cb144-13" aria-hidden="true" tabindex="-1"></a> )</span>
<span id="cb144-14"><a href="#cb144-14" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb144-15"><a href="#cb144-15" aria-hidden="true" tabindex="-1"></a> },</span>
<span id="cb144-16"><a href="#cb144-16" aria-hidden="true" tabindex="-1"></a> {<span class="st">"d"</span>: {<span class="st">"gte"</span>: datetime.date.fromisoformat(<span class="st">"1987-12-09"</span>)}},</span>
<span id="cb144-17"><a href="#cb144-17" aria-hidden="true" tabindex="-1"></a> ]</span>
<span id="cb144-18"><a href="#cb144-18" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb144-19"><a href="#cb144-19" aria-hidden="true" tabindex="-1"></a>)</span></code></pre></div>
<h4 data-number="8.2.1.2" id="example---function"><span
class="header-section-number">8.2.1.2</span> Example -
Function</h4>
<p>Consider the following sample function:</p>
<div class="sourceCode" id="cb145"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb145-1"><a href="#cb145-1" aria-hidden="true" tabindex="-1"></a><span class="co">/*</span></span>
<span id="cb145-2"><a href="#cb145-2" aria-hidden="true" tabindex="-1"></a><span class="co">Sample functions using date and time data types.</span></span>
<span id="cb145-3"><a href="#cb145-3" aria-hidden="true" tabindex="-1"></a><span class="co">*/</span></span>
<span id="cb145-4"><a href="#cb145-4" aria-hidden="true" tabindex="-1"></a><span class="kw">DROP</span> <span class="kw">FUNCTION</span> <span class="cf">IF</span> <span class="kw">EXISTS</span> mrs_tests.func_date_and_time_ts;</span>
<span id="cb145-5"><a href="#cb145-5" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> <span class="kw">FUNCTION</span> mrs_tests.func_date_and_time_ts (ts <span class="dt">TIMESTAMP</span>(<span class="dv">4</span>))</span>
<span id="cb145-6"><a href="#cb145-6" aria-hidden="true" tabindex="-1"></a> RETURNS <span class="dt">TIMESTAMP</span>(<span class="dv">4</span>) DETERMINISTIC</span>
<span id="cb145-7"><a href="#cb145-7" aria-hidden="true" tabindex="-1"></a> <span class="kw">RETURN</span> TIMESTAMPADD(<span class="dt">MONTH</span>, <span class="dv">1</span>, ts);</span></code></pre></div>
<p>After you have added the corresponding schema
(<code>mrs_tests</code>) and function
(<code>func_date_and_time_ts</code>) objects to the MRS
service (let’s say <code>my_service</code>), you can
start using the MRS Python SDK.</p>
<p>Calling the <code>func_date_and_time_ts</code> in the
<code>mrs_tests</code> sample database:</p>
<div class="sourceCode" id="cb146"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb146-1"><a href="#cb146-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> datetime</span>
<span id="cb146-2"><a href="#cb146-2" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService</span>
<span id="cb146-3"><a href="#cb146-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb146-4"><a href="#cb146-4" aria-hidden="true" tabindex="-1"></a>my_service <span class="op">=</span> MyService()</span>
<span id="cb146-5"><a href="#cb146-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb146-6"><a href="#cb146-6" aria-hidden="true" tabindex="-1"></a><span class="co"># `ts` stands for timestamp</span></span>
<span id="cb146-7"><a href="#cb146-7" aria-hidden="true" tabindex="-1"></a>value <span class="op">=</span> <span class="cf">await</span> <span class="va">self</span>.my_service.mrs_tests.func_date_and_time_ts(ts<span class="op">=</span>datetime.datetime.now())</span></code></pre></div>
<h4 data-number="8.2.1.3" id="types-mismatch-2"><span
class="header-section-number">8.2.1.3</span> Types
Mismatch</h4>
<p>If an unexpected data type is specified on the
client-side for a certain field (column), the Python
environment via mypy should yield a typing error.</p>
<h2 data-number="8.3"
id="working-with-vector-data-types"><span
class="header-section-number">8.3</span> Working with
Vector Data Types</h2>
<p>MySQL supports the VECTOR data type for representing
a structure that can hold up to a specified number of
entries <code>N</code>, where each entry is a 4-byte
(single-precision) floating-point value.</p>
<p>Visit the <a
href="https://dev.mysql.com/doc/refman/9.0/en/vector.html">official
documentation</a> to know more about the MySQL VECTOR
type.</p>
<h3 data-number="8.3.1" id="python-sdk-2"><span
class="header-section-number">8.3.1</span> Python
SDK</h3>
<h4 data-number="8.3.1.1"
id="client-side-representation"><span
class="header-section-number">8.3.1.1</span> Client-Side
Representation</h4>
<p>MySQL Rest Service (MRS) Python SDK utilizes the
following client-side data type for representing,
operating on, or manipulating MySQL vector data:</p>
<table>
<caption>Client-Side Representation of Vector
Datatype</caption>
<colgroup>
<col style="width: 52%" />
<col style="width: 47%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: center;">MySQL data type</th>
<th style="text-align: center;">MRS Python SDK data
type</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: center;">VECTOR</td>
<td style="text-align: center;"><a
href="https://docs.python.org/3/tutorial/datastructures.html#more-on-lists"><code>list</code></a>
of <a
href="https://docs.python.org/3/library/functions.html#float"><code>floats</code></a></td>
</tr>
</tbody>
</table>
<p>The MRS Python SDK data type shall be used when
inserting or updating (upstream operations) a record
that contains a field matching a column of a
<em>vector</em> data type. Symmetrically, for downstream
operations such as finding records having
<em>vector</em> fields, such fields are specified with
MRS Python SDK data types according to the above
mapping.</p>
<p>When a vector column has a <code>NULL</code> value,
the Python SDK uses <code>None</code> on the client side
to represent it.</p>
<h4 data-number="8.3.1.2" id="out-of-bounds"><span
class="header-section-number">8.3.1.2</span> Out of
Bounds</h4>
<p>As specified for the <a
href="https://dev.mysql.com/doc/refman/9.0/en/vector.html">MySQL
Vector data</a> type, each entry must be a 4-byte
(single-precision) floating-point value. Python lists
can store a wider set of floating point values, in this
regard, nothing stops the application from specifying
entries that are out of bounds, such as a
double-precision values.</p>
<p>This event may happen unintentionally, or not,
however, in any case, the client does not carry on a
verification, in other words, entries are sent to the
server as they are, and the client lets the server
handle it (an error should be expected).</p>
<h4 data-number="8.3.1.3" id="examples"><span
class="header-section-number">8.3.1.3</span>
Examples</h4>
<p>In the following sections, fictional but relevant
examples are presented to showcase the usage of the
MySQL Vector data type via the MRS Python SDK.</p>
<blockquote>
<p>The examples assume a sample database named
<code>mrs_tests</code> exists.</p>
</blockquote>
<p>Consider the following sample table:</p>
<div class="sourceCode" id="cb147"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb147-1"><a href="#cb147-1" aria-hidden="true" tabindex="-1"></a><span class="co">/*</span></span>
<span id="cb147-2"><a href="#cb147-2" aria-hidden="true" tabindex="-1"></a><span class="co">Sample table including a column for vector type.</span></span>
<span id="cb147-3"><a href="#cb147-3" aria-hidden="true" tabindex="-1"></a><span class="co">*/</span></span>
<span id="cb147-4"><a href="#cb147-4" aria-hidden="true" tabindex="-1"></a><span class="kw">DROP</span> <span class="kw">TABLE</span> <span class="cf">IF</span> <span class="kw">EXISTS</span> mrs_tests.table_vector;</span>
<span id="cb147-5"><a href="#cb147-5" aria-hidden="true" tabindex="-1"></a><span class="kw">CREATE</span> <span class="kw">TABLE</span> mrs_tests.table_vector (</span>
<span id="cb147-6"><a href="#cb147-6" aria-hidden="true" tabindex="-1"></a> idx <span class="dt">SMALLINT</span> UNSIGNED <span class="kw">NOT</span> <span class="kw">NULL</span> AUTO_INCREMENT,</span>
<span id="cb147-7"><a href="#cb147-7" aria-hidden="true" tabindex="-1"></a> embedding VECTOR,</span>
<span id="cb147-8"><a href="#cb147-8" aria-hidden="true" tabindex="-1"></a> <span class="kw">PRIMARY</span> <span class="kw">KEY</span> (idx)</span>
<span id="cb147-9"><a href="#cb147-9" aria-hidden="true" tabindex="-1"></a>);</span></code></pre></div>
<p>After you have added the corresponding schema
(<code>mrs_tests</code>) and view
(<code>table_vector</code>) objects to the MRS service
(let’s say <code>my_service</code>), you can start using
the MRS Python SDK.</p>
<h5 data-number="8.3.1.3.1" id="create-3"><span
class="header-section-number">8.3.1.3.1</span>
Create</h5>
<p>Inserting a record into the <code>table_vector</code>
table in the <code>mrs_tests</code> sample database.</p>
<div class="sourceCode" id="cb148"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb148-1"><a href="#cb148-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService</span>
<span id="cb148-2"><a href="#cb148-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb148-3"><a href="#cb148-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb148-4"><a href="#cb148-4" aria-hidden="true" tabindex="-1"></a><span class="cf">async</span> <span class="kw">def</span> main():</span>
<span id="cb148-5"><a href="#cb148-5" aria-hidden="true" tabindex="-1"></a> my_service <span class="op">=</span> MyService()</span>
<span id="cb148-6"><a href="#cb148-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb148-7"><a href="#cb148-7" aria-hidden="true" tabindex="-1"></a> data <span class="op">=</span> [</span>
<span id="cb148-8"><a href="#cb148-8" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb148-9"><a href="#cb148-9" aria-hidden="true" tabindex="-1"></a> <span class="st">"embedding"</span>: [</span>
<span id="cb148-10"><a href="#cb148-10" aria-hidden="true" tabindex="-1"></a> <span class="fl">3.1415159702301025</span>,</span>
<span id="cb148-11"><a href="#cb148-11" aria-hidden="true" tabindex="-1"></a> <span class="fl">2.719064950942993</span>,</span>
<span id="cb148-12"><a href="#cb148-12" aria-hidden="true" tabindex="-1"></a> <span class="op">-</span><span class="fl">87.53939819335938</span>,</span>
<span id="cb148-13"><a href="#cb148-13" aria-hidden="true" tabindex="-1"></a> <span class="fl">44.11e+10</span>,</span>
<span id="cb148-14"><a href="#cb148-14" aria-hidden="true" tabindex="-1"></a> ]</span>
<span id="cb148-15"><a href="#cb148-15" aria-hidden="true" tabindex="-1"></a> },</span>
<span id="cb148-16"><a href="#cb148-16" aria-hidden="true" tabindex="-1"></a> {<span class="st">"embedding"</span>: [<span class="fl">9.147116</span>, <span class="op">-</span><span class="fl">76.769115</span>, <span class="op">-</span><span class="fl">5.354053</span>]},</span>
<span id="cb148-17"><a href="#cb148-17" aria-hidden="true" tabindex="-1"></a> {<span class="st">"embedding"</span>: <span class="va">None</span>},</span>
<span id="cb148-18"><a href="#cb148-18" aria-hidden="true" tabindex="-1"></a> ]</span>
<span id="cb148-19"><a href="#cb148-19" aria-hidden="true" tabindex="-1"></a> <span class="cf">async</span> <span class="cf">for</span> doc <span class="kw">in</span> my_service.mrs_tests.table_vector.create_many(data):</span>
<span id="cb148-20"><a href="#cb148-20" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(doc.embedding)</span>
<span id="cb148-21"><a href="#cb148-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb148-22"><a href="#cb148-22" aria-hidden="true" tabindex="-1"></a> <span class="co"># ------STDOUT-------</span></span>
<span id="cb148-23"><a href="#cb148-23" aria-hidden="true" tabindex="-1"></a> <span class="co"># [3.1415159702301025, 2.719064950942993, -87.53939819335938, 44.11e+10]</span></span>
<span id="cb148-24"><a href="#cb148-24" aria-hidden="true" tabindex="-1"></a> <span class="co"># [9.147116, -76.769115, -5.354053]</span></span>
<span id="cb148-25"><a href="#cb148-25" aria-hidden="true" tabindex="-1"></a> <span class="co"># None</span></span>
<span id="cb148-26"><a href="#cb148-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb148-27"><a href="#cb148-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb148-28"><a href="#cb148-28" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">"__main__"</span>:</span>
<span id="cb148-29"><a href="#cb148-29" aria-hidden="true" tabindex="-1"></a> asyncio.run(main())</span></code></pre></div>
<h5 data-number="8.3.1.3.2" id="update-3"><span
class="header-section-number">8.3.1.3.2</span>
Update</h5>
<p>Updating a record from the <code>table_vector</code>
table in the <code>mrs_tests</code> sample database.</p>
<div class="sourceCode" id="cb149"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb149-1"><a href="#cb149-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService</span>
<span id="cb149-2"><a href="#cb149-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb149-3"><a href="#cb149-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb149-4"><a href="#cb149-4" aria-hidden="true" tabindex="-1"></a><span class="cf">async</span> <span class="kw">def</span> main():</span>
<span id="cb149-5"><a href="#cb149-5" aria-hidden="true" tabindex="-1"></a> my_service <span class="op">=</span> MyService()</span>
<span id="cb149-6"><a href="#cb149-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb149-7"><a href="#cb149-7" aria-hidden="true" tabindex="-1"></a> doc <span class="op">=</span> <span class="cf">await</span> my_service.mrs_tests.table_vector.update(</span>
<span id="cb149-8"><a href="#cb149-8" aria-hidden="true" tabindex="-1"></a> data<span class="op">=</span>{</span>
<span id="cb149-9"><a href="#cb149-9" aria-hidden="true" tabindex="-1"></a> <span class="st">"idx"</span>: <span class="dv">1</span>,</span>
<span id="cb149-10"><a href="#cb149-10" aria-hidden="true" tabindex="-1"></a> <span class="st">"embedding"</span>: [<span class="op">-</span><span class="fl">3.141516</span>, <span class="fl">5.769005</span>, <span class="op">-</span><span class="fl">0.334013</span>, <span class="fl">33.333</span>, <span class="op">-</span><span class="fl">12.76</span>],</span>
<span id="cb149-11"><a href="#cb149-11" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb149-12"><a href="#cb149-12" aria-hidden="true" tabindex="-1"></a> )</span>
<span id="cb149-13"><a href="#cb149-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb149-14"><a href="#cb149-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb149-15"><a href="#cb149-15" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">"__main__"</span>:</span>
<span id="cb149-16"><a href="#cb149-16" aria-hidden="true" tabindex="-1"></a> asyncio.run(main())</span></code></pre></div>
<h5 data-number="8.3.1.3.3" id="find-2"><span
class="header-section-number">8.3.1.3.3</span> Find</h5>
<p>Finding a record from the <code>table_vector</code>
table in the <code>mrs_tests</code> sample database.</p>
<div class="sourceCode" id="cb150"><pre
class="sourceCode py"><code class="sourceCode python"><span id="cb150-1"><a href="#cb150-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> sdk.python <span class="im">import</span> MyService</span>
<span id="cb150-2"><a href="#cb150-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb150-3"><a href="#cb150-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb150-4"><a href="#cb150-4" aria-hidden="true" tabindex="-1"></a><span class="cf">async</span> <span class="kw">def</span> main():</span>
<span id="cb150-5"><a href="#cb150-5" aria-hidden="true" tabindex="-1"></a> my_service <span class="op">=</span> MyService()</span>
<span id="cb150-6"><a href="#cb150-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb150-7"><a href="#cb150-7" aria-hidden="true" tabindex="-1"></a> doc_id <span class="op">=</span> <span class="dv">2</span></span>
<span id="cb150-8"><a href="#cb150-8" aria-hidden="true" tabindex="-1"></a> <span class="cf">try</span>:</span>
<span id="cb150-9"><a href="#cb150-9" aria-hidden="true" tabindex="-1"></a> doc <span class="op">=</span> <span class="cf">await</span> my_service.mrs_tests.table_vector.find_first_or_throw(</span>
<span id="cb150-10"><a href="#cb150-10" aria-hidden="true" tabindex="-1"></a> where<span class="op">=</span>{<span class="st">"idx"</span>: doc_id}</span>
<span id="cb150-11"><a href="#cb150-11" aria-hidden="true" tabindex="-1"></a> )</span>
<span id="cb150-12"><a href="#cb150-12" aria-hidden="true" tabindex="-1"></a> <span class="cf">except</span> MrsDocumentNotFoundError:</span>
<span id="cb150-13"><a href="#cb150-13" aria-hidden="true" tabindex="-1"></a> <span class="cf">raise</span> MrsDocumentNotFoundError(msg<span class="op">=</span><span class="ss">f"No document exists matching idx=</span><span class="sc">{</span>doc_id<span class="sc">}</span><span class="ss">"</span>)</span>
<span id="cb150-14"><a href="#cb150-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb150-15"><a href="#cb150-15" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(doc.embedding)</span>
<span id="cb150-16"><a href="#cb150-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb150-17"><a href="#cb150-17" aria-hidden="true" tabindex="-1"></a> <span class="co"># ------STDOUT-------</span></span>
<span id="cb150-18"><a href="#cb150-18" aria-hidden="true" tabindex="-1"></a> <span class="co"># [9.147116, -76.769115, -5.354053]</span></span>
<span id="cb150-19"><a href="#cb150-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb150-20"><a href="#cb150-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb150-21"><a href="#cb150-21" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">"__main__"</span>:</span>
<span id="cb150-22"><a href="#cb150-22" aria-hidden="true" tabindex="-1"></a> asyncio.run(main())</span></code></pre></div>
<h2 data-number="8.4"
id="working-with-lossy-numbers"><span
class="header-section-number">8.4</span> Working with
lossy numbers</h2>
<p>TypeScript <code>number</code>s use a double
precision 64-bit binary format as defined by the IEEE
754 standard. This means that it is not capable, without
losing precision, of representing integers above 2^53-1
(which are valid in the 64-bit integer range) and also
fixed-point arbitrary precision decimals. This is
particularly important because the <code>BIGINT</code>
data type in MySQL can represent numbers up to 2^64-1
and the <code>DECIMAL</code>/<code>NUMERIC</code> data
type can represent fixed point numbers.</p>
<p>64-bit integers can still be represented using a
<code>BigInt</code> type without losing precision, so
the TypeScript SDK converts the raw JSON number into a
corresponding instance of this type, if the value, in
fact, looses precision. Otherwise it converts it to a
regular <code>number</code> instance.</p>
<p>For example, consider a table as follows:</p>
<div class="sourceCode" id="cb151"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb151-1"><a href="#cb151-1" aria-hidden="true" tabindex="-1"></a> <span class="kw">CREATE</span> <span class="kw">TABLE</span> <span class="cf">IF</span> <span class="kw">NOT</span> <span class="kw">EXISTS</span> my_db.my_table (small BIGINT UNSIGNED, large BIGINT UNSIGNED);</span>
<span id="cb151-2"><a href="#cb151-2" aria-hidden="true" tabindex="-1"></a> <span class="kw">INSERT</span> <span class="kw">INTO</span> my_db.my_table (small, large) <span class="kw">VALUES</span> (<span class="dv">1234</span>, <span class="dv">18446744073709551615</span>);</span></code></pre></div>
<p>with a corresponding REST View created as
follows:</p>
<div class="sourceCode" id="cb152"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb152-1"><a href="#cb152-1" aria-hidden="true" tabindex="-1"></a> <span class="kw">CREATE</span> REST <span class="kw">VIEW</span> <span class="op">/</span>myTable</span>
<span id="cb152-2"><a href="#cb152-2" aria-hidden="true" tabindex="-1"></a> <span class="kw">ON</span> SERVICE <span class="op">/</span>myService <span class="kw">SCHEMA</span> <span class="op">/</span>myDb</span>
<span id="cb152-3"><a href="#cb152-3" aria-hidden="true" tabindex="-1"></a> <span class="kw">AS</span> `my_db`.`my_table` {</span>
<span id="cb152-4"><a href="#cb152-4" aria-hidden="true" tabindex="-1"></a> small: small,</span>
<span id="cb152-5"><a href="#cb152-5" aria-hidden="true" tabindex="-1"></a> large: large,</span>
<span id="cb152-6"><a href="#cb152-6" aria-hidden="true" tabindex="-1"></a> };</span></code></pre></div>
<p>The document can be retrieved, using the TypeScript
SDK, as follows:</p>
<div class="sourceCode" id="cb153"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb153-1"><a href="#cb153-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> doc <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="at">myDb</span><span class="op">.</span><span class="at">myTable</span><span class="op">.</span><span class="fu">findFirst</span>({ where<span class="op">:</span> { large<span class="op">:</span> <span class="dv">18446744073709551615</span>n } })</span>
<span id="cb153-2"><a href="#cb153-2" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(doc<span class="op">.</span><span class="at">small</span>) <span class="co">// 123</span></span>
<span id="cb153-3"><a href="#cb153-3" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="kw">typeof</span> doc<span class="op">.</span><span class="at">small</span>) <span class="co">// number</span></span>
<span id="cb153-4"><a href="#cb153-4" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(doc<span class="op">.</span><span class="at">large</span>) <span class="co">// 18446744073709551615n</span></span>
<span id="cb153-5"><a href="#cb153-5" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="kw">typeof</span> doc<span class="op">.</span><span class="at">large</span>) <span class="co">// bigint</span></span></code></pre></div>
<p>However, there is no similar construct for
fixed-point decimals. In this case, the MRS TypeScript
SDK handles these values as <code>string</code>s, if
they, in fact, lose precision. For example, consider a
table as follows:</p>
<div class="sourceCode" id="cb154"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb154-1"><a href="#cb154-1" aria-hidden="true" tabindex="-1"></a> <span class="kw">CREATE</span> <span class="kw">TABLE</span> <span class="cf">IF</span> <span class="kw">NOT</span> <span class="kw">EXISTS</span> my_db.my_table (wide <span class="dt">DECIMAL</span>(<span class="dv">18</span>, <span class="dv">17</span>) narrow <span class="dt">DECIMAL</span>(<span class="dv">18</span>, <span class="dv">17</span>));</span>
<span id="cb154-2"><a href="#cb154-2" aria-hidden="true" tabindex="-1"></a> <span class="kw">INSERT</span> <span class="kw">INTO</span> my_db.my_table (wide, narrow) <span class="kw">VALUES</span> (<span class="fl">1.234</span>, <span class="fl">1.23456789012345678</span>);</span></code></pre></div>
<p>with a corresponding REST View created as
follows:</p>
<div class="sourceCode" id="cb155"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb155-1"><a href="#cb155-1" aria-hidden="true" tabindex="-1"></a> <span class="kw">CREATE</span> REST <span class="kw">VIEW</span> <span class="op">/</span>myTable</span>
<span id="cb155-2"><a href="#cb155-2" aria-hidden="true" tabindex="-1"></a> <span class="kw">ON</span> SERVICE <span class="op">/</span>myService <span class="kw">SCHEMA</span> <span class="op">/</span>myDb</span>
<span id="cb155-3"><a href="#cb155-3" aria-hidden="true" tabindex="-1"></a> <span class="kw">AS</span> `my_db`.`my_table` {</span>
<span id="cb155-4"><a href="#cb155-4" aria-hidden="true" tabindex="-1"></a> wide: wide,</span>
<span id="cb155-5"><a href="#cb155-5" aria-hidden="true" tabindex="-1"></a> narrow: narrow,</span>
<span id="cb155-6"><a href="#cb155-6" aria-hidden="true" tabindex="-1"></a> };</span></code></pre></div>
<p>The document can be retrieved, using the TypeScript
SDK, as follows:</p>
<div class="sourceCode" id="cb156"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb156-1"><a href="#cb156-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> doc <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="at">myDb</span><span class="op">.</span><span class="at">myTable</span><span class="op">.</span><span class="fu">findFirst</span>({ where<span class="op">:</span> { narrow<span class="op">:</span> <span class="st">"1.23456789012345678"</span> } })</span>
<span id="cb156-2"><a href="#cb156-2" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(doc<span class="op">.</span><span class="at">wide</span>) <span class="co">// 123</span></span>
<span id="cb156-3"><a href="#cb156-3" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="kw">typeof</span> doc<span class="op">.</span><span class="at">wide</span>) <span class="co">// number</span></span>
<span id="cb156-4"><a href="#cb156-4" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(doc<span class="op">.</span><span class="at">narrow</span>) <span class="co">// 1.23456789012345678</span></span>
<span id="cb156-5"><a href="#cb156-5" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="kw">typeof</span> doc<span class="op">.</span><span class="at">narrow</span>) <span class="co">// string</span></span></code></pre></div>
<!-- Copyright (c) 2022, 2026, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2.0,
as published by the Free Software Foundation.
This program is designed to work with certain software (including
but not limited to OpenSSL) that is licensed under separate terms, as
designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have either included with
the program or referenced in the documentation.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
the GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -->
<h1 data-number="9" id="application-metadata"><span
class="header-section-number">9</span> Application
Metadata</h1>
<p>Application-specific metadata can be attached to any
MRS Resource (REST Service, Schema and/or Object).</p>
<h2 data-number="9.1" id="rest-services"><span
class="header-section-number">9.1</span> REST
Services</h2>
<p>Consider a REST Service, with custom metadata,
created as follows:</p>
<div class="sourceCode" id="cb157"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb157-1"><a href="#cb157-1" aria-hidden="true" tabindex="-1"></a> <span class="kw">CREATE</span> <span class="kw">OR</span> <span class="kw">REPLACE</span> REST SERVICE <span class="op">/</span>myService</span>
<span id="cb157-2"><a href="#cb157-2" aria-hidden="true" tabindex="-1"></a> METADATA {</span>
<span id="cb157-3"><a href="#cb157-3" aria-hidden="true" tabindex="-1"></a> <span class="ot">"type"</span>: <span class="ot">"service"</span></span>
<span id="cb157-4"><a href="#cb157-4" aria-hidden="true" tabindex="-1"></a> };</span></code></pre></div>
<p>After generating the TypeScript SDK for this service,
the custom metadata can be obtained as follows:</p>
<div class="sourceCode" id="cb158"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb158-1"><a href="#cb158-1" aria-hidden="true" tabindex="-1"></a> <span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">"/path/to/sdk/myService"</span></span>
<span id="cb158-2"><a href="#cb158-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb158-3"><a href="#cb158-3" aria-hidden="true" tabindex="-1"></a> <span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()</span>
<span id="cb158-4"><a href="#cb158-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb158-5"><a href="#cb158-5" aria-hidden="true" tabindex="-1"></a> <span class="kw">const</span> metadata <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="fu">getMetadata</span>()</span>
<span id="cb158-6"><a href="#cb158-6" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(metadata) <span class="co">// { type: "service" }</span></span></code></pre></div>
<p>If the REST Service does not contain custom
metadata:</p>
<div class="sourceCode" id="cb159"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb159-1"><a href="#cb159-1" aria-hidden="true" tabindex="-1"></a> <span class="kw">CREATE</span> <span class="kw">OR</span> <span class="kw">REPLACE</span> REST SERVICE <span class="op">/</span>myService</span></code></pre></div>
<p>The command returns an empty object:</p>
<div class="sourceCode" id="cb160"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb160-1"><a href="#cb160-1" aria-hidden="true" tabindex="-1"></a> <span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">"/path/to/sdk/myService"</span></span>
<span id="cb160-2"><a href="#cb160-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb160-3"><a href="#cb160-3" aria-hidden="true" tabindex="-1"></a> <span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()</span>
<span id="cb160-4"><a href="#cb160-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb160-5"><a href="#cb160-5" aria-hidden="true" tabindex="-1"></a> <span class="kw">const</span> metadata <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="fu">getMetadata</span>()</span>
<span id="cb160-6"><a href="#cb160-6" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(metadata) <span class="co">// {}</span></span></code></pre></div>
<h2 data-number="9.2" id="rest-schemas"><span
class="header-section-number">9.2</span> REST
Schemas</h2>
<p>Consider a MySQL database created as follows:</p>
<div class="sourceCode" id="cb161"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb161-1"><a href="#cb161-1" aria-hidden="true" tabindex="-1"></a> <span class="kw">CREATE</span> <span class="kw">DATABASE</span> <span class="cf">IF</span> <span class="kw">NOT</span> <span class="kw">EXISTS</span> my_db;</span></code></pre></div>
<p>and a corresponding REST Schema, with custom
metadata, created as follows:</p>
<div class="sourceCode" id="cb162"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb162-1"><a href="#cb162-1" aria-hidden="true" tabindex="-1"></a> <span class="kw">CREATE</span> <span class="kw">OR</span> <span class="kw">REPLACE</span> REST <span class="kw">SCHEMA</span> <span class="op">/</span>myDb <span class="kw">ON</span> SERVICE <span class="op">/</span>myService</span>
<span id="cb162-2"><a href="#cb162-2" aria-hidden="true" tabindex="-1"></a> <span class="kw">FROM</span> `my_db`</span>
<span id="cb162-3"><a href="#cb162-3" aria-hidden="true" tabindex="-1"></a> METADATA {</span>
<span id="cb162-4"><a href="#cb162-4" aria-hidden="true" tabindex="-1"></a> <span class="ot">"type"</span>: <span class="ot">"schema"</span></span>
<span id="cb162-5"><a href="#cb162-5" aria-hidden="true" tabindex="-1"></a> };</span></code></pre></div>
<p>The custom metadata can be obtained as follows:</p>
<div class="sourceCode" id="cb163"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb163-1"><a href="#cb163-1" aria-hidden="true" tabindex="-1"></a> <span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">"/path/to/sdk/myService"</span></span>
<span id="cb163-2"><a href="#cb163-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb163-3"><a href="#cb163-3" aria-hidden="true" tabindex="-1"></a> <span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()</span>
<span id="cb163-4"><a href="#cb163-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb163-5"><a href="#cb163-5" aria-hidden="true" tabindex="-1"></a> <span class="kw">const</span> metadata <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="at">myDb</span><span class="op">.</span><span class="fu">getMetadata</span>()</span>
<span id="cb163-6"><a href="#cb163-6" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(metadata) <span class="co">// { type: "schema" }</span></span></code></pre></div>
<p>Just like for a REST Service, if a REST Schema does
not specify custom metadata:</p>
<div class="sourceCode" id="cb164"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb164-1"><a href="#cb164-1" aria-hidden="true" tabindex="-1"></a> <span class="kw">CREATE</span> <span class="kw">OR</span> <span class="kw">REPLACE</span> REST <span class="kw">SCHEMA</span> <span class="op">/</span>myDb <span class="kw">ON</span> SERVICE <span class="op">/</span>myService</span>
<span id="cb164-2"><a href="#cb164-2" aria-hidden="true" tabindex="-1"></a> <span class="kw">FROM</span> `my_db`</span></code></pre></div>
<p>The command returns an empty object:</p>
<div class="sourceCode" id="cb165"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb165-1"><a href="#cb165-1" aria-hidden="true" tabindex="-1"></a> <span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">"/path/to/sdk/myService"</span></span>
<span id="cb165-2"><a href="#cb165-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb165-3"><a href="#cb165-3" aria-hidden="true" tabindex="-1"></a> <span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()</span>
<span id="cb165-4"><a href="#cb165-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb165-5"><a href="#cb165-5" aria-hidden="true" tabindex="-1"></a> <span class="kw">const</span> metadata <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="at">myDb</span><span class="op">.</span><span class="fu">getMetadata</span>()</span>
<span id="cb165-6"><a href="#cb165-6" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(metadata) <span class="co">// {}</span></span></code></pre></div>
<p>If the REST Schema requires authentication:</p>
<div class="sourceCode" id="cb166"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb166-1"><a href="#cb166-1" aria-hidden="true" tabindex="-1"></a> <span class="kw">CREATE</span> <span class="kw">OR</span> <span class="kw">REPLACE</span> REST <span class="kw">SCHEMA</span> <span class="op">/</span>myDb <span class="kw">ON</span> SERVICE <span class="op">/</span>myService</span>
<span id="cb166-2"><a href="#cb166-2" aria-hidden="true" tabindex="-1"></a> <span class="kw">FROM</span> `my_db`</span>
<span id="cb166-3"><a href="#cb166-3" aria-hidden="true" tabindex="-1"></a> AUTHENTICATION REQUIRED</span>
<span id="cb166-4"><a href="#cb166-4" aria-hidden="true" tabindex="-1"></a> METADATA {</span>
<span id="cb166-5"><a href="#cb166-5" aria-hidden="true" tabindex="-1"></a> <span class="ot">"type"</span>: <span class="ot">"schema"</span></span>
<span id="cb166-6"><a href="#cb166-6" aria-hidden="true" tabindex="-1"></a> };</span>
<span id="cb166-7"><a href="#cb166-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb166-8"><a href="#cb166-8" aria-hidden="true" tabindex="-1"></a> <span class="kw">CREATE</span> <span class="fu">USER</span> foo <span class="kw">IDENTIFIED</span> <span class="kw">BY</span> <span class="st">'bar'</span>;</span>
<span id="cb166-9"><a href="#cb166-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb166-10"><a href="#cb166-10" aria-hidden="true" tabindex="-1"></a> <span class="kw">ALTER</span> REST SERVICE <span class="op">/</span>myService <span class="kw">ADD</span> AUTH APP <span class="ot">"MySQL"</span>;</span></code></pre></div>
<p>The command only succeeds if the client authenticates
beforehand:</p>
<div class="sourceCode" id="cb167"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb167-1"><a href="#cb167-1" aria-hidden="true" tabindex="-1"></a> <span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">"/path/to/sdk/myService"</span></span>
<span id="cb167-2"><a href="#cb167-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb167-3"><a href="#cb167-3" aria-hidden="true" tabindex="-1"></a> <span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()</span>
<span id="cb167-4"><a href="#cb167-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb167-5"><a href="#cb167-5" aria-hidden="true" tabindex="-1"></a> <span class="cf">await</span> myService<span class="op">.</span><span class="fu">authenticate</span>({ username<span class="op">:</span> <span class="st">"foo"</span><span class="op">,</span> password<span class="op">:</span> <span class="st">"bar"</span><span class="op">,</span> app<span class="op">:</span> <span class="st">"MySQL"</span> })</span>
<span id="cb167-6"><a href="#cb167-6" aria-hidden="true" tabindex="-1"></a> <span class="kw">const</span> metadata <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="at">myDb</span><span class="op">.</span><span class="fu">getMetadata</span>()</span></code></pre></div>
<p>Otherwise, the command yields an authentication
error:</p>
<div class="sourceCode" id="cb168"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb168-1"><a href="#cb168-1" aria-hidden="true" tabindex="-1"></a> <span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">"/path/to/sdk/myService"</span></span>
<span id="cb168-2"><a href="#cb168-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb168-3"><a href="#cb168-3" aria-hidden="true" tabindex="-1"></a> <span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()</span>
<span id="cb168-4"><a href="#cb168-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb168-5"><a href="#cb168-5" aria-hidden="true" tabindex="-1"></a> <span class="cf">try</span> {</span>
<span id="cb168-6"><a href="#cb168-6" aria-hidden="true" tabindex="-1"></a> <span class="kw">const</span> metadata <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="at">myDb</span><span class="op">.</span><span class="fu">getMetadata</span>()</span>
<span id="cb168-7"><a href="#cb168-7" aria-hidden="true" tabindex="-1"></a> } <span class="cf">catch</span> (err) {</span>
<span id="cb168-8"><a href="#cb168-8" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(err) <span class="co">// Not authenticated. Please authenticate first before accessing the path /myService/myDb/_metadata.</span></span>
<span id="cb168-9"><a href="#cb168-9" aria-hidden="true" tabindex="-1"></a> }</span></code></pre></div>
<h2 data-number="9.3" id="rest-objects"><span
class="header-section-number">9.3</span> REST
Objects</h2>
<p>Custom metadata can be specified for any kind of REST
object, be it a <code>VIEW</code>,
<code>FUNCTION</code>, <code>PROCEDURE</code> or
<code>SCRIPT</code>.</p>
<p>As an example, consider any MySQL Table, such as one
created as follows:</p>
<div class="sourceCode" id="cb169"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb169-1"><a href="#cb169-1" aria-hidden="true" tabindex="-1"></a> <span class="kw">CREATE</span> <span class="kw">TABLE</span> <span class="cf">IF</span> <span class="kw">NOT</span> <span class="kw">EXISTS</span> my_table (<span class="kw">id</span> <span class="dt">INT</span> AUTO_INCREMENT <span class="kw">NOT</span> <span class="kw">NULL</span>, name <span class="dt">VARCHAR</span>(<span class="dv">3</span>), <span class="kw">PRIMARY</span> <span class="kw">KEY</span> (<span class="kw">id</span>));</span></code></pre></div>
<p>and a corresponding REST View, with custom metadata,
created as follows:</p>
<div class="sourceCode" id="cb170"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb170-1"><a href="#cb170-1" aria-hidden="true" tabindex="-1"></a> <span class="kw">CREATE</span> <span class="kw">OR</span> <span class="kw">REPLACE</span> REST <span class="kw">VIEW</span> <span class="op">/</span>myTable <span class="kw">ON</span> SERVICE <span class="op">/</span>myService <span class="kw">SCHEMA</span> <span class="op">/</span>myDb</span>
<span id="cb170-2"><a href="#cb170-2" aria-hidden="true" tabindex="-1"></a> <span class="kw">AS</span> `my_db`.`my_table` <span class="kw">CLASS</span> MyServiceMyDbMyTable {</span>
<span id="cb170-3"><a href="#cb170-3" aria-hidden="true" tabindex="-1"></a> <span class="kw">id</span>: <span class="kw">id</span> @SORTABLE @KEY,</span>
<span id="cb170-4"><a href="#cb170-4" aria-hidden="true" tabindex="-1"></a> name: name</span>
<span id="cb170-5"><a href="#cb170-5" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb170-6"><a href="#cb170-6" aria-hidden="true" tabindex="-1"></a> METADATA {</span>
<span id="cb170-7"><a href="#cb170-7" aria-hidden="true" tabindex="-1"></a> <span class="ot">"type"</span>: <span class="ot">"table"</span></span>
<span id="cb170-8"><a href="#cb170-8" aria-hidden="true" tabindex="-1"></a> };</span></code></pre></div>
<p>The custom metadata can be obtained as follows:</p>
<div class="sourceCode" id="cb171"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb171-1"><a href="#cb171-1" aria-hidden="true" tabindex="-1"></a> <span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">"/path/to/sdk/myService"</span></span>
<span id="cb171-2"><a href="#cb171-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb171-3"><a href="#cb171-3" aria-hidden="true" tabindex="-1"></a> <span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()</span>
<span id="cb171-4"><a href="#cb171-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb171-5"><a href="#cb171-5" aria-hidden="true" tabindex="-1"></a> <span class="kw">const</span> metadata <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="at">myDb</span><span class="op">.</span><span class="at">myTable</span><span class="op">.</span><span class="fu">getMetadata</span>()</span>
<span id="cb171-6"><a href="#cb171-6" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(metadata) <span class="co">// { type: "table" }</span></span></code></pre></div>
<p>Just like for a REST Service and Schema, if the REST
View does not specify custom metadata:</p>
<div class="sourceCode" id="cb172"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb172-1"><a href="#cb172-1" aria-hidden="true" tabindex="-1"></a> <span class="kw">CREATE</span> <span class="kw">OR</span> <span class="kw">REPLACE</span> REST <span class="kw">VIEW</span> <span class="op">/</span>myTable <span class="kw">ON</span> SERVICE <span class="op">/</span>myService <span class="kw">SCHEMA</span> <span class="op">/</span>myDb</span>
<span id="cb172-2"><a href="#cb172-2" aria-hidden="true" tabindex="-1"></a> <span class="kw">AS</span> `my_db`.`my_table` <span class="kw">CLASS</span> MyServiceMyDbMyTable {</span>
<span id="cb172-3"><a href="#cb172-3" aria-hidden="true" tabindex="-1"></a> <span class="kw">id</span>: <span class="kw">id</span> @SORTABLE @KEY,</span>
<span id="cb172-4"><a href="#cb172-4" aria-hidden="true" tabindex="-1"></a> name: name</span>
<span id="cb172-5"><a href="#cb172-5" aria-hidden="true" tabindex="-1"></a> };</span></code></pre></div>
<p>The command returns an empty object:</p>
<div class="sourceCode" id="cb173"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb173-1"><a href="#cb173-1" aria-hidden="true" tabindex="-1"></a> <span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">"/path/to/sdk/myService"</span></span>
<span id="cb173-2"><a href="#cb173-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb173-3"><a href="#cb173-3" aria-hidden="true" tabindex="-1"></a> <span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()</span>
<span id="cb173-4"><a href="#cb173-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb173-5"><a href="#cb173-5" aria-hidden="true" tabindex="-1"></a> <span class="kw">const</span> metadata <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="at">myDb</span><span class="op">.</span><span class="at">myTable</span><span class="op">.</span><span class="fu">getMetadata</span>()</span>
<span id="cb173-6"><a href="#cb173-6" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(metadata) <span class="co">// {}</span></span></code></pre></div>
<p>If the REST View requires authentication:</p>
<div class="sourceCode" id="cb174"><pre
class="sourceCode sql"><code class="sourceCode sql"><span id="cb174-1"><a href="#cb174-1" aria-hidden="true" tabindex="-1"></a> <span class="kw">CREATE</span> <span class="kw">OR</span> <span class="kw">REPLACE</span> REST <span class="kw">VIEW</span> <span class="op">/</span>myTable <span class="kw">ON</span> SERVICE <span class="op">/</span>myService <span class="kw">SCHEMA</span> <span class="op">/</span>myDb</span>
<span id="cb174-2"><a href="#cb174-2" aria-hidden="true" tabindex="-1"></a> <span class="kw">AS</span> `my_db`.`my_table` <span class="kw">CLASS</span> MyServiceMyDbMyTable {</span>
<span id="cb174-3"><a href="#cb174-3" aria-hidden="true" tabindex="-1"></a> <span class="kw">id</span>: <span class="kw">id</span> @SORTABLE @KEY,</span>
<span id="cb174-4"><a href="#cb174-4" aria-hidden="true" tabindex="-1"></a> name: name</span>
<span id="cb174-5"><a href="#cb174-5" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb174-6"><a href="#cb174-6" aria-hidden="true" tabindex="-1"></a> AUTHENTICATION REQUIRED</span>
<span id="cb174-7"><a href="#cb174-7" aria-hidden="true" tabindex="-1"></a> METADATA {</span>
<span id="cb174-8"><a href="#cb174-8" aria-hidden="true" tabindex="-1"></a> <span class="ot">"type"</span>: <span class="ot">"table"</span></span>
<span id="cb174-9"><a href="#cb174-9" aria-hidden="true" tabindex="-1"></a> };</span></code></pre></div>
<p>Just like for a REST Schema, the command only
succeeds if the client authenticates beforehand:</p>
<div class="sourceCode" id="cb175"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb175-1"><a href="#cb175-1" aria-hidden="true" tabindex="-1"></a> <span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">"/path/to/sdk/myService"</span></span>
<span id="cb175-2"><a href="#cb175-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb175-3"><a href="#cb175-3" aria-hidden="true" tabindex="-1"></a> <span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()</span>
<span id="cb175-4"><a href="#cb175-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb175-5"><a href="#cb175-5" aria-hidden="true" tabindex="-1"></a> <span class="cf">await</span> myService<span class="op">.</span><span class="fu">authenticate</span>({ username<span class="op">:</span> <span class="st">"foo"</span><span class="op">,</span> password<span class="op">:</span> <span class="st">"bar"</span><span class="op">,</span> app<span class="op">:</span> <span class="st">"MySQL"</span> })</span>
<span id="cb175-6"><a href="#cb175-6" aria-hidden="true" tabindex="-1"></a> <span class="kw">const</span> metadata <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="at">myDb</span><span class="op">.</span><span class="at">myTable</span><span class="op">.</span><span class="fu">getMetadata</span>()</span>
<span id="cb175-7"><a href="#cb175-7" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(metadata) <span class="co">// { type: "table" }</span></span></code></pre></div>
<p>Otherwise, the command yields an authentication
error:</p>
<div class="sourceCode" id="cb176"><pre
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb176-1"><a href="#cb176-1" aria-hidden="true" tabindex="-1"></a> <span class="im">import</span> { MyService } <span class="im">from</span> <span class="st">"/path/to/sdk/myService"</span></span>
<span id="cb176-2"><a href="#cb176-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb176-3"><a href="#cb176-3" aria-hidden="true" tabindex="-1"></a> <span class="kw">const</span> myService <span class="op">=</span> <span class="kw">new</span> <span class="fu">MyService</span>()</span>
<span id="cb176-4"><a href="#cb176-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb176-5"><a href="#cb176-5" aria-hidden="true" tabindex="-1"></a> <span class="cf">try</span> {</span>
<span id="cb176-6"><a href="#cb176-6" aria-hidden="true" tabindex="-1"></a> <span class="kw">const</span> metadata <span class="op">=</span> <span class="cf">await</span> myService<span class="op">.</span><span class="at">myDb</span><span class="op">.</span><span class="at">myTable</span><span class="op">.</span><span class="fu">getMetadata</span>()</span>
<span id="cb176-7"><a href="#cb176-7" aria-hidden="true" tabindex="-1"></a> } <span class="cf">catch</span> (err) {</span>
<span id="cb176-8"><a href="#cb176-8" aria-hidden="true" tabindex="-1"></a> <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(err) <span class="co">// Not authenticated. Please authenticate first before accessing the path /myService/myDb/myTable/_metadata.</span></span>
<span id="cb176-9"><a href="#cb176-9" aria-hidden="true" tabindex="-1"></a> }</span></code></pre></div>
<p>Copyright (c) 2022, 2025, Oracle and/or its
affiliates.</p>
</div>
</div>
</div>
</body>
</html>