Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: type options per dialect, add "url" option, remove alternative Sequelize constructor signatures #17222

Merged
merged 48 commits into from Apr 4, 2024

Conversation

ephys
Copy link
Member

@ephys ephys commented Mar 28, 2024

Note

Please review #17219 first

Description of Changes

The initial goal was to remove the extra signatures from the Sequelize constructor, and add the "url" option.
To do these changes cleanly, I moved the constructor to the TypeScript implementation.

Of course, and this is where I'm sorry, that lead to a series of changes to make the constructor TypeScript-compatible. Here they are:

  • The list of options persisted on the sequelize instance has been cleaned up to remove anything that did not make sense and would cause confusion, like:
    • options.dialect: users should access the dialect field instead
    • options.databaseVersion: users should use getDatabaseVersion instead
    • options.hooks: Is a shortcut for calling .hooks.addListener
    • options.models: Is a shortcut for calling .addModels
    • options.pool: The options are available on sequelize.pool instead
  • AbstractDialect.getDefaultPort has been removed because port normalization is now done by the dialect themselves, as connection options differ wildly per dialect
  • The pool was moved to the sequelize instance for two reasons:
    • All dialects should go through the pool, the pool is more coupled to the sequelize instance than the connection manager.
    • This fixes the issue where pool events would not fire for SQLite. The goal is to treat SQLite like all other dialects.
    • The sequelize options need to create the dialect instance to be able to parse the connection options, but the pool needs the connection options to init, so the dialect cannot be responsible for creating the pool
    • This also remove the weird workaround to get the database version.
  • Because the pool was moved, functions from the connection manager that only proxied to the pool have been removed. We now use the pool directly. Some of the features that were present in the connection manager were moved to the pool instead.
  • The replication config has been normalized to become the source of truth, instead of it being split in multiple places (options, config, replication)
  • All dialects now specify exactly which option they accept. Their connection options now more accurately represent what the dialect supports.

Sequelize throws if an unknown option is used:

image

Important

With this PR, the URL parsing is broken because it does not produce the right options for every dialect. We need to fix that before we publish a release.
I would rather not do it in this PR considering how big this PR already is.

Misc changes

  • Removed eslint rules that were already removed from the preset
  • Made the logging option disallow true in typings
  • Every possible way of setting the database version now calls sequelize.setDatabaseVersion which does the database version check
  • sequelize.sync's options does not inherit from sequelize's options anymore, as they caused problems with schemas. They still inherit from sequelize.options.sync.
  • Fixed a bug in sqlite's alter table: It was ignoring the transaction in non-cls mode
  • Removed the "match" option from sequelize.sync: It only worked for databases that have a "database" option. A better alternative should be considered instead

Changes made to tests

  • integration/configuration.test.ts was mostly disabled due to the test not actually testing anything, see Drop subclasses of SequelizeConnectionError #17240
  • the contents of abstract/connection-manager.test.ts were moved to pool.test.ts (split between integration & unit)
  • The hook writability tests are broken and should be dropped in favor of tests (written in typescript) that actually try to modify these values individually

List of Breaking Changes

  • The sequelize constructor only accepts a single parameter: the option bag. All other signatures have been removed.
  • Setting the sequelize option to a string representing a URL has been replaced with the "url" option.
  • The dialectOptions option has been removed. All options that were previously in that object can now be set at the root of the option bag, like all other options.
  • All dialect-specific options changed. This includes at least some credential options that changed.
  • Which dialect-specific option can be used is allow-listed to ensure they do not break Sequelize
  • The sequelize pool is not on the connection manager anymore. It is now directly on the sequelize instance and can be accessed via sequelize.pool
  • The sequelize.config field has been removed. Everything related to connecting to the database has been normalized to sequelize.options.replication.write (always present) and sequelize.options.replication.read (only present if read-replication is enabled)
  • sequelize.options is now fully frozen. It is no longer possible to modify the Sequelize options after the instance has been created.
  • sequelize.options is a normalized list of option. If you wish to access the options that were used to create the sequelize instance, use sequelize.rawOptions
  • The default sqlite database is not ':memory:' anymore, but sequelize.sqlite in your current working directory.
  • Setting the sqlite database to a temporary database like ':memory:' or '' requires configuring the pool to behave like a singleton, and disallowed read replication
  • The match option is no longer supported by sequelize.sync. If you made use of this feature, let us know so we can design a better alternative.

@ephys ephys requested a review from a team as a code owner March 28, 2024 23:23
@ephys ephys requested review from WikiRik and removed request for a team March 28, 2024 23:23
@ephys ephys changed the title feat: type options per dialect feat: type options per dialect, add "url" option, remove alternative Sequelize constructor signatures Mar 28, 2024
@ephys ephys changed the title feat: type options per dialect, add "url" option, remove alternative Sequelize constructor signatures feat!: type options per dialect, add "url" option, remove alternative Sequelize constructor signatures Mar 28, 2024
@ephys ephys marked this pull request as draft March 28, 2024 23:29
@ephys
Copy link
Member Author

ephys commented Mar 29, 2024

I'm reading as much as I can on SQLite pooling and the documentation is pretty clear about the fact that we can have multiple concurrent read connections, but only one connection can write at a time
Similarly, you can have multiple read transactions open at the same time, but you can only have a single write transaction open at any given time (otherwise you get sqlite_busy)

With that in mind, I think SQLite should use the pool like all other dialects, but:

  • the write pool should be set to 1 by default
  • the read pool should be configurable separately (it would make sense to have a different pool for each entry of the replication.read array)

Base automatically changed from ephys/module-overrides to main March 29, 2024 10:26
@ephys ephys marked this pull request as ready for review April 4, 2024 17:30
Copy link
Member

@WikiRik WikiRik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Few minor remarks

packages/core/package.json Outdated Show resolved Hide resolved
packages/sqlite/src/dialect.ts Outdated Show resolved Hide resolved
packages/core/test/unit/utils/sql.test.ts Show resolved Hide resolved
packages/core/src/index.d.ts Outdated Show resolved Hide resolved
packages/core/src/sequelize.internals.ts Outdated Show resolved Hide resolved
packages/postgres/src/dialect.ts Show resolved Hide resolved
packages/snowflake/src/connection-manager.ts Outdated Show resolved Hide resolved
@ephys ephys changed the title feat!: type options per dialect, add "url" option, remove alternative Sequelize constructor signatures feat: type options per dialect, add "url" option, remove alternative Sequelize constructor signatures Apr 4, 2024
@ephys ephys requested a review from WikiRik April 4, 2024 21:33
@WikiRik WikiRik merged commit 13224da into main Apr 4, 2024
51 checks passed
@WikiRik WikiRik deleted the ephys/option-rewrite branch April 4, 2024 21:53
@ephys
Copy link
Member Author

ephys commented Apr 4, 2024

Don't forget to add the list of breaking changes to the commit when merging, using the conventional commit syntax

WikiRik pushed a commit that referenced this pull request Apr 5, 2024
…Sequelize constructor signatures (#17222)

BREAKING CHANGE: The sequelize constructor only accepts a single parameter: the option bag. All other signatures have been removed.
BREAKING CHANGE: Setting the sequelize option to a string representing a URL has been replaced with the `"url"` option.
BREAKING CHANGE: The `dialectOptions` option has been removed. All options that were previously in that object can now be set at the root of the option bag, like all other options.
BREAKING CHANGE: All dialect-specific options changed. This includes at least some credential options that changed.
BREAKING CHANGE: Which dialect-specific option can be used is allow-listed to ensure they do not break Sequelize
BREAKING CHANGE: The sequelize pool is not on the connection manager anymore. It is now directly on the sequelize instance and can be accessed via `sequelize.pool`
BREAKING CHANGE: The `sequelize.config` field has been removed. Everything related to connecting to the database has been normalized to `sequelize.options.replication.write` (always present) and `sequelize.options.replication.read` (only present if read-replication is enabled)
BREAKING CHANGE: `sequelize.options` is now fully frozen. It is no longer possible to modify the Sequelize options after the instance has been created.
BREAKING CHANGE: `sequelize.options` is a normalized list of option. If you wish to access the options that were used to create the sequelize instance, use `sequelize.rawOptions`
BREAKING CHANGE: The default sqlite database is not `':memory:'` anymore, but `sequelize.sqlite` in your current working directory.
BREAKING CHANGE: Setting the sqlite database to a temporary database like `':memory:'` or `''` requires configuring the pool to behave like a singleton, and disallowed read replication
BREAKING CHANGE: The `match` option is no longer supported by `sequelize.sync`. If you made use of this feature, let us know so we can design a better alternative.
WikiRik added a commit that referenced this pull request Apr 7, 2024
…rnative Sequelize constructor signatures (#17222)"

This reverts commit 13224da.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Documenting
Development

Successfully merging this pull request may close these issues.

None yet

2 participants