### Install Databases and Start Services (macOS) Source: https://github.com/cyjake/leoric/blob/master/docs/contributing/guides.md This snippet installs MySQL, PostgreSQL, and SQLite using Homebrew and then starts the MySQL and PostgreSQL services. It's a prerequisite for setting up the development environment. ```bash brew install mysql postgres sqlite brew service start mysql brew service start postgres ``` -------------------------------- ### Install egg-orm and Database Drivers Source: https://github.com/cyjake/leoric/blob/master/docs/setup/egg.md Installs the egg-orm plugin and necessary database drivers for common databases like MySQL, PostgreSQL, and SQLite. ```bash $ npm i --save egg-orm $ npm install --save mysql2 # MySQL or other compatible databases # other databases $ npm install --save pg # PostgreSQL $ npm install --save sqlite3 # SQLite ``` -------------------------------- ### Configure Leoric Database Connection Source: https://github.com/cyjake/leoric/blob/master/docs/starter.md Sets up a Leoric Realm instance for connecting to a MySQL database. It specifies connection details like host, user, database name, and directories for models and migrations. After configuration, it establishes the database connection. ```javascript const Realm = require('leoric'); const realm = new Realm({ host: 'localhost', user: 'portra', database: 'portra', models: 'app/models', migrations: 'database/migrations', }); await realm.connect(); ``` -------------------------------- ### Configure Multiple Leoric Data Sources in Midway Source: https://github.com/cyjake/leoric/blob/master/docs/setup/midway.md This configuration example shows how to set up and manage multiple distinct database data sources (e.g., 'main' and 'backup') for Leoric within a Midway application. It defines separate database files and model paths for each source, and specifies a default data source name. ```typescript // src/config/config.default.ts export default () => { return { leoric: { dataSource: { main: { dialect: 'sqlite', database: path.join(__dirname, '../../', 'database.sqlite'), models: [ 'models/*{.ts,.js}' ] }, backup: { dialect: 'sqlite', database: path.join(__dirname, '../../', 'backup.sqlite'), models: [ 'backup/models/*{.ts,.js}' ] }, }, defaultDataSourceName: 'main', }, }; } ``` -------------------------------- ### Initialize Leoric Realm with MySQL Source: https://github.com/cyjake/leoric/blob/master/docs/setup/mysql.md This snippet demonstrates the basic setup for connecting Leoric to a MySQL database. It requires `leoric` and `mysql` packages and establishes a connection using provided credentials. ```javascript const Realm = require('leoric'); const realm = new Realm({ host: 'localhost', user: 'test', database: 'test', models: 'app/models', }); await realm.connect(); ``` -------------------------------- ### Initialize Leoric with SQLite Source: https://github.com/cyjake/leoric/blob/master/docs/setup/sqlite.md This snippet shows the basic setup for Leoric to connect to an SQLite database. It requires the 'leoric' and 'sqlite3' packages to be installed. The configuration specifies the dialect, database file path, and the directory for models. The realm connection is established using await realm.connect(). ```javascript const Realm = require('leoric'); const realm = new Realm({ dialect: 'sqlite', database: 'database/development.sqlite3', models: 'app/models', }); await realm.connect(); ``` -------------------------------- ### Consume Models in Controller Source: https://github.com/cyjake/leoric/blob/master/docs/setup/egg.md Demonstrates how to fetch user data in an Egg.js controller using the defined 'User' model. It shows an example of querying users based on a condition involving another model. ```javascript // app/controller/home.js const { Controller } = require('egg'); module.exports = class HomeController extends Controller { async index() { const users = await ctx.model.User.find({ corpId: ctx.model.Corp.findOne({ name: 'tyrael' }), }); ctx.body = users; } }; ``` -------------------------------- ### Define Leoric Model and Basic Operations Source: https://github.com/cyjake/leoric/blob/master/docs/starter.md Illustrates how to define a Leoric model, specifically a User model, without explicit attribute definition, allowing Leoric to infer them from the database schema. It also shows basic CRUD operations: creating a user, finding the first user, updating a user's name, and removing a user. ```javascript const { Bone } = require('leoric'); module.exports = class User extends Bone { static initialize() { this.hasMany('books'); this.hasMany('comments'); } } // create user await User.create({ name: 'Stranger' }); // find the user just created const user = await User.first; assert.equal(user.name, 'Stranger'); // change the name of the user await user.update({ name: 'Tyrael' }); // remove user await user.remove(); ``` -------------------------------- ### Hook Setup API Source: https://github.com/cyjake/leoric/blob/master/docs/api/global.html Documentation for the `setupSingleHook` function, used to set up a hook on a target class. ```APIDOC ## POST /api/hooks/setup ### Description Sets up a hook on a specified target class for a given hook name and function. ### Method POST ### Endpoint /api/hooks/setup ### Parameters #### Request Body - **target** ([Bone](Bone.html)) - Required - The target class instance. - **hookName** (string) - Required - The name of the hook to set up. - **func** (function) - Required - The function to be executed as the hook. ### Request Example ```json { "target": "instance_of_bone_class", "hookName": "beforeSave", "func": "function_to_execute" } ``` ### Response #### Success Response (200) - **status** (string) - Indicates the success of the hook setup. #### Response Example ```json { "status": "hook_setup_successful" } ``` ``` -------------------------------- ### Add Leoric and MySQL Dependencies Source: https://github.com/cyjake/leoric/blob/master/docs/setup/mysql.md This is a package.json diff showing how to add `leoric` and `mysql` as project dependencies. These are essential for Leoric to interact with a MySQL database. ```diff diff --git a/package.json b/package.json index cf91c34..7ae144d 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,8 @@ "dependencies": { + "leoric": "^1.10.0", + "mysql": "^2.18.1", ``` ``` -------------------------------- ### Enable Sequelize Adapter Source: https://github.com/cyjake/leoric/blob/master/docs/setup/egg.md Activates the Sequelize adapter within egg-orm to facilitate migration from existing Sequelize models with minimal effort. ```javascript // config/config.default.js exports.orm = { client: 'mysql', sequelize: true, }; ``` -------------------------------- ### Inject Leoric Data Source using @InjectDataSource Source: https://github.com/cyjake/leoric/blob/master/docs/setup/midway.md This snippet demonstrates injecting a Leoric data source into a Midway service class using the @InjectDataSource decorator. It allows direct access to the data source for executing raw SQL queries, as shown with the 'realm.query' example. ```typescript // src/service/user.ts import { Provide } from '@midwayjs/core'; import { InjectDataSource, Realm } from '@midwayjs/leoric'; @Provide() export class UserService { @InjectDataSource() realm: Realm; async findAll() { const { rows, fields, ...etc } = this.realm.query('SELECT * FROM users'); return rows; } } ``` -------------------------------- ### Leoric Schema Dump Example Source: https://github.com/cyjake/leoric/blob/master/docs/migrations.md Presents an example of a schema dump file generated by Leoric after migrations. This file contains statements to recreate the database schema, including table definitions and constraints, but does not include data. ```javascript module.exports = async function createSchema(driver, DataTypes) { const { STRING, INTEGER, BIGINT, DATE } = DataTypes; await driver.dropTable('products'); await driver.createTable('products', { id: { type: BIGINT, primaryKey: true }, name: STRING, price: INTEGER, createdAt: DATE, updatedAt: DATE, }); // other tables } ``` -------------------------------- ### Customize SQLite Client in Leoric Source: https://github.com/cyjake/leoric/blob/master/docs/setup/sqlite.md This example demonstrates how to specify a custom client for Leoric when using SQLite, such as '@journeyapps/sqlcipher' for encrypted databases. Ensure the custom client is installed as a dependency. The configuration remains similar, but the 'client' option is added. ```javascript const realm = new Realm({ client: '@journeyapps/sqlcipher', dialect: 'sqlite', database: 'database/development.sqlite3', models: 'app/models', }); ``` -------------------------------- ### Configure Database Connection Source: https://github.com/cyjake/leoric/blob/master/docs/setup/egg.md Sets up the default database connection details for egg-orm, including the client type, database name, host, and the directory where models are located. ```javascript // config/config.default.js exports.orm = { client: 'mysql', database: 'temp', host: 'localhost', baseDir: 'app/model', }; ``` -------------------------------- ### Result Dispatching Examples in JavaScript Source: https://github.com/cyjake/leoric/blob/master/docs/updates/_posts/2021-10-31-v1.14.md Provides JavaScript examples demonstrating Leoric's result dispatching strategies for various query types. It covers scenarios with `GROUP BY`, aggregate functions, single-row results, and standard queries, illustrating the return types like `Collection` and `ResultSet`. ```javascript const count = await User.count(); const age = await User.average('age'); ``` ```javascript const users = await User.findAll(); // Collection const averageHeights = await User.average('height').group('sex'); // ResultSet<{ sex, height }> const generations = await User.select('DISTINCT YEAR(birthday) AS year'); // ResultSet<{ year }> ``` -------------------------------- ### Run Project Tests with npm Source: https://github.com/cyjake/leoric/blob/master/docs/contributing/guides.md These commands demonstrate how to install project dependencies and run different types of tests using npm scripts. This includes general tests, unit tests, integration tests, and TypeScript definition tests. ```bash npm install npm run test npm run test:unit npm run test:integration npm run test:dts ``` -------------------------------- ### Example Query Conditions Source: https://github.com/cyjake/leoric/blob/master/docs/api/global.html Illustrates various ways to define query conditions using different operators like $gt, $between, $like, $or, and $not. These examples showcase the flexibility in constructing query filters for data retrieval. ```javascript { foo: null } { foo: { $gt: new Date(2012, 4, 15) } } { foo: { $between: [1, 10] } } { foo: { $or: ['Leah', { $like: '%Leah%' }] } } { foo: [1, 2, 3] } { foo: { $not: { $gt: '2021-01-01', $lte: '2021-12-31' } } } { foo: [ '2021-09-30', { $gte: '2021-10-07' } ] } { foo: [ 'Leah', 'Nephalem' ] } { $or: { title: 'Leah', content: 'Diablo' } } { $or: [ { title: 'Leah', content: 'Diablo' }, { title: 'Stranger' } ] } ``` -------------------------------- ### Leoric Model Initialization Setup Source: https://github.com/cyjake/leoric/blob/master/docs/api/Bone.html Override this method to set up associations, rename attributes, and perform other initialization tasks for the model. Example shows defining a 'comments' association and renaming the 'content' attribute to 'body'. ```javascript class Post extends Bone { static didLoad() { this.belongsTo('author', { className: 'User' }) this.renameAttribute('content', 'body') } } ``` -------------------------------- ### Configure Leoric with PostgreSQL Source: https://github.com/cyjake/leoric/blob/master/docs/setup/postgres.md This JavaScript snippet demonstrates how to initialize Leoric with PostgreSQL. It requires the 'leoric' package and specifies connection details such as dialect, host, user, database, and model path. The `realm.connect()` method establishes the database connection. ```javascript const Realm = require('leoric'); const realm = new Realm({ dialect: 'postgres', host: 'localhost', user: 'test', database: 'test', models: 'app/models', }); await realm.connect(); ``` -------------------------------- ### Model Definition Example Source: https://github.com/cyjake/leoric/blob/master/docs/api/Bone.html Demonstrates how to define a model extending Bone and setting up associations and attributes. ```APIDOC ## Model Definition Example ### Description This example shows how to create a `Post` model that extends the `Bone` class, defining one-to-many and many-to-one relationships, and an attribute with JSON type. ### Method N/A (This is a class definition example) ### Endpoint N/A ### Parameters N/A ### Request Example ```javascript class Post extends Bone { static initialize() { this.hasMany('comments'); this.belongsTo('author', { className: 'User' }); this.attribute('extra', { type: JSON }); } } ``` ### Response N/A ``` -------------------------------- ### Inject Leoric Model using @InjectModel Decorator Source: https://github.com/cyjake/leoric/blob/master/docs/setup/midway.md This example shows how to inject a Leoric model, specifically the 'User' model, into a service class in Midway using the @InjectModel decorator. This is useful for performing data operations within services. ```typescript // src/service/user.ts import { Provide } from '@midwayjs/core'; import { InjectModel } from '@midwayjs/leoric'; import User from '../model/user'; @Provide() export class UserService { @InjectModel(User) User: typeof User; } ``` -------------------------------- ### Configure Leoric Realm for PolarDB Source: https://github.com/cyjake/leoric/blob/master/docs/setup/mysql.md This example shows how to configure Leoric for PolarDB, a MySQL-compliant cloud database. It highlights the use of `appName` for routing tables, which might differ from the local database name. ```javascript const realm = new Realm({ host: 'polardb.host', user: 'FOO_APP', appName: 'FOO_APP', database: 'foo', }); ``` -------------------------------- ### Add Leoric and SQLite3 Dependencies Source: https://github.com/cyjake/leoric/blob/master/docs/setup/sqlite.md This diff shows the necessary additions to a package.json file to include Leoric and sqlite3 as project dependencies. These packages are required for Leoric to interact with an SQLite database. ```diff diff --git a/package.json b/package.json index cf91c34..7ae144d 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,8 @@ "dependencies": { + "leoric": "^1.10.0", + "sqlite3": "^5.0.2", ``` -------------------------------- ### Add PostgreSQL Dependencies to package.json Source: https://github.com/cyjake/leoric/blob/master/docs/setup/postgres.md This `diff` snippet shows how to add the 'leoric' and 'pg' packages to your project's `package.json` file. 'pg' is the default client for PostgreSQL, and 'leoric' is the ORM itself. Ensure these are listed under `dependencies` for your project to function correctly. ```diff diff --git a/package.json b/package.json index cf91c34..7ae144d 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,8 @@ "dependencies": { + "leoric": "^1.10.0", + "pg": "^8.5.1", ``` -------------------------------- ### Define User Model (Class Syntax) Source: https://github.com/cyjake/leoric/blob/master/docs/setup/egg.md Defines a 'User' model using modern class syntax, extending Leoric's Bone class. This approach offers a more declarative way to define models and their attributes. ```javascript // app/model/user.js module.exports = function(app) { const { Bone } = app.model; const { STRING } = app.model.DataTypes; return class User extends Bone { static table = 'users' static attributes = { name: STRING, password: STRING, avatar: STRING(2048), } }; } ``` -------------------------------- ### Setup Hook to Class Source: https://github.com/cyjake/leoric/blob/master/docs/api/global.html This function, `setupSingleHook`, allows you to set up a hook on a target class. It takes the target class, the name of the hook, and the function to be executed as the hook. This enables extending or modifying class behavior. ```javascript setupSingleHook(target, hookName, func) ``` -------------------------------- ### Configure Custom Model Directory Source: https://github.com/cyjake/leoric/blob/master/docs/setup/egg.md Allows overriding the default model directory (`app/model`) by specifying a custom path using the `opts.baseDir` configuration option. ```javascript // config/config.default.js exports.orm = { baseDir: 'app/bone', }; ``` -------------------------------- ### Configure Leoric Database Connection Source: https://github.com/cyjake/leoric/blob/master/docs/setup/midway.md This snippet demonstrates how to configure the database connection for Leoric within a Midway application's default configuration file. It specifies the dialect, database path, synchronization, and model locations. Ensure the 'path' module is available for 'path.join'. ```typescript // src/config/config.default.ts export default () => { return { leoric: { dataSource: { default: { dialect: 'sqlite', database: path.join(__dirname, '../../', 'database.sqlite'), sync: true, models: [ '**/models/*{.ts,.js}' ] }, }, }, } } ``` -------------------------------- ### Inject Specific Leoric Model and Data Source by Name Source: https://github.com/cyjake/leoric/blob/master/docs/setup/midway.md This Midway controller code demonstrates how to inject a specific Leoric model ('User') and data source ('backup') using their names when multiple data sources are configured. This allows for targeted database operations on a particular data source. ```typescript // src/controller/user.ts import { Controller, Get } from '@midwayjs/core'; import Realm, { InjectDataSource, InjectModel } from '@midwayjs/leoric'; import User from '../model/user'; @Controller('/api/users') export class UserController { @InjectModel(User, 'backup') User: typeof User; @InjectDataSource('backup') backupRealm: Realm @Get('') async index() { const users = await this.User.find(); return users.toJSON(); } } ``` -------------------------------- ### Define User Model (Standard JS) Source: https://github.com/cyjake/leoric/blob/master/docs/setup/egg.md Defines a 'User' model using standard JavaScript syntax within the Egg.js application structure. It specifies table columns and their data types. ```javascript // app/model/user.js module.exports = function(app) { const { STRING } = app.model.DataTypes; return app.model.define('User', { name: STRING, password: STRING, avatar: STRING(2048), }, { tableName: 'users', }); } ``` -------------------------------- ### Activate Leoric Component in Midway Source: https://github.com/cyjake/leoric/blob/master/docs/setup/midway.md This TypeScript code snippet shows how to activate the Leoric component within a Midway application by importing and including it in the Configuration decorator. It's a fundamental step for enabling Leoric's ORM functionalities. ```typescript // src/configuration.ts import { Configuration, ILifeCycle } from '@midwayjs/core'; import * as leoric from '@midwayjs/leoric'; @Configuration({ imports: [ leoric, ], }) export class ContainerLifeCycle implements ILifeCycle {} ``` -------------------------------- ### Leoric TypeScript Example Source: https://github.com/cyjake/leoric/blob/master/docs/updates/_posts/2021-09-30-v1.11.md Provides an example of using Leoric with TypeScript, demonstrating model definition, data creation, updates, and basic querying. This showcases the improved TypeScript definition types available in v1. ```typescript import * as assert from 'assert'; import Realm, { Bone, DataTypes } from '../../../types/index'; const { STRING, DATE } = DataTypes; class User extends Bone { static attributes = { name: STRING, created_at: DATE, updated_at: DATE, } } async function main() { const userBone = await User.create({ name: 'Stranger' }); assert.strictEqual(userBone.toJSON().name, userBone.toObject().name); const user = await User.first; await user.update({ name: 'Tyrael' }); const realm = new Realm({ dialect: 'sqlite', database: '/tmp/leoric.sqlite3', }); await realm.query('SELECT * FROM sqlite_master'); } main().catch(err => console.error(err)) ``` -------------------------------- ### Example Data Creation - JavaScript Source: https://github.com/cyjake/leoric/blob/master/docs/updates/_posts/2021-11-30-v1.15.md This snippet demonstrates how to use `bulkCreate` to populate `Post` and `Comment` models with sample data, including associated IDs, which is relevant for testing JOIN query functionalities. ```javascript await Post.bulkCreate([ { id: 2, title: 'Archbishop Lazarus' }, { id: 3, title: 'Archangel Tyrael' }, ]); await Comment.bulkCreate([ { articleId: 2, content: 'foo' }, { articleId: 2, content: 'bar' }, { articleId: 3, content: 'baz' }, ]); ``` -------------------------------- ### Enable egg-orm Plugin Source: https://github.com/cyjake/leoric/blob/master/docs/setup/egg.md Configuration snippet to enable the egg-orm plugin within an Egg.js application by setting its 'enable' property to true in the plugin configuration. ```javascript // config/plugin.js exports.orm = { enable: true, package: 'egg-orm', }; ``` -------------------------------- ### Configure Custom Delegate Property Source: https://github.com/cyjake/leoric/blob/master/docs/setup/egg.md Enables changing the property name used to access Leoric models from the default `app.model` and `ctx.model` to a custom name, such as `app.bone` and `ctx.bone`, using `opts.delegate`. ```javascript // config/config.default.js exports.orm = { delegate: 'bone', }; // Now we can access egg-orm from app.bone and ctx.bone. ``` -------------------------------- ### Grouping and Counting Results in JavaScript Source: https://github.com/cyjake/leoric/blob/master/docs/zh/querying.md Explains how to use `.group()` and `.count()` methods for data aggregation in Leoric ORM. This example shows how to find the number of posts per day and sort the results. ```javascript Post.group('DATE(createdAt)').count().order('count desc') // => SELECT COUNT(*) as count, DATE(created_at) FROM posts GROUP BY DATE(created_at) ORDER BY count DESC; ``` -------------------------------- ### Method Chaining Example with Spell Class Source: https://github.com/cyjake/leoric/blob/master/docs/api/Spell.html Demonstrates how to use the Spell class for constructing SQL queries with method chaining. Each method call returns a new instance, allowing for independent query modifications. ```javascript const query = Post.find('createdAt > ?', new Date(2012, 4, 15)); const [ { count } ] = query.count(); const posts = query.offset(page * pageSize).limit(pageSize); this.body = { count, posts } ``` -------------------------------- ### Spell Class $forceIndex Method Example Source: https://github.com/cyjake/leoric/blob/master/docs/api/Spell.html Illustrates the usage of the $forceIndex method to specify index hints for a query. Multiple index hints can be provided, and they can include ordering or grouping clauses. ```javascript .forceIndex('idx_id') .forceIndex('idx_id', 'idx_title_id') .forceIndex('idx_id', { orderBy: ['idx_title', 'idx_org_id'] }, { groupBy: 'idx_type' }) ``` -------------------------------- ### Inject and Use Leoric Model in Midway Controller Source: https://github.com/cyjake/leoric/blob/master/docs/setup/midway.md This TypeScript code illustrates how to inject a Leoric model into a Midway controller using the @InjectModel decorator and then perform database operations like querying. It assumes the 'User' model is defined and configured. ```typescript // src/controller/user.ts import { Controller } from '@midwayjs/core'; import { InjectModel } from '@midwayjs/leoric'; import User from '../model/user'; @Controller('/api/users') export class UserController { @InjectModel(User) User: typeof User; @Get('/') async index() { return await this.User.order('id', 'desc').limit(10); } } ``` -------------------------------- ### Start a Find Query with 'find' Source: https://github.com/cyjake/leoric/blob/master/docs/api/Bone.html Demonstrates initiating a database query using the static 'find' method. This method returns a Spell instance, allowing for further query building. Conditions and values are passed to the Spell's 'where' clause. ```javascript Post.find('title = ?', 'Leah') ``` -------------------------------- ### Create and Query Shop Instances Source: https://github.com/cyjake/leoric/blob/master/docs/basics.md This JavaScript snippet demonstrates how to create a new Shop instance and save it, or use the static 'create' method for the same purpose. It assumes the Shop model is already defined and connected. ```javascript const shop = new Shop({ name: 'Horadric Cube' }) await shop.save() // or simply await Shop.create({ name: 'Horadric Cube' }) ``` -------------------------------- ### Serve Documentation Locally with Jekyll Source: https://github.com/cyjake/leoric/blob/master/docs/contributing/guides.md This bash command navigates to the docs directory and then serves the documentation locally using `jekyll serve`. It also shows the typical output, including the server address and regeneration status, indicating the documentation is available at http://127.0.0.1:4000/. ```bash cd docs je_yll serve ``` -------------------------------- ### 本地构建和启动 Jekyll 站点 (Bash) Source: https://github.com/cyjake/leoric/blob/master/docs/zh/contributing/guides.md 在 Leoric 项目的 `docs` 目录下,使用 `jekyll serve` 命令启动本地 Jekyll 开发服务器。该命令会构建站点并提供一个本地预览地址。 ```bash cd docs jeekyll serve ``` -------------------------------- ### Spell Class $optimizerHints Method Example Source: https://github.com/cyjake/leoric/blob/master/docs/api/Spell.html Shows how to add optimizer hints to a query using the $optimizerHints method. These hints can influence the query execution plan, such as disabling foreign key checks or setting execution time limits. ```javascript .optimizerHints('SET_VAR(foreign_key_checks=OFF)') .optimizerHints('SET_VAR(foreign_key_checks=OFF)', 'MAX_EXECUTION_TIME(1000)') ``` -------------------------------- ### Configure SQLite Busy Timeout in Leoric Source: https://github.com/cyjake/leoric/blob/master/docs/setup/sqlite.md This example illustrates setting the 'busyTimeout' option in Leoric for SQLite connections. This value, in milliseconds, determines how long the database will wait when it's locked before returning a 'SQLITE_BUSY' error. The default is 30000ms. ```javascript const realm = new Realm({ dialect: 'sqlite', database: 'database/development.sqlite3', models: 'app/models', busyTimeout: 30000, }); ``` -------------------------------- ### Equivalent SQL for Creating 'products' Table Source: https://github.com/cyjake/leoric/blob/master/docs/migrations.md This SQL statement demonstrates the equivalent database command for creating the 'products' table as defined in the JavaScript migration. It shows the direct mapping of Leoric's schema definition to SQL syntax. ```sql CREATE TABLE `products` ( `id` BIGINT PRIMARY KEY, `category_id` BIGINT, `name` VARCHAR(255), `price` INT, ); ``` -------------------------------- ### Filter Test Execution with npm and Selectively Run Tests Source: https://github.com/cyjake/leoric/blob/master/docs/contributing/guides.md This section shows how to filter test execution using the `--grep` flag with npm test commands, allowing for more specific test runs. It also includes an example of using `.only` within a test file to focus on a particular test case, emphasizing that these should be removed before committing. ```bash npm run test -- test/unit/test.connect.js --grep "should work" npm run test:unit --grep "=> Sequelize adapter" npm run test:mysql --grep "bone.toJSON()" ``` -------------------------------- ### Initialize Leoric with Sequelize Adapter Source: https://github.com/cyjake/leoric/blob/master/docs/sequelize.md This snippet demonstrates how to enable the Sequelize adapter in Leoric by setting the 'sequelize' option to true. It then connects to the database. ```javascript const Realm = require('leoric'); const realm = new Realm({ sequelize: true, // turn on sequelize adapter host: 'localhost', }); await realm.connect(); ``` -------------------------------- ### Spell Class $join Method Example Source: https://github.com/cyjake/leoric/blob/master/docs/api/Spell.html Provides an example of using the $join method for performing LEFT JOIN operations between models. It requires the model to join, the on-conditions, and optionally additional values. ```javascript .join(User, 'users.id = posts.authorId'); .join(TagMap, 'tagMaps.targetId = posts.id and tagMaps.targetType = 0') ``` -------------------------------- ### Spell#$get(index) with LIMIT in Leoric Source: https://github.com/cyjake/leoric/blob/master/History.md Fixes the `Spell#$get(index)` method when used with a `LIMIT` clause in Leoric. This ensures that retrieving specific results by index works correctly even when the query is limited. ```javascript // Spell#$get(index) with LIMIT clause ``` -------------------------------- ### Define Basic Table Creation Migration (JavaScript) Source: https://github.com/cyjake/leoric/blob/master/docs/migrations.md This migration defines the `up` and `down` methods to create and drop a 'products' table. The `up` method creates the table with 'id', 'name', and 'description' columns. The `down` method drops the table. It uses Leoric's driver and DataTypes for schema definition. ```javascript module.exports = { async up(driver, DataTypes) { const { BIGINT, STRING, TEXT } = DataTypes; await driver.createTable('products', { id: { type: BIGINT, primaryKey: true }, name: STRING, description: TEXT, }); }, async down(driver, DataTypes) { await driver.dropTable('products'); }, } ``` -------------------------------- ### Create Records using Sequelize Adapter Source: https://github.com/cyjake/leoric/blob/master/docs/sequelize.md Shows three common methods for inserting data into the database using Leoric's Sequelize adapter: single create, bulk create, and instance save. ```javascript await Shop.create({ name: 'MILL' }); await Shop.bulkCreate([ { name: 'wagas' }, { name: 'family mart' }, ]); await (new Shop({ name: "McDonald's" })).save(); ``` -------------------------------- ### Query and Find Records with Leoric Source: https://context7.com/cyjake/leoric/llms.txt Details Leoric's methods for querying records from the database. Includes finding by primary key (`findOne`), with specific conditions (`findOne`, `find`), retrieving all records (`all`, `find()`), getting the first or last record (`first`, `last`), and accessing records by index (`get`). Returns `null` if a record is not found. ```javascript // Find by primary key const post = await Post.findOne(42); console.log(post.title); // => 'New Post' // Find with conditions const post = await Post.findOne({ title: 'New Post' }); const posts = await Post.find({ authorId: 1 }); // Find all records const allPosts = await Post.all; const allPosts2 = await Post.find(); // Same as above // First and last const firstPost = await Post.first; const lastPost = await Post.last; // Get by index const secondPost = await Post.get(1); // OFFSET 1 LIMIT 1 // Find returns null if not found const missing = await Post.findOne({ title: 'NonExistent' }); console.log(missing); // => null ``` -------------------------------- ### 安装 egg-orm 和数据库驱动 Source: https://github.com/cyjake/leoric/blob/master/docs/zh/setup/egg.md 此代码片段展示了如何使用 npm 安装 egg-orm 插件及其支持的数据库驱动,如 MySQL、PostgreSQL 和 SQLite。需要根据项目需求选择相应的数据库驱动进行安装。 ```bash $ npm i --save egg-orm $ npm install --save mysql2 # MySQL 或者其他兼容 MySQL 的数据库 # 其他数据库类型 $ npm install --save pg # PostgreSQL $ npm install --save sqlite3 # SQLite ``` -------------------------------- ### Bone Constructor Source: https://github.com/cyjake/leoric/blob/master/docs/api/Bone.html Details on how to instantiate the Bone class with initial data. ```APIDOC ## Constructor: new Bone(dataValues) ### Description Creates an instance of Bone, optionally accepting an object with initial data values to set on the model instance. ### Method `new` (Constructor) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```javascript // Create a new post instance without initial data const post = new Post(); // Create a new post instance with initial data const post = new Post({ title: 'Leah' }); ``` ### Response N/A ### Properties - `#raw` (Object) - The raw data values of the model. - `#rawSaved` (Object) - The raw data values when the model was last saved. - `#rawPrevious` (Object) - The raw data values from the previous state. - `#rawUnset` (Set) - A set of attribute names that have been unset. - `isNewRecord` (Boolean) - Flag indicating if the record is new and has not been saved to the database yet. ``` -------------------------------- ### Spell Class $having Method Example Source: https://github.com/cyjake/leoric/blob/master/docs/api/Spell.html Demonstrates how to apply HAVING conditions to filter grouped query results. Conditions can be specified as strings with placeholders or as objects. ```javascript .having('average between ? and ?', 10, 20); .having('maximum > 42'); .having({ count: 5 }) ``` -------------------------------- ### Leoric BulkCreate Hooks (JavaScript) Source: https://github.com/cyjake/leoric/blob/master/docs/hooks.md Explains the beforeBulkCreate and afterBulkCreate hooks, specifying their arguments and the context in which they are called. ```javascript // bulkCreate hooks Model.beforeBulkCreate(records, queryOptions) // function's context is the Model Model.afterBulkCreate(instances, Model) // the argument 'instances' are instances to be created ``` -------------------------------- ### MongoDB Upsert Example Source: https://github.com/cyjake/leoric/blob/master/docs/zh/querying.md Illustrates the MongoDB `db.collection.update({ upsert: true })` command, which is used to update an existing document or insert a new one if no match is found. ```javascript db.collection.update({ upsert: true }) ``` -------------------------------- ### Filtering Grouped Results with HAVING in JavaScript Source: https://github.com/cyjake/leoric/blob/master/docs/zh/querying.md Shows how to use the `.having()` clause to filter results after aggregation in Leoric ORM. This example filters days with less than 5 posts. ```javascript Post.group('DATE(createdAt)').count().order('count desc').having('count < 5') // => SELECT COUNT(*) as count, DATE(created_at) FROM posts GROUP BY DATE(created_at) HAVING count < 5 ORDER BY count DESC; ``` -------------------------------- ### MySQL Connection Error Example Source: https://github.com/cyjake/leoric/blob/master/Readme.md Illustrates the typical 'ECONNREFUSED' error encountered when a MySQL client tries to connect to an IPv6 localhost address that the MySQL server is not listening on. ```javascript Error: connect ECONNREFUSED ::1:3306 at __node_internal_captureLargerStackTrace (node:internal/errors:490:5) at __node_internal_exceptionWithHostPort (node:internal/errors:668:12) at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1494:16) ``` -------------------------------- ### 配置多数据源 - Leoric - TypeScript Source: https://github.com/cyjake/leoric/blob/master/docs/zh/setup/midway.md 配置 Leoric 以支持多个数据源。在 `src/config/config.default.ts` 中,可以在 `leoric.dataSource` 下定义多个数据源(例如 'main' 和 'backup'),并分别指定其连接信息和模型路径。`defaultDataSourceName` 用于设置默认数据源。 ```typescript // src/config/config.default.ts export default () => { return { leoric: { dataSource: { main: { dialect: 'sqlite', database: path.join(__dirname, '../../', 'database.sqlite'), models: [ 'models/*{.ts,.js}' ] }, backup: { dialect: 'sqlite', database: path.join(__dirname, '../../', 'backup.sqlite'), models: [ 'backup/models/*{.ts,.js}' ] }, }, // 如果想要在 @InjectModel() 时省略数据源名称,那就需要在这里指定缺省值 defaultDataSourceName: 'main', }, }; } ``` -------------------------------- ### Count Related Records Source: https://github.com/cyjake/leoric/blob/master/docs/zh/querying.md This function allows counting related records. The example shows how to count the 'items' associated with a specific 'Shop'. The generated SQL illustrates the join operation. ```javascript Shop.find(1).with('items').count('items.*') ``` -------------------------------- ### Logger for SQL and Errors in Leoric (v1.0.0) Source: https://github.com/cyjake/leoric/blob/master/History.md Introduces basic logging for SQL queries and errors in Leoric starting from version 1.0.0. The `logger.logQuery` and `logger.logQueryError` functions help in monitoring database interactions. ```javascript logger.logQuery(sql, duration); logger.logQueryError(sql, err); ``` -------------------------------- ### Limit and Offset for Pagination Source: https://github.com/cyjake/leoric/blob/master/docs/querying.md Demonstrates how to use 'limit' and 'offset' to implement pagination, fetching specific ranges of records, such as the most recently updated posts. ```javascript const posts = await Post.order('updatedAt desc').limit(20) ``` ```javascript const posts = await Post.order('updatedAt desc').limit(20).offset(20) ``` ```sql SELECT * FROM posts ORDER BY updated_at DESC LIMIT 20 OFFSET 20; ``` -------------------------------- ### Define Associations in Model (JavaScript) Source: https://github.com/cyjake/leoric/blob/master/docs/querying.md Defines associations like 'hasMany' and 'belongsTo' within a Leoric model's describe method. This setup is necessary for using predefined joins. ```javascript class Post extends Bone { static initialize() { this.hasMany('comments') this.belongsTo('author', { foreignKey: 'authorId', Model: 'User' }) } } ``` -------------------------------- ### Running Migrations with Leoric Source: https://github.com/cyjake/leoric/blob/master/docs/migrations.md Demonstrates how to execute all pending migrations using Leoric's `realm.migrate()` method. This command iterates through migration files and applies the `up()` method for each one that hasn't been executed. ```javascript const Realm = require('leoric'); const realm = new Realm(); await realm.migrate(); ``` -------------------------------- ### Override Attribute Metadata with 'attribute' Method Source: https://github.com/cyjake/leoric/blob/master/docs/api/Bone.html Provides an example of overriding or defining attribute metadata for a model. Specifically, it shows how to set the 'type' for an attribute, such as 'extra' to JSON. ```javascript class Post extends Bone { static initialize() { Post.attribute('extra', { type: JSON }) } } ``` -------------------------------- ### STRING Class Source: https://github.com/cyjake/leoric/blob/master/docs/api/STRING.html Documentation for the STRING class, including its constructor and parameters. ```APIDOC ## STRING Class ### Description Documentation for the STRING class. ### Constructor #### new STRING(dataLength) ##### Parameters: | Name | Type | Description | |------------|--------|-------------| | `dataLength` | `number` | | ``` -------------------------------- ### Limiting and Offsetting Query Results in JavaScript Source: https://github.com/cyjake/leoric/blob/master/docs/zh/querying.md Demonstrates the use of `.limit()` and `.offset()` methods for pagination in Leoric ORM. These methods control the number of records returned and the starting point of the result set. ```javascript const posts = await Post.order('updatedAt desc').limit(20) const posts = await Post.order('updatedAt desc').limit(20).offset(20) // => SELECT * FROM posts ORDER BY updated_at DESC LIMIT 20 OFFSET 20; ``` -------------------------------- ### Allow connect({ model }) and connect({ models }) in Leoric Source: https://github.com/cyjake/leoric/blob/master/History.md Enhances Leoric's `connect` method to accept both a single `model` object and an array of `models`. This provides flexibility in how models are provided during the connection setup. ```javascript connect({ model: MyModel }); connect({ models: [ModelA, ModelB] }); ``` -------------------------------- ### Leoric Method Chaining with Promises and Async/Await Source: https://github.com/cyjake/leoric/blob/master/docs/querying.md Demonstrates how to build and execute database queries using Leoric's method chaining. Supports traditional Promises and modern async/await syntax. SQL is generated upon execution. ```javascript const spell = Post.find() sspell .then(posts => { ... }) .catch(err => console.error(err.stacak)) ``` ```javascript co(function* () { const posts = yield Post.find() }) ``` ```javascript async function() { const posts = await Post.find() } ``` ```javascript const query = Post.where('title LIKE ?', '%Post%') const posts = await query.order('updatedAt desc').limit(10) const [{ count }] = await query.count() this.body = { posts, count } ``` -------------------------------- ### Spell Class $group Method Example Source: https://github.com/cyjake/leoric/blob/master/docs/api/Spell.html Shows how to use the $group method to group query results by specified attributes. It supports aliasing for grouped columns, allowing for cleaner syntax. ```javascript .select('YEAR(createdAt)) AS year').group('year'); .group('city'); .group('YEAR(createdAt)') ``` -------------------------------- ### Querying Posts Using Bone Class Methods Source: https://github.com/cyjake/leoric/blob/master/docs/api/Bone.html Illustrates various ways to query 'Post' model instances using static methods provided by the Bone class. This includes fetching the first record, filtering by conditions, and performing complex queries with includes, grouping, and ordering. ```javascript Post.first Post.where('title = ? && authorId = ?', 'Leah', 42) Post.include('comments').group('posts.id').count('comments.*').order('count') ``` -------------------------------- ### 自定义 egg-orm 模型文件加载目录 Source: https://github.com/cyjake/leoric/blob/master/docs/zh/setup/egg.md 此代码展示了如何在 `config/config.default.js` 中使用 `opts.baseDir` 配置项来自定义 egg-orm 模型文件的加载目录,而不是使用默认的 `app/model`。 ```javascript // config/config.default.js exports.orm = { bsaeDir: 'app/bone', }; ``` -------------------------------- ### PostgreSQL ON CONFLICT Example Source: https://github.com/cyjake/leoric/blob/master/docs/zh/querying.md Shows the PostgreSQL `INSERT ... ON CONFLICT ... DO UPDATE` syntax, which allows for inserting a new row or updating an existing one if a unique constraint violation occurs. ```sql INSERT INTO ... ON CONFLICT ... DO UPDATE ``` -------------------------------- ### Leoric Create Hooks (JavaScript) Source: https://github.com/cyjake/leoric/blob/master/docs/hooks.md Illustrates the usage of beforeCreate and afterCreate hooks for both Model class and instance calls. It highlights that the context for these hooks is the instance being created. ```javascript // create hooks, args are create function's arguments Model.beforeCreate(args) // function's context is the instance to be created Model.afterCreate(instance, createResult) // createResult is create function's returns instance.beforeCreate(args) instance.afterCreate(instance, createResult) // function's context is the instance to be created ``` -------------------------------- ### Soft Delete Scope Example (SQL) Source: https://github.com/cyjake/leoric/blob/master/docs/querying.md Illustrates the default scope behavior for soft deletes in Leoric. When a model has a 'deletedAt' attribute, queries implicitly filter out records where 'deletedAt' is not null. ```sql SELECT * FROM posts WHERE deleted_at IS NULL; ``` ```sql SELECT * FROM posts WHERE deleted_at IS NOT NULL; ``` -------------------------------- ### Leoric Schema Migration with Model Definitions (Node.js) Source: https://github.com/cyjake/leoric/blob/master/docs/api/index.html This example illustrates how Leoric can be used for database schema migration. Models are defined with their attributes and data types, and then a `Realm` is used to synchronize the schema with the database. ```javascript const { Bone, connect } = require('leoric') const { BIGINT, STRING } = Bone.DataTypes; class Post extends Bone { static attributes = { id: { type: BIGINT, primaryKey: true }, email: { type: STRING, allowNull: false }, nickname: { type: STRING, allowNull: false }, } } const realm = new Realm({ models: [ Post ] }); await realm.sync(); ``` -------------------------------- ### Create a New Migration File (JavaScript) Source: https://github.com/cyjake/leoric/blob/master/docs/migrations.md This snippet shows how to programmatically create a new migration file using Leoric's `createMigrationFile` method. It initializes a Realm instance and then calls the method with a desired migration name. The output is a timestamped migration file. ```javascript const Realm = require('leoric'); const realm = new Realm({ client: 'mysql', migrations: 'database/migrations', }); await realm.createMigrationFile('create-products'); // which creates migration file like 20210621170235-create-products.js in database/migrations ``` -------------------------------- ### Define Migration for Creating 'products' Table (JavaScript) Source: https://github.com/cyjake/leoric/blob/master/docs/migrations.md This migration defines the `up` method to create a 'products' table with specified columns: 'id', 'category_id', 'name', and 'price'. It utilizes Leoric's DataTypes for defining column types and constraints like primary key. ```javascript module.exports = { async up(driver, DataTypes) { const { STRING, BIGINT, INTEGER } = DataTypes; await driver.createTable('products', { id: { type: BIGINT, primary: true }, category_id: { type: BIGINT }, name: STRING, price: INTEGER, }); }, }; ``` -------------------------------- ### Enable Stringifying Objects for MySQL Queries Source: https://github.com/cyjake/leoric/blob/master/docs/setup/mysql.md This code snippet illustrates how to enable `stringifyObjects` in Leoric. This option prevents incorrect SQL generation when objects are passed as query values, ensuring proper stringification. ```javascript await Post.where({ name: { id: 1, name: 'Untitled' } }); ``` -------------------------------- ### 修改 Ruby Gems 源 (Diff) Source: https://github.com/cyjake/leoric/blob/master/docs/zh/contributing/guides.md 修改 Leoric 项目 `docs/Gemfile` 文件,将默认的 Ruby Gems 源 `https://rubygems.org` 更改为 `https://gems.ruby-china.com`,以解决连接超时问题。 ```diff diff --git a/docs/Gemfile b/docs/Gemfile index 4382725..b4dba82 100644 --- a/docs/Gemfile +++ b/docs/Gemfile -source "https://rubygems.org" +source "https://gems.ruby-china.com" ``` -------------------------------- ### Include Predefined Joins (JavaScript) Source: https://github.com/cyjake/leoric/blob/master/docs/querying.md Demonstrates how to fetch records along with their associated data using predefined joins. This can be done using the .include() or .with() methods. ```javascript Post.include('comments') // or Post.find().with('comments') ``` ```javascript Post.include('comments', 'author') // or Post.find().with('comments').with('author') ``` ```javascript Post.findOne().with('comments').limit(10) ``` -------------------------------- ### Instantiate a Bone Model Source: https://github.com/cyjake/leoric/blob/master/docs/api/Bone.html Shows how to create new instances of a model extending Bone. This can be done with no initial data or by providing an object of initial data values during construction. ```javascript const post = new Post() const post = new Post({ title: 'Leah' }) ``` -------------------------------- ### Spell Class $ignoreIndex Method Example Source: https://github.com/cyjake/leoric/blob/master/docs/api/Spell.html Illustrates the usage of the $ignoreIndex method to exclude specific index hints from a query. Similar to $forceIndex, it accepts multiple hints and can include sorting or grouping criteria. ```javascript .ignoreIndex('idx_id') .ignoreIndex('idx_id', 'idx_title_id') .ignoreIndex('idx_id', { orderBy: ['idx_title', 'idx_org_id'] }, { groupBy: 'idx_type' }) ``` -------------------------------- ### 执行 Leoric 测试 (Bash) Source: https://github.com/cyjake/leoric/blob/master/docs/zh/contributing/guides.md 安装项目依赖并执行不同类型的测试。包括运行所有测试、仅单元测试、仅集成测试、TypeScript 定义测试,以及单个测试文件或使用 --grep 选项执行特定测试。 ```bash npm install npm run test npm run test:unit npm run test:integration npm run test:dts npm run test -- test/unit/test.connect.js --grep "should work" npm run test:unit -- --grep "=> Sequelize adapter" npm run test:mysql -- --grep "bone.toJSON()" ``` -------------------------------- ### MySQL ON DUPLICATE KEY UPDATE Example Source: https://github.com/cyjake/leoric/blob/master/docs/zh/querying.md Demonstrates the MySQL `INSERT ... ON DUPLICATE KEY UPDATE` statement, used to insert a new row or update an existing row if a duplicate key error is encountered. ```sql INSERT ... ON DUPLICATE KEY UPDATE ``` -------------------------------- ### 安装 Jekyll 和 Ruby 依赖 (Bash) Source: https://github.com/cyjake/leoric/blob/master/docs/zh/contributing/guides.md 使用 Homebrew 安装 Ruby,配置 PATH 环境变量,进入 docs 目录,并安装 Jekyll 所需的 Ruby Gems。这是构建 Leoric 帮助文档的前提。 ```bash brew install ruby echo 'export PATH="/usr/local/opt/ruby/bin:$PATH"' >> ~/.zshrc cd docs bundle install ``` -------------------------------- ### SQL Equivalent for Model.sum() Operation Source: https://github.com/cyjake/leoric/blob/master/docs/querying.md Provides the SQL query that corresponds to the Leoric `Model.sum()` operation shown in the JavaScript example. This helps in understanding the underlying database query generated by Leoric for sum aggregations. ```sql SELECT SUM(items.price) FROM (SELECT * FROM shops WHERE id = 42) AS shops LEFT JOIN items ON items.shop_id = shops.id; ```