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(NODE-3517): improve index spec handling and type definitions #3315

Merged
merged 29 commits into from Jul 27, 2022

Conversation

aditi-khare-mongoDB
Copy link
Contributor

@aditi-khare-mongoDB aditi-khare-mongoDB commented Jul 7, 2022

Description

parseIndexOptions() was a helper function that allowed users to multiple different input formattings for CreateIndex and normalizes them to one format.

The function was buggy, in the wrong file, and had some unused outputs, so I renamed it to getFieldHash and put it inside the makeIndexSpec function.

What is changing?

Is there new documentation needed for these changes?

Yes,

  1. Bug Fix: need to notify users that the tuple input formatting did not work correctly for IndexDirections other than 1
  2. Map type is now an acceptable input formatting, and it is the only one that that will preserve numerical key ordering.

What is the motivation for this change?

Bug:
the previous parseIndexOptions was buggy when a [string, IndexDirection] tuple was part of the input.

Desired Output:
{string: IndexDirection}

Current Output:
(if IndexDirection is numerical) {string: 1}
OR
(if IndexDirection is not numerical): {{string: 1} {IndexDirection: 1}

New Feature:
Can now input a Map with a single key and value, or an array of length = 1 Maps as input.
** This is important as now we can preserve numerical key ordering **

Input Examples:
ex: new Map<string, IndexDirection>([['sample_index', -1]])

ex2: [ new Map<string, IndexDirection>([['sample_index1', 1]]), new Map<string, IndexDirection>([['sample_index2', -1]]), new Map<string, IndexDirection>([['sample_index3', '2d']]) ]

Addresses:

PR Summary:

  • Map as a valid input type in TS definition
  • Uses Map under the hood to ensure key order is preserved, esp with FLE
  • Tuples passed at the top level to createIndex were incorrectly parsed as string input
    • createIndex(['myKey', 1]) would create { 'myKey': 1, '1': 1 }.
    • Now it's correctly detected if the second arg is one of the known index directions.
    • We recommend using a Map to avoid all the edge cases here.
  • Type strictness on this nesting of array (one or more)
  • Type strictness for createIndexes aligned with createIndex
    • No longer accepts just Document, checks that the values are a known IndexDirection

Double check the following

  • Ran npm run check:lint script
  • Self-review completed using the steps outlined here
  • PR title follows the correct format: <type>(NODE-xxxx)<!>: <description>
  • Changes are covered by tests
  • New TODOs have a related JIRA ticket

@nbbeeken nbbeeken marked this pull request as draft July 7, 2022 17:34
@nbbeeken nbbeeken changed the title Node 3517 improve parse index options fix(NODE-3517): WIP improve parse index options Jul 7, 2022
@nbbeeken nbbeeken added the wip label Jul 7, 2022
@aditi-khare-mongoDB aditi-khare-mongoDB changed the title fix(NODE-3517): WIP improve parse index options fix(NODE-3517): Improve parse index options Jul 11, 2022
@aditi-khare-mongoDB aditi-khare-mongoDB force-pushed the NODE-3517-improve-parseIndexOptions branch from d08bfe3 to 20261ac Compare July 11, 2022 19:56
@nbbeeken nbbeeken force-pushed the NODE-3517-improve-parseIndexOptions branch from dc35940 to 0c03cf7 Compare July 20, 2022 15:48
@nbbeeken nbbeeken force-pushed the NODE-3517-improve-parseIndexOptions branch from 33d71dd to 79babb2 Compare July 20, 2022 18:51
@nbbeeken nbbeeken marked this pull request as ready for review July 20, 2022 18:58
@nbbeeken
Copy link
Contributor

Requesting Review from: @aditi-khare-mongoDB (GH permission issues)

@nbbeeken nbbeeken added the Primary Review In Review with primary reviewer, not yet ready for team's eyes label Jul 20, 2022
src/cmap/connection.ts Outdated Show resolved Hide resolved
test/integration/client-side-encryption/driver.test.ts Outdated Show resolved Hide resolved
test/tools/spec-runner/index.js Show resolved Hide resolved
test/unit/operations/indexes.test.ts Outdated Show resolved Hide resolved
@nbbeeken nbbeeken added Team Review Needs review from team and removed Primary Review In Review with primary reviewer, not yet ready for team's eyes labels Jul 22, 2022
let collection: Collection;

beforeEach(async function () {
if (this.configuration.clientSideEncryption == null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

What is this check for?

Copy link
Contributor

Choose a reason for hiding this comment

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

It is to avoid the dependency missing error that will be thrown by the newClient call that takes an autoEncryption option.

Copy link
Contributor

Choose a reason for hiding this comment

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

So if clientSideEncryption is nullish, we return. Is that supposed to skip these tests? If so, we should explicitly skip them and attach a skip reason.

Also, if that's the intention, should we follow the precedent we just set and use this.configuration.clientEncryption.enabled?

Copy link
Contributor

@nbbeeken nbbeeken Jul 26, 2022

Choose a reason for hiding this comment

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

The tests are skipped by the metadata attached to each test

try {
expect(await collection.indexExists(operation.arguments.indexName)).to.be.true;
indexes = await listIndexCursor.toArray();
Copy link
Contributor

Choose a reason for hiding this comment

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

Why did we change the implementation here? Is our indexExists broken?

Copy link
Contributor

Choose a reason for hiding this comment

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

It asserted the reverse of what the operation expects (expected indexExists to return true for the assertIndexNotExists operation.) So it needed to be flipped but also we made the code the same as the code for assertExists, listIndexes is spec-ed so seems like we should use that in the spec test runner.

test/tools/unified-spec-runner/runner.ts Show resolved Hide resolved
return (
typeof x === 'number' || x === '2d' || x === '2dsphere' || x === 'text' || x === 'geoHaystack'
);
}
/** @public */
export type IndexSpecification = OneOrMore<
| string
| [string, IndexDirection]
| { [key: string]: IndexDirection }
Copy link
Contributor

Choose a reason for hiding this comment

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

Removing the array options is a breaking change, because the following used to be permitted, even though it's not a valid index specification according to MongoDB:

const invalid: IndexSpecification = [[["name", 1]]]

Our precedent is to release breaking TS changes as bug fixes when applicable, which I am okay with, but maybe we should consider pulling this change (the deletion of lines 60/61) into a separate bug fix PR to not mix the bug fix in with this other work.

Copy link
Contributor

Choose a reason for hiding this comment

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

Of the three we're addressing here should we pull them each out and try and make this PR only about the refactor (i.e. why this bug but not the others)? (I think the tuple one might be difficult but we can see).

Copy link
Contributor

Choose a reason for hiding this comment

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

what "three" are you referencing here? three bugs?

Copy link
Contributor

Choose a reason for hiding this comment

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

  • Map in TS
  • Key order FLE
  • Tuple parsing issue
  • Type strictness on this nesting of array (one or more)
  • Type strictness for createIndexes aligned with createIndex

Copy link
Contributor

Choose a reason for hiding this comment

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

I think whether we pull these out into separate PRs/fixes or not, we should make sure that the PR description accurately reflects whatever fixes are included and that we are super clear in our release notes about the changes in behavior. It's also worth noting that the types in the documentation won't get updated on a patch, unless we manually regenerate the 4.8, which could be confusing. I think because of the scope of the changes here, this set of improvements that's coming in as a bug fix is better marked as a feat:

Copy link
Contributor

@dariakp dariakp Jul 26, 2022

Choose a reason for hiding this comment

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

Oh and let's triple check to make sure that every single one of those things has full regression test coverage

Copy link
Contributor

Choose a reason for hiding this comment

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

Collected a summary in the description and between the type/fle/indexes.test.ts additions I see coverage for each point.

src/operations/indexes.ts Outdated Show resolved Hide resolved
src/operations/indexes.ts Show resolved Hide resolved
src/cmap/connection.ts Show resolved Hide resolved
@@ -196,7 +219,25 @@ export class CreateIndexesOperation<
this.options = options ?? {};
this.collectionName = collectionName;

this.indexes = indexes;
// Ensure we generate the correct name if the parameter is not set
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we move this code into a function? We discussed this a bit in the office, but I still think for readability it should be broken out. The fact that a comment is necessary to explain what this block of code is doing strongly indicates that this should be broken out into a function.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure done!

test/unit/operations/indexes.test.ts Outdated Show resolved Hide resolved
src/operations/indexes.ts Outdated Show resolved Hide resolved
src/operations/indexes.ts Outdated Show resolved Hide resolved
src/operations/indexes.ts Outdated Show resolved Hide resolved
test/integration/client-side-encryption/driver.test.ts Outdated Show resolved Hide resolved
test/tools/spec-runner/index.js Outdated Show resolved Hide resolved
test/tools/unified-spec-runner/match.ts Show resolved Hide resolved
test/types/community/createIndex.test-d.ts Show resolved Hide resolved
test/unit/operations/indexes.test.ts Show resolved Hide resolved
Copy link
Contributor

@baileympearson baileympearson left a comment

Choose a reason for hiding this comment

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

requesting changes for visibility

@nbbeeken nbbeeken changed the title fix(NODE-3517): Improve parse index options feat(NODE-3517): improve index spec handling and type definitions Jul 27, 2022
@nbbeeken nbbeeken requested a review from dariakp July 27, 2022 16:15
@baileympearson baileympearson merged commit 0754bf9 into main Jul 27, 2022
@baileympearson baileympearson deleted the NODE-3517-improve-parseIndexOptions branch July 27, 2022 18:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Team Review Needs review from team
Projects
None yet
4 participants