From 0ea2d4b846a1937a21167715f77afeed8c070395 Mon Sep 17 00:00:00 2001 From: Dhiraj Kumar Azad Date: Mon, 1 Apr 2024 22:42:21 +0530 Subject: [PATCH 1/4] initial commit --- docs/databases.md | 153 +++++++++++++++++- .../img/Couchbase_Lite_Database_Hierarchy.svg | 55 +++++++ static/img/Couchbase_Lite_Examples.svg | 64 ++++++++ 3 files changed, 271 insertions(+), 1 deletion(-) create mode 100644 static/img/Couchbase_Lite_Database_Hierarchy.svg create mode 100644 static/img/Couchbase_Lite_Examples.svg diff --git a/docs/databases.md b/docs/databases.md index 9dc2040..209d685 100644 --- a/docs/databases.md +++ b/docs/databases.md @@ -3,4 +3,155 @@ id: databases sidebar_position: 4 --- -# Databases \ No newline at end of file +# Databases + +> Description — _Working with Couchbase Lite Databases_ +> Related Content — [Blobs](blobs.md) | [Documents](documents.md) | [Indexing](indexing.md) + + +## Database Concepts + +Databases created on Couchbase Lite can share the same hierarchical structure as Capella databases. This makes it easier to sync data between mobile applications and applications built using Capella. + +
+ +![Couchbase Lite Database Hierarchy](/img/Couchbase_Lite_Database_Hierarchy.svg) + +_Figure 1. Couchbase Lite Database Hierarchy_ + +
+ +Although the terminology is different, the structure can be mapped to relational database terms: + +Table 1. Relational Database → Couchbase + +| Relational database | Couchbase | +|---------------------|---------------------| +| Database | Database | +| Schema | Scope | +| Table | Collection | + +This structure gives you plenty of choices when it comes to partitioning your data. The most basic structure is to use the single default scope with a single default collection; or you could opt for a structure that allow you to split your collections into logical scopes. + + +
+ +![Couchbase Lite Examples](/img/Couchbase_Lite_Examples.svg) + +_Figure 2. Couchbase Lite Examples_ + +
+ +### Storing local configuration + +You may not need to sync all the data related to a particular application. You can set up a scope that syncs data, and a second scope that doesn’t. One reason for doing this is to store local configuration data (such as the preferred screen orientation or keyboard layout). Since this information only relates to a particular device, there is no need to sync it: + +- **local data scope** — Contains information pertaining to the device. +- **syncing data scope** — Contains information pertaining to the user, which can be synced back to the cloud for use on the web or another device. + +## Managing Couchbase Lite Databases in Ionic + +### Initializing the Environment +To work with Couchbase Lite databases in an Ionic application, you must first initialize the Capacitor Engine and set up the Database Context. This setup is crucial for enabling communication between your Ionic application and the native platform-specific database operations. + +**Example: Initializing Capacitor Engine and Database Context** +```javascript +import { CapacitorEngine } from 'couchbase-lite-ee-ionic'; +import DatabaseContext from './providers/DatabaseContext'; + +const engine = new CapacitorEngine(); +``` + +This initialization should occur once, typically in your application's root component or main entry file. + +### Create or Open a Database + +To create or open a database, use the Database class from the cblite-core package, specifying the database name and optionally, a DatabaseConfiguration for custom settings like the database directory or encryption. + +**Example 1. Creating/Opening a Database** + +```javascript +import { Database, DatabaseConfiguration } from 'cblite-core'; + +const config = new DatabaseConfiguration(); +config.setDirectory('path/to/database'); // Optional +const myDatabase = new Database('myDatabaseName', config); +await myDatabase.open(); +``` + +### Closing a Database + +You are advised to incorporate the closing of all open databases into your application workflow. + +**Example 2. Closing a Database** + +```javascript +await myDatabase.close(); +``` + +## Database Encryption + +Couchbase Lite includes the ability to encrypt Couchbase Lite databases. This allows mobile applications to secure data at rest, when it is being stored on the device. The algorithm used to encrypt the database is 256-bit AES. + +### Enabling + +To enable database encryption in Ionic, use the `DatabaseConfiguration` class to set an encryption key before opening or creating a database. This encryption key must be provided every time the database is accessed. + +**Example3. Configure Database Encryption** + +```typescript +import { useContext } from 'react'; +import { IonButton, IonInput } from '@ionic/react'; +import DatabaseContext from '../context/DatabaseContext'; +import { Database, DatabaseConfiguration } from 'cblite-core'; + +const EncryptDatabasePage = () => { + const { addDatabase } = useContext(DatabaseContext); + + const createEncryptedDatabase = async () => { + const dbName = 'my_secure_db'; + const encryptionKey = 'my_secret_key'; + const config = new DatabaseConfiguration().setEncryptionKey(encryptionKey); + const db = new Database(dbName, config); + await db.open(); + addDatabase(db); + }; + + return ( +
+ + + Encrypt & Open Database +
+ ); +}; + +export default EncryptDatabasePage; +``` + +### Persisting + +Couchbase Lite does not persist the key. It is the application’s responsibility to manage the key and store it in a platform-specific secure store such as Apples's [Keystore](https://developer.apple.com/documentation/security/keychain_services) or Android’s [Keystore](https://developer.android.com/privacy-and-security/keystore). + +### Opening + +An encrypted database can only be opened with the same language package that was used to encrypt it in the first place. So a database encrypted using the Ionic package, and then exported, is readable only by the Ionic package. + +## Database Maintenance + + + +## Command Line Tool + +cblite is a command-line tool for inspecting and querying Couchbase Lite databases. + +You can download and build it from the couchbaselabs [GitHub repository](https://github.com/couchbaselabs/couchbase-mobile-tools/blob/master/README.cblite.md). Note that the cblite tool is not supported by the [Couchbase Support Policy](https://www.couchbase.com/support-policy/). + + +## Couchbase Lite for VSCode + +Couchbase Lite for VSCode is a Visual Studio Code extension that provides a user interface for inspecting and querying Couchbase Lite databases. You can find more information about this extension from it's [GitHub repository](https://github.com/couchbaselabs/vscode-cblite). + + + + diff --git a/static/img/Couchbase_Lite_Database_Hierarchy.svg b/static/img/Couchbase_Lite_Database_Hierarchy.svg new file mode 100644 index 0000000..c269bad --- /dev/null +++ b/static/img/Couchbase_Lite_Database_Hierarchy.svg @@ -0,0 +1,55 @@ +DatabaseScopeCollectionDocumentDocumentDocumentMaximum of 1000 per scopeOne database per application \ No newline at end of file diff --git a/static/img/Couchbase_Lite_Examples.svg b/static/img/Couchbase_Lite_Examples.svg new file mode 100644 index 0000000..c928635 --- /dev/null +++ b/static/img/Couchbase_Lite_Examples.svg @@ -0,0 +1,64 @@ +Couchbase Lite database_default scopeCouchbase Lite database_default scopeScope A_default collection_default collectionCollection ACollection ACollection B \ No newline at end of file From 5bf0430cb5e94fbe5d16eeb0220c553b18c06566 Mon Sep 17 00:00:00 2001 From: Dhiraj Kumar Azad Date: Tue, 2 Apr 2024 20:43:44 +0530 Subject: [PATCH 2/4] worked on comments and added docs for prebuilt database --- docs/database-prebuilt.md | 114 +++++++++++++++++++++++++++++++++++++- docs/databases.md | 67 +++++++++++----------- 2 files changed, 149 insertions(+), 32 deletions(-) diff --git a/docs/database-prebuilt.md b/docs/database-prebuilt.md index 7c68c2b..fe15277 100644 --- a/docs/database-prebuilt.md +++ b/docs/database-prebuilt.md @@ -3,4 +3,116 @@ id: database-prebuilt sidebar_position: 5 --- -# Pre-built Database \ No newline at end of file +# Pre-built Database + +> Description — _How to Handle Pre-Built Couchbase Lite Databases in Your App_ +> Abstract — _This content explains how to include a snapshot of a pre-built database in your package to shorten initial sync time and reduce bandwidth use._ + +## Overview + +*Couchbase Lite* supports pre-built databases. You can pre-load your app with data instead of syncing it from Sync Gateway during startup to minimize consumer wait time (arising from data setup) on initial install and launch of the application. + +Avoiding an initial bulk sync reduces startup time and network transfer costs. + +It is typically more efficient to download bulk data using the http/ftp stream employed during the application installation than to install a smaller application bundle and then use a replicator to pull in the bulk data. + +Pre-loaded data is typically public/shared, non-user-specific data that is static. Even if the data is not static, you can still benefit from preloading it and only syncing the changed documents on startup. + +The initial sync of any pre-built database pulls in any content changes on the server that occurred after its incorporation into the app, updating the database. + +## To use a Pre-built Database + +1. Create a new Couchbase Lite database with the required data set - see [Creating Pre-built database](#creating-pre-built-database). + +2. Incorporate the pre-built database with your app bundle as an asset/resource - see [Bundle a Database with an Application](#bundle-a-database-with-an-application). + +3. Adjust the start-up logic of your app to check for the presence of the required database. If the database doesn’t already exist, create one using the bundled pre-built database. Initiate a sync to update the data - see [Using Pre-built Database on App Launch](#using-pre-built-database-on-app-launch). + +## Creating Pre-built database + +These steps should form part of your build and release process: + +1. Create a fresh Couchbase Lite database (every time) + +:::important +Always start with a fresh database for each app version; this ensures there are no checkpoint issues. + +**Otherwise:** You will invalidate the cached checkpoint in the packaged database, and instead reuse the same database in your build process (for subsequent app versions). +::: + +2. Pull the data from Sync Gateway into the new Couchbase Lite database + +:::important +Ensure the replication used to populate Couchbase Lite database uses the exact same remote URL and replication config parameters (channels and filters) as those your app will use when it is running. + +**Otherwise:** …​ there will be a checkpoint mismatch and the app will attempt to pull the data down again + +Don’t, for instance, create a pre-built database against a staging Sync Gateway server and use it within a production app that syncs against a production Sync Gateway. +::: + +You can use the cblite tool (cblite cp) for this — see: [cblite cp (export, import, push, pull)](https://github.com/couchbaselabs/couchbase-mobile-tools/blob/master/Documentation.md#cp-aka-export-import-push-pull) on GitHub. + + +3. Create the same indexes the app will use (wait for the replication to finish before doing this). + +## Bundle a database with an application + +Copy the database into your app package. + +Put it in an appropriate place (for example, an assets or resource folder). + +Where the platform permits you can zip the database. + +**Alternatively:**​ rather than bundling the database within the app, the app could pull the database down from a CDN server on launch. + +## Database Encryption + +If you are using en encrypted database, note that Database.copy does not change the encryption key. The encryption key specified in the config when opening the database is the encryption key used for both the original database and copied database. + +If you copied an un-encrypted database and want to apply encryption to the copy, or if you want to change (or remove) the encryption key applied to the copy: + +1. Provide the original encryption-key (if any) in the database copy's configuration using DatabaseConfiguration.getEncryptionKey(). + +2. Open the database copy + +3. Use Database.setEncryptionKey() on the database copy to set the required encryption key. + +:::tip +To remove encryption on the copy, provide a null encryption-key. +::: + +## Using Pre-built Database on App Launch + +1. Locate the pre-packaged database (for example, in the assets or other resource folder) + +2. Copy the pre-packaged database to the required location + +Use the API's Database.copy method — see: [Example 1](#example-1-decompress-and-copy-database-using-api). This ensures that a unique UUID is generated for each copy. + +:::important +Do not copy the database using any other method. + +**Otherwise:** Each copy of the app will invalidate the other apps' checkpoints because a new UUID was not generated. +::: + +3. Open the database; you can now start querying the data and using it. + +4. Start a pull replication, to sync any changes. + +The replicator uses the pre-built database's checkpoint as the timestamp to sync from; only documents changed since then are synced. + +:::note +Start your normal application logic immediately, unless it is essential to have the absolute up-to-date data set to begin. That way the user is not kept hanging around watching a progress indicator. They can begin interacting with your app whilst any out-of-data data is being updated. +::: + +#### Example 1. Decompress and Copy Database using API + +```typescript +// Check if the database already exists +if (!await Database.exists(dbName, null)) { + // Copy the database from the sourcePath to the app's directory + await Database.copy(sourcePath, dbName, new DatabaseConfiguration()); +} +``` + + diff --git a/docs/databases.md b/docs/databases.md index 209d685..cdad2ea 100644 --- a/docs/databases.md +++ b/docs/databases.md @@ -52,17 +52,17 @@ You may not need to sync all the data related to a particular application. You c ## Managing Couchbase Lite Databases in Ionic ### Initializing the Environment -To work with Couchbase Lite databases in an Ionic application, you must first initialize the Capacitor Engine and set up the Database Context. This setup is crucial for enabling communication between your Ionic application and the native platform-specific database operations. + +In an Ionic application using Couchbase Lite, begin by initializing the Capacitor Engine. Subsequently, employ a design pattern such as Context/Provider or Service Locator to maintain and access your database instances throughout the application lifecycle. **Example: Initializing Capacitor Engine and Database Context** ```javascript import { CapacitorEngine } from 'couchbase-lite-ee-ionic'; -import DatabaseContext from './providers/DatabaseContext'; -const engine = new CapacitorEngine(); +const engine = new CapacitorEngine(); // Initialize once, early in your app ``` -This initialization should occur once, typically in your application's root component or main entry file. +This configuration ensures seamless interaction between your Ionic app and the underlying native database functionalities, facilitating effective database management. ### Create or Open a Database @@ -100,33 +100,11 @@ To enable database encryption in Ionic, use the `DatabaseConfiguration` class to **Example3. Configure Database Encryption** ```typescript -import { useContext } from 'react'; -import { IonButton, IonInput } from '@ionic/react'; -import DatabaseContext from '../context/DatabaseContext'; -import { Database, DatabaseConfiguration } from 'cblite-core'; - -const EncryptDatabasePage = () => { - const { addDatabase } = useContext(DatabaseContext); - - const createEncryptedDatabase = async () => { - const dbName = 'my_secure_db'; - const encryptionKey = 'my_secret_key'; - const config = new DatabaseConfiguration().setEncryptionKey(encryptionKey); - const db = new Database(dbName, config); - await db.open(); - addDatabase(db); - }; - - return ( -
- - - Encrypt & Open Database -
- ); -}; - -export default EncryptDatabasePage; +const dbName = 'my_secure_db'; +const encryptionKey = 'my_secret_key'; +const config = new DatabaseConfiguration().setEncryptionKey(encryptionKey); +const db = new Database(dbName, config); +await db.open(); ``` ### Persisting @@ -139,6 +117,11 @@ An encrypted database can only be opened with the same language package that was ## Database Maintenance +From time to time it may be necessary to perform certain maintenance activities on your database, for example to compact the database file, removing unused documents and blobs no longer referenced by any documents. + +```typescript +await db.compact(); +``` ## Command Line Tool @@ -152,6 +135,28 @@ You can download and build it from the couchbaselabs [GitHub repository](https:/ Couchbase Lite for VSCode is a Visual Studio Code extension that provides a user interface for inspecting and querying Couchbase Lite databases. You can find more information about this extension from it's [GitHub repository](https://github.com/couchbaselabs/vscode-cblite). +## Couchbase Lite for JetBrains + +Couchbase Lite for JetBrains is a JetBrains IDE plugin that provides a user interface for inspecting and querying Couchbase Lite databases. You can find more information about this plugin from its [GitHub repository](https://github.com/couchbaselabs/couchbase_jetbrains_plugin). + +## Troubleshooting + +You should use console logs as your first source of diagnostic information. If the information in the default logging level is insufficient you can focus it on database errors and generate more verbose messages. + + +```typescript +import { Database, LogDomain, LogLevel } from 'cblite-core'; + +db.setLogLevel(LogDomain.DATABASE, LogLevel.VERBOSE) + .then(() => console.log('Database log level set to VERBOSE.')) + .catch(error => console.error('Setting log level failed:', error)); +``` + + + + + + From 51d359df2ce77e86733d924efc9782284cff10d7 Mon Sep 17 00:00:00 2001 From: Dhiraj Kumar Azad Date: Mon, 8 Apr 2024 14:49:10 +0530 Subject: [PATCH 3/4] added documentation for databases and blobs --- docs/blobs.md | 91 ++++++++++- docs/documents.md | 384 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 473 insertions(+), 2 deletions(-) diff --git a/docs/blobs.md b/docs/blobs.md index 6e99afe..dc8494d 100644 --- a/docs/blobs.md +++ b/docs/blobs.md @@ -3,4 +3,93 @@ id: blobs sidebar_position: 8 --- -# Blobs \ No newline at end of file +# Blobs + +> Description — _Couchbase Lite database data model concepts - blobs_ +> Related Content — [Databases](databases.md) | [Documents](documents.md) | [Indexing](indexing.md) + +## Introduction + +Couchbase Lite for Ionic uses blobs to store the contents of images, other media files and similar format files as binary objects. + +The blob itself is not stored in the document. It is held in a separate content-addressable store indexed from the document and retrieved only on-demand. + +When a document is synchronized, the Couchbase Lite replicator adds an `_attachments` dictionary to the document's properties if it contains a blob — see [Figure 1](#figure-1-sample-blob-document). + +## Blob Objects + +The blob as an object appears in a document as dictionary property — see, for example avatar in [Figure 1](#figure-1-sample-blob-document). + +Other properties include `length` (the length in bytes), and optionally `content_type` (typically, its MIME type). + +The blob's data (an image, audio or video content) is not stored in the document, but in a separate content-addressable store, indexed by the `digest` property — see [Using Blobs]. + +### Constraints + +* Couchbase Lite + + Blobs can be arbitrarily large. They are only read on demand, not when you load a the document. + +* Capella App Services/Sync Gateway + + The maximum content size is 20 MB per blob. If a document's blob is over 20 MB, the document will be replicated but not the blob. + +## Using Blobs + +The Blob API lets you access the blob's data content as in-memory data or as a Stream of Uint8Array. + +The code in [Example 1](#example-1-working-with-blobs) shows how you might add a blob to a document and save it to the database. Here we use avatar as the property key and a jpeg file as the blob data. + +#### Example 1. Working with Blobs + +```typescript +// Example function to simulate fetching binary data for an avatar image +const imageData = await fetchAvatarImageData(); + +// Create a Blob instance with the image data and content type +const avatarBlob = new Blob('image/jpeg', imageData); + +// Retrieve an existing document +let document = await database.getDocument(documentId); + +// Assign the Blob to the document under the 'avatar' key +document.setBlob('avatar', avatarBlob); + +// Save the updated document back to the database +await database.save(document); +``` + +## Syncing + +When a document containing a blob object is synchronized, the Couchbase Lite replicator generates an `_attachments` dictionary with an auto-generated name for each blob attachment. This is different to the `avatar` key and is used internally to access the blob content. + +If you view a sync'd blob document in either Capella's Admin Interface or Couchbase Server's Admin Console, you will see something similar to [Figure 1], which shows the document with its generated `_attachments` dictionary, including the digest. + +#### Figure 1. Sample Blob Document + +```typescript +{ + "_attachments": { + "blob_1": { + "content_type": "image/jpeg", + "digest": "sha1-F1Tfe61RZP4zC9UYT6JFmLTh2s8=", + "length": 8112955, + "revpos": 2, + "stub": true + } + }, + "avatar": { + "@type": "blob", + "content_type": "image/jpeg", + "digest": "sha1-F1Tfe61RZP4zC9UYT6JFmLTh2s8=", + "length": 8112955 + } +} +``` + + + + + + + diff --git a/docs/documents.md b/docs/documents.md index d09e817..39e6064 100644 --- a/docs/documents.md +++ b/docs/documents.md @@ -3,4 +3,386 @@ id: documents sidebar_position: 7 --- -# Documents \ No newline at end of file +# Documents + +> Description — _Couchbase Lite Concepts - Data Model - Documents_ +> Related Content — [Databases](databases.md) | [Blobs](blobs.md) | [Indexing](indexing.md) + +## Overview + +### Document Structure + +In Couchbase Lite the term 'document' refers to an entry in the database. You can compare it to a record, or a row in a table. + +Each document has an ID or unique identifier. This ID is similar to a primary key in other databases. + +You can specify the ID programmatically. If you omit it, it will be automatically generated as a UUID. + +:::note +Couchbase documents are assigned to a Collection. The ID of a document must be unique within the Collection it is written to. You cannot change it after you have written the document. +::: + +The document also has a value which contains the actual application data. This value is stored as a dictionary of key-value (k-v) pairs. The values can be made of up several different Data Types such as numbers, strings, arrays, and nested objects. + +### Data Encoding + +The document body is stored in an internal, efficient, binary form called [Fleece](https://github.com/couchbase/fleece#readme). This internal form can be easily converted into a manageable native dictionary format for manipulation in applications. + +Fleece data is stored in the smallest format that will hold the value whilst maintaining the integrity of the value. + +### Data Types + +The Document class offers a set of property accessors for various scalar types, such as: + +* Boolean + +* Date + +* Double + +* Float + +* Int + +* Long + +* String + +These accessors take care of converting to/from JSON encoding, and make sure you get the type you expect. + +In addition to these basic data types Couchbase Lite provides for the following: + +* **Dictionary** - Represents a read-only key-value pair collection +* **MutableDictionary** - Represents a writeable key-value pair collection. +* **Array** - Represents a writeable collection of objects. +* **MutableArray** - Represents a writeable collection of objects. +* **Blob** - Represents an arbitrary piece of binary data. + +### JSON + +Couchbase Lite also provides for the direct handling of JSON data implemented in most cases by the provision of a ToJSON() method on appropriate API classes (for example, on MutableDocument, Dictionary, Blob and Array) — see Working with JSON Data. + +## Constructing a Document + +An individual document often represents a single instance of an object in application code. A document might be considered equivalent to a row in a relational table; with each of the document's attributes being equivalent to a column. + +Documents can contain nested structures. This allows developers to express many-to-many relationships without requiring a reference or junction table; and is naturally expressive of hierarchical data. + +Most apps will work with one or more documents, persisting them to a local database and optionally syncing them, either centrally or to the cloud. + +In this section we provide an example of how you might create a hotel document, which provides basic contact details and price data. + +### Data Model + +```typescript +hotel: { + type: string (value = `hotel`) + name: string + address: dictionary { + street: string + city: string + state: string + country: string + code: string + } + phones: array + rate: float +} +``` + +### Open a Database + +First open your database. If the database does not already exist, Couchbase Lite will create it for you. + +```typescript +const myDatabase = new Database('myDatabaseName', config); +``` +See [Databases](https://cbl-ionic.dev/databases) for more information. + +### Create a Document + +```typescript +let document = new MutableDocument(hotel.id); +``` + + +For more on using Documents, see Document Initializers and Mutability. + +### Create a Dictionary + +Now create a mutable dictionary (address). + +Each element of the dictionary value will be directly accessible via its own key. + +```typescript +// Create a new MutableDocument instance +const document = new MutableDocument(); + +// Now, populate the document as if it's a dictionary named 'address' +document.setString('address.street', '1 Main st.'); +document.setString('address.city', 'San Francisco'); +document.setString('address.state', 'CA'); +document.setString('address.country', 'USA'); +document.setString('address.code', '90210'); +``` + +### Create an Array + +Since the hotel may have multiple contact numbers, provide a field (phones) as a mutable array. + +```typescript +// Create an instance of MutableDocument +const hotelInfo = new MutableDocument(); + +// Since `setArray` method accepts an array, directly pass the contact numbers as an array +hotelInfo.setArray("phones", ["650-000-0000", "650-000-0001"]); +``` + +### Populate a Document + +Now add your data to the mutable document created earlier. Each data item is stored as a key-value pair. + +```typescript +// Assuming address and phones are already defined as shown in previous examples +const address = { + street: "1 Main st.", + city: "San Francisco", + state: "CA", + country: "USA", + code: "90210" +}; + +const phones = ["650-000-0000", "650-000-0001"]; + +// Create an instance of MutableDocument +let hotelInfo = new MutableDocument(); + +// Add document type and hotel name as string +hotelInfo.setString("type", "hotel"); +hotelInfo.setString("name", "Hotel Java Mo"); + +// Add average room rate (float) +hotelInfo.setFloat("room_rate", 121.75); + +// Add address (dictionary) +hotelInfo.setDictionary("address", address); + +// Add phone numbers (array) +hotelInfo.setArray("phones", phones); +``` + +:::note +Couchbase recommend using a type attribute to define each logical document type. +::: + +### Save a Document + +With the document now populated, we can persist to our Couchbase Lite database. + +```typescript +db.save(hotelInfo); +``` + +### Close the Database + +With your document saved, you can now close our Couchbase Lite database. + +```typescript +db.close(); +``` + +## Working with Data + +### Checking a Document's Properties + +### Date accessors + +Couchbase Lite offers Date accessors as a convenience. Dates are a common data type, but JSON doesn’t natively support them, so the convention is to store them as strings in ISO-8601 format. + +#### Example 1. Date Getter + +This example sets the date on the createdAt property and reads it back using the Document.getDate() accessor method. + +```typescript +// Create an instance of MutableDocument +let document = new MutableDocument(); + +// Set the current date on the "createdAt" property +document.setDate("createdAt", new Date()); + +// Get the Date +const date = document.getDate("createdAt"); +``` + +### Using Dictionaries + +#### API References + + +#### Example 2. Read Only + +```typescript +// Get a document by ID +const doc: Document = database.getDocument('doc1'); + +// Getting a dictionary from the document's properties +const addressDict = doc.getDictionary('address'); + +// Access a value with a key from the dictionary +const street = addressDict?.getString('street'); + +// Iterate over the dictionary +Object.keys(addressDict || {}).forEach(key => { + console.log(`Key ${key} = ${addressDict[key]}`); +}); + +// Create a mutable copy +const mutableDict = { ...addressDict }; +``` + +#### Example 3. Mutable + +```typescript +// Create a new "dictionary" as a simple JavaScript object +const addressDict = { + street: "1 Main st.", + city: "San Francisco", +}; + +// Create a new mutable document and add the dictionary to its properties +const mutableDoc = new MutableDocument("doc1"); +mutableDoc.setDictionary("address", addressDict); + +// Simulate saving the document +mutableDoc.save(); +``` + +### Using Arrays + +#### API References + + +#### Example 4. Read Only + +```typescript +// Getting a phones array from the document's properties +const phonesArray = document.data.phones; + +// Get element count +const count = phonesArray.length; + +// Access an array element by index +if (count >= 1) { + const phone = phonesArray[1]; + console.log(`Second phone: ${phone}`); +} + +// Iterate over the array +phonesArray.forEach((item, index) => { + console.log(`Item ${index} = ${item}`); +}); + +// Create a mutable copy of the array +const mutableArray = [...phonesArray]; +``` + +#### Example 5. Mutable + +```typescript +// Create a new mutable document +const document = new MutableDocument(); + +// Prepare the data for the array +const phones = ["650-000-0000", "650-000-0001"]; + +// Assign the array to a key in the document +doc.setArray("phones", phones); + +// Save the document with the new array to the database +await database.save(doc); +``` + +### Using Blobs + +For more on working with blobs, see [Blobs](blobs.md) + +## Document Initializers + +The `MutableDocument` constructor is utilized to create a new document instance. If no document ID is specified, the database generates a unique ID for the document automatically. + +The `Database.getDocument` method can be used to get a document. If it doesn't exist in the database, it will return null. This method can be used to check if a document with a given ID already exists in the database. + +#### Example 6. Persist a document + +The following code example creates a document and persists it to the database. + +```typescript +// Create a new MutableDocument instance +const document = new MutableDocument(); + +// Set various fields on the document +document.setString('type', 'task'); +document.setString('owner', 'todo'); +document.setDate('createdAt', new Date()); + +// Persist the document to the database +await database.save(document); +``` + +## Mutability + +## Batch Operations + +If you’re making multiple changes to a database at once, it’s faster to group them together. The following example persists a few documents in batch. + +#### Example 8. Batch Operations + +## Document change events + +It is possible to register for document changes. The following example registers for changes to the document with ID user.john and prints the verified_account property when a change is detected. + +```typescript +const token = database.addDocumentChangeListener('user.john', async (change) => { + const document = await database.getDocument(change.documentID); + if (document !== null) { + console.log(`Status: ${document.getString('verified_account')}`); + } +}); +``` + +## Document Expiration + +## Document Constraints + +Couchbase Lite APIs do not explicitly disallow the use of attributes with the underscore prefix at the top level of document. This is to facilitate the creation of documents for use either in local only mode where documents are not synced. + +:::note +`_id`, `_rev` and `_sequence` are reserved keywords and must not be used as top-level attributes — see [Example 13](#example-13-reserved-keys-list). +::: + +#### Example 13. Reserved Keys List + +* `_attachments` +* `_deleted` +* `_id` +* `_removed` +* `_rev` +* `_sequence` + +## Working with JSON Data + + + + + + + + + + + + + + + + From e207095b36c8b0ce0d7a7400be2b2cb028dd7881 Mon Sep 17 00:00:00 2001 From: Dhiraj Kumar Azad Date: Wed, 10 Apr 2024 13:41:22 +0530 Subject: [PATCH 4/4] Added docs for logging --- docs/Troubleshooting/using-logs.md | 42 +++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/docs/Troubleshooting/using-logs.md b/docs/Troubleshooting/using-logs.md index 8b8128a..dbe1efa 100644 --- a/docs/Troubleshooting/using-logs.md +++ b/docs/Troubleshooting/using-logs.md @@ -3,4 +3,44 @@ id: using-logs sidebar_position: 1 --- -# Using Logs \ No newline at end of file +# Using Logs for Troubleshooting + +> Description — _Couchbase Lite on Ionic — Using Logs for Troubleshooting_ +> Related Content — [Troubleshooting Queries](troubeshoot-queries.md) | [Troubleshooting Crashes](troubleshoot-crashes.md) + +:::note +* The retrieval of logs from the device is out of scope of this feature. +* This content applies to the post 2.5 versions. If you are using a Couchbase Lite release prior to 2.5 see Deprecated functionality. +::: + +## Introduction + +Couchbase Lite provides a robust Logging API — see: API References for Logging classes — which make debugging and troubleshooting easier during development and in production. It delivers flexibility in terms of how logs are generated and retained, whilst also maintaining the level of logging required by Couchbase Support for investigation of issues. + +Log output is split into the following streams: + +* File based logging + + Here logs are written to separate log files filtered by log level, with each log level supporting individual retention policies. + +* Console based logging + + You can independently configure and control console logs, which provides a convenient method of accessing diagnostic information during debugging scenarios. With console logging, you can fine-tune diagnostic output to suit specific debug scenarios, without interfering with any logging required by Couchbase Support for the investigation of issues. + +* Custom logging + + For greater flexibility you can implement a custom logging class using the ILogger interface. + +## Console based logging + +Console based logging is often used to facilitate troubleshooting during development. + +Console logs are your go-to resource for diagnostic information. You can easily fine-tune their diagnostic content to meet the needs of a particular debugging scenario, perhaps by increasing the verbosity and-or choosing to focus on messages from a specific domain; to better focus on the problem area. + +Changes to console logging are independent of file logging, so you can make change without compromising any files logging streams. It is enabled by default. To change default settings use database’s setLogLevel method to set the required values — see Example 1. + +#### Example 1. Change Console Logging Settings + +```typescript +database.setLogLevel(LogDomain.ALL, Loglevel.VERBOSE); +```