### Pagination example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of using page and pageSize parameters for pagination. ```javascript const posts = await broker.call("posts.list", { page: 3, pageSize: 10 }); ``` -------------------------------- ### Multiple populates example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of populating multiple fields. ```javascript const posts = await broker.call("posts.find", { populate: ["author", "voters"] }); ``` -------------------------------- ### Get function example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of using the `get` function to mask a credit card number. ```javascript { creditCardNumber: { type: "string", // Mask the credit card number get: ({ value }) => value.replace(/(\d{4}-){3}/g, "****-****-****-") } } ``` -------------------------------- ### Searching example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of using search and searchText parameters. ```javascript const posts = await broker.call("posts.find", { search: "content", searchText: ["title", "content"] }); ``` -------------------------------- ### Limit & offset example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of using limit and offset parameters. ```javascript const posts = await broker.call("posts.find", { limit: 10, offset: 50 }); ``` -------------------------------- ### Install Knex Source: https://github.com/moleculerjs/database/blob/master/docs/adapters/Knex.md Install the dependent library for the Knex adapter. ```bash npm install knex@^1.0.1 ``` -------------------------------- ### Multiple scopes example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of using multiple scopes. ```javascript const posts = await broker.call("posts.find", { scope: ["onlyActive", "hasVotes"] }); ``` -------------------------------- ### Populate example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of using the populate parameter to include related data. ```javascript const posts = await broker.call("posts.find", { populate: "author" }); ``` -------------------------------- ### Example Source: https://github.com/moleculerjs/database/blob/master/docs/adapters/Knex.md This example shows how to configure the Knex adapter with MSSQL and define the service settings. ```javascript // posts.service.js const DbService = require("@moleculer/database").Service; module.exports = { name: "posts", mixins: [DbService({ adapter: { type: "Knex", options: { knex: { client: "mssql", connection: { host: "127.0.0.1", port: 1433, user: "sa", password: "Moleculer@Pass1234", database: "moleculer", encrypt: false } } } } })], settings: { fields: { id: { type: "number", primaryKey: true, columnName: "_id", columnType: "integer" }, title: { type: "string", required: true, max: 100, trim: true }, content: { type: "string", columnType: "text" } } }, async started() { const adapter = await this.getAdapter(); await adapter.createTable(); } } ``` -------------------------------- ### Using query example (simple) Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of using the query parameter with a simple object. ```javascript const posts = await broker.call("posts.find", { query: { status: false } }); ``` -------------------------------- ### Fields example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of using the fields parameter to select specific fields. ```javascript const posts = await broker.call("posts.find", { fields: ["id", "title", "votes"] }); ``` -------------------------------- ### Install Source: https://github.com/moleculerjs/database/blob/master/README.md Install the @moleculer/database package and optionally @seald-io/nedb for prototyping. ```bash npm i @moleculer/database @seald-io/nedb ``` -------------------------------- ### Default value examples Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Examples demonstrating how to set default values for fields, including asynchronous functions. ```javascript { votes: { type: "number", default: 0 }, role: { type: "string", default: async ({ ctx }) => await ctx.call("config.getDefaultRole") } status: { type: "boolean", default: true }, } ``` -------------------------------- ### Example with dependencies Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Demonstrates how to define service dependencies, which are other services the current service relies on. ```javascript module.exports = { name: "posts", mixins: [DbService(/*...*/)], // Define the 'users' as dependency dependencies: ["users", "comments"], /* ... */ }; ``` -------------------------------- ### Count entities example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Get the number of entities by query. ```javascript const postCount = await broker.call("posts.count"); ``` -------------------------------- ### Get an entity by ID example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Get an entity by ID. ```javascript const post = await broker.call("posts.get", { id: "YVdnh5oQCyEIRja0" }); ``` -------------------------------- ### Using query example (complex) Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of using the query parameter with a more complex object including operators. ```javascript const posts = await broker.call("posts.find", { query: { status: true, votes: { $gt: 5 } } }); ``` -------------------------------- ### Database/Server-based Tenancy Configuration Example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example configuration for database/server-based multi-tenancy in Moleculer's Database Service, using `getAdapterByContext` to specify connection strings. ```javascript // posts.service.js module.exports = { name: "posts", mixins: [DbService({ adapter: "MongoDB" })], settings: { fields: { id: { type: "string", primaryKey: true, columnName: "_id" }, title: { type: "string", required: true, min: 5 }, content: { type: "string", required: true } } }, methods: { getAdapterByContext(ctx, adapterDef) { const tenantId = ctx && ctx.meta.user.tenantId; if (!tenantId) throw new Error("Missing tenantId!"); return [ // cache key tenantId, // Adapter options { type: "MongoDB", options: { uri: `mongodb://127.0.0.1:27017/moleculer-demo--${tenantId}`, collection: `posts` } } ]; } } }; ``` -------------------------------- ### Example Schema Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Demonstrates various field types and configurations including shorthand formats. ```javascript { id: { type: "string", primaryKey: true, columnName: "_id" }, username: { type: "string" }, age: "number", // Shorthand format dateOfBirth: { type: "date" }, address: { type: "object", properties: { country: { type: "string", required: true }, city: "string|required", // shorthand format street: { type: "string" } zip: { type: "number" } } }, phones: { type: "array", items: "string" } } ``` -------------------------------- ### Storing with non-supported adapters - Example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example showing how to set 'columnType' to 'string' for object fields when using non-SQL adapters. ```javascript module.exports = { // ... settings: { fields: { address: { type: "object", // Set columnType to string because it will be converted to JSON string. columnType: "string", properties: { // ... } } } } }; ``` -------------------------------- ### onCreate hook example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of using the `onCreate` hook to set `createdAt` timestamp and `createdBy` user ID. ```javascript { createdAt: { type: "number", readonly: true, onCreate: () => Date.now() }, createdBy: { type: "string", readonly: true, onCreate: ({ ctx }) => ctx.meta.user.id } } ``` -------------------------------- ### Scope example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of using the scope parameter to filter results. ```javascript const posts = await broker.call("posts.find", { scope: "onlyActive" }); ``` -------------------------------- ### Call the actions Source: https://github.com/moleculerjs/database/blob/master/README.md Examples of calling various database actions like create, find, list, get, update, and remove using the Moleculer broker. ```javascript // sample.js // Create a new post let post = await broker.call("posts.create", { title: "My first post", content: "Content of my first post..." }); console.log("New post:", post); /* Results: New post: { id: 'Zrpjq8B1XTSywUgT', title: 'My first post', content: 'Content of my first post...', votes: 0, status: true, createdAt: 1618065551990 } */ // Get all posts let posts = await broker.call("posts.find", { sort: "-createdAt" }); console.log("Find:", posts); // List posts with pagination posts = await broker.call("posts.list", { page: 1, pageSize: 10 }); console.log("List:", posts); // Get a post by ID post = await broker.call("posts.get", { id: post.id }); console.log("Get:", post); // Update the post post = await broker.call("posts.update", { id: post.id, title: "Modified post" }); console.log("Updated:", post); // Delete a user const res = await broker.call("posts.remove", { id: post.id }); console.log("Deleted:", res); ``` -------------------------------- ### Table/Collection-based Tenancy Configuration Example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example configuration for table/collection-based multi-tenancy in Moleculer's Database Service, demonstrating the `getAdapterByContext` method. ```javascript // posts.service.js module.exports = { name: "posts", mixins: [DbService({ adapter: "MongoDB" })], settings: { fields: { id: { type: "string", primaryKey: true, columnName: "_id" }, title: { type: "string", required: true, min: 5 }, content: { type: "string", required: true } } }, methods: { getAdapterByContext(ctx, adapterDef) { const tenantId = ctx && ctx.meta.user.tenantId; if (!tenantId) throw new Error("Missing tenantId!"); return [ // cache key tenantId, // Adapter options { type: "MongoDB", options: { uri: "mongodb://127.0.0.1:27017/moleculer-demo", collection: `posts-${tenantId}` } } ]; } } }; ``` -------------------------------- ### Field Definitions Example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md An example demonstrating how to define fields for a service using the Database Mixin, including various property types and configurations. ```javascript // posts.service.js module.exports = { // ... settings: { fields: { id: { type: "string", primaryKey: true, columnName: "_id" }, title: { type: "string", required: true, max: 100, trim: true }, content: { type: "string", columnType: "text" }, votes: "number|integer", // Shorthand format status: { type: "boolean", default: true }, createdAt: { type: "number", readonly: true, onCreate: () => Date.now() }, updatedAt: { type: "number", readonly: true, onUpdate: () => Date.now() } } } // ... } ``` -------------------------------- ### Virtual field example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example demonstrating a virtual field that computes its value. ```javascript { fullName: { type: "string", virtual: true, get: ({ entity }) => `${entity.firstName} ${entity.lastName}` } } ``` -------------------------------- ### Disable all default scopes example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of disabling all default scopes. ```javascript const posts = await broker.call("posts.find", { scope: false }); ``` -------------------------------- ### Set function example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of using the `set` function to combine first and last names into a full name, and to convert email to lowercase. ```javascript { firstName: { type: "string", required: true }, lastName: { type: "string", required: true }, fullName: { type: "string", readonly: true, set: ({ params }) => `${params.firstName} ${params.lastName}` }, email: { type: "string", set: value => value.toLowerCase() } } ``` -------------------------------- ### Immutable field example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example showing how to define an immutable field. ```javascript { accountType: { type: "string", immutable: true } } ``` -------------------------------- ### Service Hooks - Adapter hooks example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md An example demonstrating the usage of 'adapterConnected' and 'adapterDisconnected' hooks within a service's custom hooks. ```javascript // posts.service.js { name: "posts", mixins: [DbService(/*...*/)], hooks: { customs: { adapterConnected: "createTables" // method name async adapterDisconnected(adapter, hash) { // ... } } }, method: { async createTables(adapter, hash, adapterOpts) { // ... } } } ``` -------------------------------- ### Service Implementation Example Source: https://github.com/moleculerjs/database/blob/master/CLAUDE.md An example of how to implement a service using the @moleculer/database mixin. ```javascript const DbService = require("@moleculer/database").Service; module.exports = { name: "posts", mixins: [DbService({ adapter: "MongoDB" })], settings: { fields: { id: { type: "string", primaryKey: true, columnName: "_id" }, title: { type: "string", required: true }, // ... more fields } } } ``` -------------------------------- ### Record-based Tenancy Configuration Example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example configuration for record-based multi-tenancy in Moleculer's Database Service, including defining fields and scopes. ```javascript // posts.service.js module.exports = { name: "posts", mixins: [DbService({ adapter: "MongoDB" })], settings: { fields: { id: { type: "string", primaryKey: true, columnName: "_id" }, title: { type: "string", required: true, min: 5 }, content: { type: "string", required: true }, tenantId: { type: "string", required: true, set: ({ ctx }) => ctx.meta.user.tenantId } }, scopes: { tenant(q, ctx, params) { const tenantId = ctx.meta.user.tenantId; if (!tenantId) throw new Error("Missing tenantId!"); q.tenantId = tenantId; return q; } }, defaultScopes: ["tenant"] } }; ``` -------------------------------- ### Sorting (one field) example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of sorting by a single field. ```javascript const posts = await broker.call("posts.find", { sort: "createdAt" }); ``` -------------------------------- ### Sorting (multiple fields) example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of sorting by multiple fields, including descending order. ```javascript const posts = await broker.call("posts.find", { sort: ["-votes", "title"] }); ``` -------------------------------- ### Create multiple entities Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of creating multiple post entities. ```javascript const post = await broker.call("posts.createMany", [ { title: "My first post", content: "Content of my first post..." }, { title: "My second post", content: "Content of my second post..." } ]); ``` -------------------------------- ### Custom actions example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of defining custom actions like voteUp and voteDown in a Moleculer service. ```javascript // posts.service.js module.exports = { // ... actions: { voteUp: { rest: "POST /:id/vote-up", params: { id: "string|required" }, handler(ctx) { const entity = this.resolveEntity(ctx, params); return this.updateEntity(ctx, { id: ctx.params.id, votes: entity.votes + 1 }); } }, voteDown: { rest: "POST /:id/vote-down", params: { id: "string|required" }, handler(ctx) { const entity = this.resolveEntity(ctx, params); return this.updateEntity(ctx, { id: ctx.params.id, votes: entity.votes - 1 }); } } } // ... } ``` -------------------------------- ### Example with authority Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Demonstrates how to implement the `checkScopeAuthority` method in a service to control access based on user roles. ```javascript // posts.service.js module.exports = { name: "posts", mixins: [DbService(/*...*/)], settings: { /* ... */ }, methods: { /** * Check the scope authority. Should be implemented in the service. * * @param {Context} ctx * @param {String} name * @param {String} operation * @param {Object} scope */ async checkScopeAuthority(ctx, name, operation, scope) { // We enable default scope disabling only for administrators. if (operation == "remove") { return ctx.meta.user.roles.includes("admin"); } // Enable all other scopes for everybody. return true; }, } }; ``` -------------------------------- ### Example Valid Data Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Shows a valid data object conforming to the example schema. ```javascript { id: "abc123", username: "John Doe", age: 34, dateOfBirth: new Date(), address: { country: "UK", city: "London", street: "Main Street 156", zip: 12345 }, phones: ["555-1234", "555-9876"] } ``` -------------------------------- ### REST endpoint for find Source: https://github.com/moleculerjs/database/blob/master/docs/README.md GET /{serviceName}/all ```javascript GET /{serviceName}/all ``` -------------------------------- ### Install MongoDB driver Source: https://github.com/moleculerjs/database/blob/master/docs/adapters/MongoDB.md Command to install the MongoDB driver using npm. ```bash npm install mongodb@^4.1.4 ``` -------------------------------- ### Handle the Stream response Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of how to consume the stream response and collect data. ```javascript const rows = []; const ss = await broker.call("posts.findStream"); ss.on("data", row => rows.push(row)); ss.on("end", () => { console.log("Received all entities via stream:", rows) }); ``` -------------------------------- ### Create a single entity Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of creating a single post entity. ```javascript const post = await broker.call("posts.create", { title: "My first post", content: "Content of my first post..." }); ``` -------------------------------- ### Results for find Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of the results returned by the find action. ```javascript [ { id: "akTRSKTKzGCg9EMz", title: "Third post", content: "Content of my 3rd post...", votes: 0, status: false, createdAt: 1618077045354, }, { id: "0YZQR0oqyjKILaRn", title: "My second post", content: "Content of my second post...", votes: 3, status: true, createdAt: 1618077045352, } ] ``` -------------------------------- ### Raw update example Source: https://github.com/moleculerjs/database/blob/master/docs/adapters/Knex.md Example of using the `updateEntity` method with `{ raw: true }` options for raw updates, including $set and $inc operators. ```javascript const row = await this.updateEntity(ctx, { id: "YVdnh5oQCyEIRja0", $set: { status: false, height: 192 }, $inc: { age: 1 } }, { raw: true }); ``` -------------------------------- ### Install NeDB dependency Source: https://github.com/moleculerjs/database/blob/master/docs/adapters/NeDB.md Install the NeDB dependent library using npm. ```bash npm install @seald-io/nedb ``` -------------------------------- ### Example User-Defined Primary Key Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Shows how to define a primary key that is generated by the user, not the database. ```javascript { id: { type: "string", primaryKey: true, generated: "user", columnName: "_id" } } ``` -------------------------------- ### REST endpoint for list Source: https://github.com/moleculerjs/database/blob/master/docs/README.md GET /{serviceName}/ ```javascript GET /{serviceName}/ ``` -------------------------------- ### afterResolveEntities Hook Example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of how to use the `afterResolveEntities` hook in a Moleculer service to check entity statuses or permissions. ```javascript // posts.service.js { name: "posts", mixins: [DbService(/*...*/)], hooks: { customs: { async afterResolveEntities(ctx, id, rawEntity, params, opts) { // ... } } } } ``` -------------------------------- ### Connect to MySQL database Source: https://github.com/moleculerjs/database/blob/master/docs/adapters/Knex.md Example of connecting to a MySQL database using the Knex adapter. ```javascript // posts.service.js const DbService = require("@moleculer/database").Service; module.exports = { name: "posts", mixins: [DbService({ adapter: { type: "Knex", options: { knex: { client: "pg", connection: { host: "127.0.0.1", user: "root", password: "pass1234", database: "moleculer" } } } } })] } ``` -------------------------------- ### Results for list Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of the results returned by the list action, including pagination details. ```javascript { rows: [ { id: "2bUwg4Driim3wRhg", title: "Third post", content: "Content of my 3rd post...", votes: 0, status: false, createdAt: 1618077609105, }, { id: "Di5T8svHC9nT6MTj", title: "My second post", content: "Content of my second post...", votes: 3, status: true, createdAt: 1618077609103, }, { id: "YVdnh5oQCyEIRja0", title: "My first post", content: "Content of my first post...", votes: 0, status: true, createdAt: 1618077608593, }, ], total: 3, page: 1, pageSize: 10, totalPages: 1, } ``` -------------------------------- ### Connect to PostgreSQL database Source: https://github.com/moleculerjs/database/blob/master/docs/adapters/Knex.md Example of connecting to a PostgreSQL database using the Knex adapter. ```javascript // posts.service.js const DbService = require("@moleculer/database").Service; module.exports = { name: "posts", mixins: [DbService({ adapter: { type: "Knex", options: { knex: { client: "pg", connection: "postgres://postgres@localhost:5432/moleculer" } } } })] } ``` -------------------------------- ### Example Custom Column Name Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Shows how to map a field name to a different column name in the database. ```javascript { id: { type: "string", primaryKey: true, columnName: "_id" }, fullName: { type: "string", columnName: "full_name" } } ``` -------------------------------- ### Replace an entity Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of replacing an existing post entity. ```javascript const post = await broker.call("posts.update", { id: "YVdnh5oQCyEIRja0", title: "Replaced title", content: "Content of my first post...", votes: 10, status: true, createdAt: 1618077608593, updatedAt: 1618082167005 }); ``` -------------------------------- ### Raw update example Source: https://github.com/moleculerjs/database/blob/master/docs/adapters/MongoDB.md Example demonstrating how to perform a raw update using MongoDB update operators with the updateEntity method. ```javascript const row = await this.updateEntity(ctx, { id: "YVdnh5oQCyEIRja0", $set: { status: false, height: 192 }, $inc: { age: 1 }, $unset: { dob: true } }, { raw: true }); ``` -------------------------------- ### Connect to MSSQL database Source: https://github.com/moleculerjs/database/blob/master/docs/adapters/Knex.md Example of connecting to an MSSQL database using the Knex adapter. ```javascript // posts.service.js const DbService = require("@moleculer/database").Service; module.exports = { name: "posts", mixins: [DbService({ adapter: { type: "Knex", options: { knex: { client: "mssql", connection: { host: "127.0.0.1", port: 1433, user: "sa", password: "Moleculer@Pass1234", database: "moleculer", encrypt: false } } } } })] } ``` -------------------------------- ### Example Custom Column Type Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Illustrates how to specify a database-specific column type for a field. ```javascript { age: { type: "number", columnType: "integer" }, lastLogin: { type: "date", columnType: "datetime" }, createdAt: { type: "number", columnType: "bigInteger" } } ``` -------------------------------- ### Example for an array with objects Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Defines an array field 'phones' where each item is an object with phone details. ```javascript module.exports = { // ... settings: { fields: { phones: { type: "array", items: { type: "object", properties: { type: { type: "string" }, number: { type: "string", required: true }, primary: { type: "boolean", default: false } } } } } } }; ``` -------------------------------- ### Example Required Field Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Illustrates how to define a required field in the schema. ```javascript { title: { type: "string", required: true } } ``` -------------------------------- ### Update an entity Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of updating an existing post entity. ```javascript const post = await broker.call("posts.update", { id: "YVdnh5oQCyEIRja0", title: "Modified title", votes: 3 }); ``` -------------------------------- ### Example for string array Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Defines an array field 'roles' that accepts strings and has a maximum length of 3. ```javascript module.exports = { // ... settings: { fields: { roles: { type: "array", max: 3, items: { type: "string" } } } } }; ``` -------------------------------- ### Example Primary Key Field Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Defines a field as the primary key with a custom column name. ```javascript { id: { type: "string", primaryKey: true, columnName: "_id" } } ``` -------------------------------- ### Get an entity by ID with different primary key field example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Get an entity by ID using a different primary key field. ```javascript const post = await broker.call("posts.get", { key: "YVdnh5oQCyEIRja0" }); ``` -------------------------------- ### In-memory NeDB adapter usage Source: https://github.com/moleculerjs/database/blob/master/docs/adapters/NeDB.md Example of using the NeDB adapter in memory, which is the default configuration and requires no specific setup. ```javascript // posts.service.js const DbService = require("@moleculer/database").Service; module.exports = { name: "posts", mixins: [DbService()] } ``` -------------------------------- ### Connect to SQLite memory database Source: https://github.com/moleculerjs/database/blob/master/docs/adapters/Knex.md Example of connecting to an SQLite memory database using the Knex adapter. ```javascript // posts.service.js const DbService = require("@moleculer/database").Service; module.exports = { name: "posts", mixins: [DbService({ adapter: { type: "Knex", options: { knex: { client: "sqlite3", connection: { filename: ":memory:" }, useNullAsDefault: true } } } })] } ``` -------------------------------- ### Example with custom cache clearing event names Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Shows how to specify exact event names for cache clearing when dependencies change. ```javascript module.exports = { name: "posts", mixins: [DbService({ cacheCleanOnDeps: [ "user.created", "cache.clean.comments", "my.some.event" ] })], /* ... */ }; ``` -------------------------------- ### Custom validation function example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of a custom validation function for a field. ```javascript { username: { type: "string", validate: ({ value }) => /^[a-zA-Z0-9]+$/.test(value) || "Wrong input value" } } ``` -------------------------------- ### Hidden field examples Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Examples illustrating the use of the 'hidden' property for fields. ```javascript { name: { type: "string" }, password: { type: "string", min: 8, hidden: true }, createdAt: { type: "number", hidden: "byDefault" } } ``` ```javascript const res = broker.call("users.find", { fields: ["name", "password"] }) ``` ```javascript const res = broker.call("users.find", { fields: ["name", "createdAt", "password"] }) ``` -------------------------------- ### Populate Fields Example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Demonstrates various ways to configure field population in MoleculerJS services, including shorthand, parameterized, virtual fields, and custom handlers. ```javascript module.exports = { // ... settings: { fields: { // Shorthand populate, only set the action name. voters: { type: "array", items: "string", populate: "users.resolve" }, // Define the action name and the params. It will resolve the `username` and `fullName` of the author. author: { type: "string", populate: { action: "users.resolve", params: { fields: ["username", "fullName"] } } }, // In this case the ID is in the `reviewerID` field. // But we create a `reviewer` virtual field which contains the populated reviewer entity. reviewer: { type: "object", virtual: true, populate: { action: "users.resolve", keyField: "reviewerID", params: { fields: ["name", "email", "avatar"] }, callOptions: { timeout: 3000 } } }, // Custom populate handler function for a virtual field postCount: { type: "number", virtual: true, populate: (ctx, values, entities, field) => { return Promise.all( entities.map(async entity => entity.postCount = await ctx.call("posts.count", { query: { authorID: entity.id } }); ) ); } } }, // Default populates that are always populated defaultPopulates: ["author", "postCount"] } // ... } ``` -------------------------------- ### Example Secure ID using Hashids Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Demonstrates how to implement secure (encrypted) IDs using the hashids library. ```javascript const Hashids = require("hashids/cjs"); const hashids = new Hashids("this is my salt"); module.exports = { name: "posts", mixins: [DbService()], settings: { fields: { id: { type: "string", primaryKey: true, secure: true, columnName: "_id" }, // ... more fields } }, methods: { encodeID(id) { return id != null ? hashids.encodeHex(id) : id; }, decodeID(id) { return id != null ? hashids.decodeHex(id) : id; } } } ``` -------------------------------- ### Posts service example for cascade delete Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Demonstrates subscribing to the 'users.removed' event to implement cascade delete for posts associated with a deleted user. ```javascript module.exports = { name: "posts", mixins: [DbService(/*...*/)], settings: { fields: { id: { type: "string", primaryKey: true, columnName: "_id" }, title: { type: "string" }, content: { type: "string" }, author: { type: "string", required: true } } }, events: { async "users.removed"(ctx) { const user = ctx.params.data; const adapter = await this.getAdapter(ctx); await adapter.removeMany({ author: user.id }); this.logger.info(`The ${user.name} user's posts removed.`); } } }; ``` -------------------------------- ### Raw updating example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Shows how to perform a raw update on an entity using the `updateEntity` method with the `raw: true` option, allowing direct database client parameter passing. ```javascript const row = await this.updateEntity(ctx, { id: docs.johnDoe.id, $set: { status: false, height: 192 }, $inc: { age: 1 }, $unset: { dob: true } }, { raw: true }); ``` -------------------------------- ### Permissions Example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Illustrates how to define field-level read and write permissions in MoleculerJS services and implement the `checkFieldAuthority` method for custom authorization logic. ```javascript // users.service.js module.exports = { name: "users", mixins: [DbService(/*...*/)], settings: { fields: { id: { type: "string", primaryKey: true, columnName: "_id" }, name: { type: "string" }, // Only the administrators can receives this field in responses. email: { type: "email", readPermission: "admin" }, // Only the administrators can read & write this field. verified: { type: "boolean", permission: "admin" } } }, methods: { // If we defined the necessary permissions in the fields, we should write // the permission checking logic into the `checkFieldAuthority` method. async checkFieldAuthority(ctx, permission, params, field) { const roles = ctx.meta.user.roles || []; // Returns `true` if the logged in user's role field contains the required role. return roles.includes(permission); } } } ``` -------------------------------- ### Example: Fields for soft delete with onReplace hook Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Illustrates how to define fields for soft deletion using the onReplace hook. ```javascript { removeAt: { type: "number", readonly: true, onReplace: () => Date.now() }, removeBy: { type: "string", readonly: true, onReplace: ({ ctx }) => ctx.meta.user.id } } ``` -------------------------------- ### Delete an entity Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Example of deleting a post entity by ID. ```javascript const post = await broker.call("posts.delete", { id: "YVdnh5oQCyEIRja0" }); ``` -------------------------------- ### Resolve entities by multiple IDs example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Resolve entities based on multiple IDs. ```javascript const post = await broker.call("posts.resolve", { id: ["YVdnh5oQCyEIRja0", "Di5T8svHC9nT6MTj"] }); ``` -------------------------------- ### Resolve an entity by a single ID example Source: https://github.com/moleculerjs/database/blob/master/docs/README.md Resolve an entity based on a single ID. ```javascript const post = await broker.call("posts.resolve", { id: "YVdnh5oQCyEIRja0" }); ```