npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

loopback4-sequelize

v2.3.0

Published

Loopback 4 Extension That Provides Sequelize Crud Repository Compatible With Default Loopback Models.

Downloads

226

Readme

Deprecated!

As of 24th April 2023, loopback4-sequelize is fully deprecated. New changes are expected to land on the official replacement of this package here: @loopback/sequelize and the same is recommended for current and future users.

loopback4-sequelize

LoopBack

This is a loopback4 extension that provides Sequelize's query builder at repository level in any loopback 4 application. It has zero learning curve as it follows similar interface as DefaultCrudRepository. For relational databases, Sequelize is a popular ORM of choice.

For pending features, refer to the Limitations section below.

Installation

To install this extension in your Loopback 4 project, run the following command:

npm install loopback4-sequelize

You'll also need to install the driver for your preferred database:

# One of the following:
npm install --save pg pg-hstore # Postgres
npm install --save mysql2
npm install --save mariadb
npm install --save sqlite3
npm install --save tedious # Microsoft SQL Server
npm install --save oracledb # Oracle Database

Usage

You can watch a video overview of this extension by clicking here.

Both newly developed and existing projects can benefit from the extension by simply changing the parent classes in the target Data Source and Repositories.

Step 1: Configure DataSource

Change the parent class from juggler.DataSource to SequelizeDataSource like below.

// ...
import {SequelizeDataSource} from 'loopback4-sequelize';

// ...
export class PgDataSource
  extends SequelizeDataSource
  implements LifeCycleObserver {
  // ...
}

SequelizeDataSource accepts commonly used config in the same way as loopback did. So in most cases you won't need to change your existing configuration. But if you want to use sequelize specific options pass them in sequelizeOptions like below:

let config = {
  name: 'db',
  connector: 'postgresql',
  sequelizeOptions: {
    username: 'postgres',
    password: 'secret',
    dialectOptions: {
      ssl: {
        rejectUnauthorized: false,
        ca: fs.readFileSync('/path/to/root.crt').toString(),
      },
    },
  },
};

Note: Options provided in sequelizeOptions will take priority over others, For eg. if you have password specified in both config.password and config.password.sequelizeOptions the latter one will be used.

Step 2: Configure Repository

Change the parent class from DefaultCrudRepository to SequelizeCrudRepository like below.

// ...
import {SequelizeCrudRepository} from 'loopback4-sequelize';

export class YourRepository extends SequelizeCrudRepository<
  YourModel,
  typeof YourModel.prototype.id,
  YourModelRelations
> {
  // ...
}

Relations

Supported Loopback Relations

With SequelizeCrudRepository, you can utilize following relations without any additional configuration:

  1. HasMany Relation
  2. BelongsTo Relation
  3. HasOne Relation
  4. HasManyThrough Relation
  5. ReferencesMany Relation

The default relation configuration, generated using the lb4 relation command (i.e. inclusion resolvers in the repository and property decorators in the model), remain unchanged.

INNER JOIN

Check the demo video of using inner joins here: https://youtu.be/ZrUxIk63oRc?t=76

When using SequelizeCrudRepository, the find(), findOne(), and findById() methods accept a new option called required in the include filter. Setting this option to true will result in an inner join query that explicitly requires the specified condition for the child model. If the row does not meet this condition, it will not be fetched and returned.

An example of the filter object might look like this to fetch the books who contains "Art" in their title, which belongs to category "Programming":

{
  "where": {"title": {"like": "%Art%"}},
  "include": [
    {
      "relation": "category",
      "scope": {
        "where": {
          "name": "Programming"
        }
      },
      "required": true // 👈
    }
  ]
}

SQL Transactions

A Sequelize repository can perform operations in a transaction using the beginTransaction() method.

Isolation levels

When you call beginTransaction(), you can optionally specify a transaction isolation level. It support the following isolation levels:

  • Transaction.ISOLATION_LEVELS.READ_UNCOMMITTED (default)
  • Transaction.ISOLATION_LEVELS.READ_COMMITTED
  • Transaction.ISOLATION_LEVELS.REPEATABLE_READ
  • Transaction.ISOLATION_LEVELS.SERIALIZABLE

Options

Following are the supported options:

{
  autocommit?: boolean;
  isolationLevel?: Transaction.ISOLATION_LEVELS;
  type?: Transaction.TYPES;
  deferrable?: string | Deferrable;
  /**
   * Parent transaction.
   */
  transaction?: Transaction | null;
}

Example

// Get repository instances. In a typical application, instances are injected
// via dependency injection using `@repository` decorator.
const userRepo = await app.getRepository(UserRepository);

// Begin a new transaction.
// It's also possible to call `userRepo.dataSource.beginTransaction` instead.
const tx = await userRepo.beginTransaction({
  isolationLevel: Transaction.ISOLATION_LEVELS.SERIALIZABLE,
});

try {
  // Then, we do some calls passing this transaction as an option:
  const user = await userRepo.create(
    {
      firstName: 'Jon',
      lastName: 'Doe',
    },
    {transaction: tx},
  );

  await userRepo.updateById(
    user.id,
    {
      firstName: 'John',
    },
    {transaction: tx},
  );

  // If the execution reaches this line, no errors were thrown.
  // We commit the transaction.
  await tx.commit();
} catch (error) {
  // If the execution reaches this line, an error was thrown.
  // We rollback the transaction.
  await tx.rollback();
}

Switching from loopback defaults to sequelize transaction is as simple as this commit in loopback4-sequelize-transaction-example.

Debug strings reference

There are three built-in debug strings available in this extension to aid in debugging. To learn more about how to use them, see this page.

Limitations

Please note, the current implementation does not support the following:

  1. Loopback Migrations (via default migrate.ts). Though you're good if using external packages like db-migrate.

Community contribution is welcome.

Feedback

If you've noticed a bug or have a question or have a feature request, search the issue tracker to see if someone else in the community has already created a ticket. If not, go ahead and make one! All feature requests are welcome. Implementation time may vary. Feel free to contribute the same, if you can. If you think this extension is useful, please star it. Appreciation really helps in keeping this project alive.

Contributing

Please read CONTRIBUTING.md for details on the process for submitting pull requests to us.

Code of conduct

Code of conduct guidelines here.

License

MIT