Skip to content

Commit

Permalink
Added test cases for query, stored procedures. and updated README.md …
Browse files Browse the repository at this point in the history
…for hierarchical partition containers.

Added hierarchical partition support for change feed api.

Added utilities for type checks for PartitionKey

Added typeChecks.ts to skip strict typechecks.

Added @remark annotation, notifying PartitionKeyDefinition as no longer part of PartitionKey

exporting newly added types to top level index.ts
  • Loading branch information
vikask00 authored and v1k1 committed Feb 27, 2023
1 parent 7270702 commit 220f752
Show file tree
Hide file tree
Showing 12 changed files with 584 additions and 173 deletions.
43 changes: 41 additions & 2 deletions sdk/cosmosdb/cosmos/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ The following sections provide several code snippets covering some of the most c
- [Query documents](#query-the-database)
- [Read an item](#read-an-item)
- [Delete an item](#delete-an-data)

- [CRUD on Container with hierarchical partition key](#container-hierarchical-partition-key)
### Create a database

After authenticating your [CosmosClient](https://docs.microsoft.com/javascript/api/@azure/cosmos/cosmosclient?view=azure-node-latest), you can work with any resource in the account. The code snippet below creates a SQL API database.
Expand Down Expand Up @@ -144,7 +144,46 @@ To read a single item from a container, use [Item.read](https://docs.microsoft.c
```js
await container.item("1").read();
```

### CRUD on Container with hierarchical partition key
```js
const containerDefinition = {
id: "Test Database",
partitionKey: {
paths: ["/name", "/address/zip"],
version: PartitionKeyDefinitionVersion.V2,
kind: PartitionKeyKind.MultiHash,
},
}
const { container } = await database.containers.createIfNotExists(containerDefinition);
console.log(container.id);
```
#### Insert an item with hierarchical partition key
```js
const item = {
id: 1,
name: 'foo',
address: {
zip: 100
},
active: true
}
await container.items.create(item);
```
#### Read an item with hierarchical partition key
```js
To read a single item from a container with hierarchical partition key defines as `paths: ["/name", "/address/zip"],`
await container.item("1", ["foo", 100]).read();
```
#### Query an item with hierarchical partition key
```js
const { resources } = await container.items
.query("SELECT * from c WHERE c.active = true", {
partitionKey: ["foo", 100],
})
.fetchAll();
for (const item of resources) {
console.log(`${item.name}, ${item.address.zip} `);
}
### Delete an item

To delete items from a container, use [Item.delete](https://docs.microsoft.com/javascript/api/@azure/cosmos/item?view=azure-node-latest#delete-requestoptions-).
Expand Down
8 changes: 4 additions & 4 deletions sdk/cosmosdb/cosmos/review/cosmos.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -908,9 +908,9 @@ export class Items {
constructor(container: Container, clientContext: ClientContext);
batch(operations: OperationInput[], partitionKey?: PartitionKey, options?: RequestOptions): Promise<Response_2<OperationResponse[]>>;
bulk(operations: OperationInput[], bulkOptions?: BulkOptions, options?: RequestOptions): Promise<OperationResponse[]>;
changeFeed(partitionKey: string | number | boolean, changeFeedOptions?: ChangeFeedOptions): ChangeFeedIterator<any>;
changeFeed(partitionKey: PartitionKey, changeFeedOptions?: ChangeFeedOptions): ChangeFeedIterator<any>;
changeFeed(changeFeedOptions?: ChangeFeedOptions): ChangeFeedIterator<any>;
changeFeed<T>(partitionKey: string | number | boolean, changeFeedOptions?: ChangeFeedOptions): ChangeFeedIterator<T>;
changeFeed<T>(partitionKey: PartitionKey, changeFeedOptions?: ChangeFeedOptions): ChangeFeedIterator<T>;
changeFeed<T>(changeFeedOptions?: ChangeFeedOptions): ChangeFeedIterator<T>;
// (undocumented)
readonly container: Container;
Expand All @@ -920,11 +920,11 @@ export class Items {
readAll(options?: FeedOptions): QueryIterator<ItemDefinition>;
readAll<T extends ItemDefinition>(options?: FeedOptions): QueryIterator<T>;
// @deprecated
readChangeFeed(partitionKey: string | number | boolean, changeFeedOptions?: ChangeFeedOptions): ChangeFeedIterator<any>;
readChangeFeed(partitionKey: PartitionKey, changeFeedOptions?: ChangeFeedOptions): ChangeFeedIterator<any>;
// @deprecated
readChangeFeed(changeFeedOptions?: ChangeFeedOptions): ChangeFeedIterator<any>;
// @deprecated
readChangeFeed<T>(partitionKey: string | number | boolean, changeFeedOptions?: ChangeFeedOptions): ChangeFeedIterator<T>;
readChangeFeed<T>(partitionKey: PartitionKey, changeFeedOptions?: ChangeFeedOptions): ChangeFeedIterator<T>;
// @deprecated
readChangeFeed<T>(changeFeedOptions?: ChangeFeedOptions): ChangeFeedIterator<T>;
upsert(body: unknown, options?: RequestOptions): Promise<ItemResponse<ItemDefinition>>;
Expand Down
3 changes: 2 additions & 1 deletion sdk/cosmosdb/cosmos/src/ChangeFeedIterator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ChangeFeedResponse } from "./ChangeFeedResponse";
import { Resource } from "./client";
import { ClientContext } from "./ClientContext";
import { Constants, ResourceType, StatusCodes } from "./common";
import { PartitionKey } from "./documents";
import { FeedOptions } from "./request";
import { Response } from "./request";

Expand All @@ -28,7 +29,7 @@ export class ChangeFeedIterator<T> {
private clientContext: ClientContext,
private resourceId: string,
private resourceLink: string,
private partitionKey: string | number | boolean,
private partitionKey: PartitionKey,
private changeFeedOptions: ChangeFeedOptions
) {
// partition key XOR partition key range id
Expand Down
21 changes: 9 additions & 12 deletions sdk/cosmosdb/cosmos/src/client/Item/Items.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,15 @@ import {
decorateBatchOperation,
splitBatchBasedOnBodySize,
} from "../../utils/batch";
import { assertNotUndefined } from "../../utils/typeChecks";
import { assertNotUndefined, isPrimitivePartitionKeyValue } from "../../utils/typeChecks";
import { hashPartitionKey } from "../../utils/hashing/hash";
import { PartitionKey, PartitionKeyDefinition } from "../../documents";

/**
* @hidden
*/
function isChangeFeedOptions(options: unknown): options is ChangeFeedOptions {
const optionsType = typeof options;
return (
options && !(optionsType === "string" || optionsType === "boolean" || optionsType === "number")
);
return options && !(isPrimitivePartitionKeyValue(options) || Array.isArray(options));
}

/**
Expand Down Expand Up @@ -126,7 +123,7 @@ export class Items {
* ```
*/
public readChangeFeed(
partitionKey: string | number | boolean,
partitionKey: PartitionKey,
changeFeedOptions?: ChangeFeedOptions
): ChangeFeedIterator<any>;
/**
Expand All @@ -140,7 +137,7 @@ export class Items {
* @deprecated Use `changeFeed` instead.
*/
public readChangeFeed<T>(
partitionKey: string | number | boolean,
partitionKey: PartitionKey,
changeFeedOptions?: ChangeFeedOptions
): ChangeFeedIterator<T>;
/**
Expand All @@ -149,7 +146,7 @@ export class Items {
*/
public readChangeFeed<T>(changeFeedOptions?: ChangeFeedOptions): ChangeFeedIterator<T>;
public readChangeFeed<T>(
partitionKeyOrChangeFeedOptions?: string | number | boolean | ChangeFeedOptions,
partitionKeyOrChangeFeedOptions?: PartitionKey | ChangeFeedOptions,
changeFeedOptions?: ChangeFeedOptions
): ChangeFeedIterator<T> {
if (isChangeFeedOptions(partitionKeyOrChangeFeedOptions)) {
Expand All @@ -171,7 +168,7 @@ export class Items {
* ```
*/
public changeFeed(
partitionKey: string | number | boolean,
partitionKey: PartitionKey,
changeFeedOptions?: ChangeFeedOptions
): ChangeFeedIterator<any>;
/**
Expand All @@ -182,18 +179,18 @@ export class Items {
* Create a `ChangeFeedIterator` to iterate over pages of changes
*/
public changeFeed<T>(
partitionKey: string | number | boolean,
partitionKey: PartitionKey,
changeFeedOptions?: ChangeFeedOptions
): ChangeFeedIterator<T>;
/**
* Create a `ChangeFeedIterator` to iterate over pages of changes
*/
public changeFeed<T>(changeFeedOptions?: ChangeFeedOptions): ChangeFeedIterator<T>;
public changeFeed<T>(
partitionKeyOrChangeFeedOptions?: string | number | boolean | ChangeFeedOptions,
partitionKeyOrChangeFeedOptions?: PartitionKey | ChangeFeedOptions,
changeFeedOptions?: ChangeFeedOptions
): ChangeFeedIterator<T> {
let partitionKey: string | number | boolean;
let partitionKey: PartitionKey;
if (!changeFeedOptions && isChangeFeedOptions(partitionKeyOrChangeFeedOptions)) {
partitionKey = undefined;
changeFeedOptions = partitionKeyOrChangeFeedOptions;
Expand Down
6 changes: 6 additions & 0 deletions sdk/cosmosdb/cosmos/src/documents/PartitionKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@

import { NonePartitionKeyLiteral, NullPartitionKeyLiteral } from "./PartitionKeyInternal";

/**
* PartitionKey of a container.
* @remarks
* - PartitionKeyDefinition is no longer part of PartitionKey. So please use PartitionKeyDefinition
* type directly where appropriate.
*/
export type PartitionKey = PrimitivePartitionKeyValue | PrimitivePartitionKeyValue[];

/**
Expand Down
5 changes: 5 additions & 0 deletions sdk/cosmosdb/cosmos/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,12 @@ export {
IndexKind,
Location,
PartitionKey,
PrimitivePartitionKeyValue,
NullPartitionKeyType,
NonePartitionKeyType,
PartitionKeyKind,
PartitionKeyDefinition,
PartitionKeyDefinitionVersion,
PermissionMode,
TriggerOperation,
TriggerType,
Expand Down
44 changes: 44 additions & 0 deletions sdk/cosmosdb/cosmos/src/utils/typeChecks.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import {
NonePartitionKeyLiteral,
NonePartitionKeyType,
NullPartitionKeyLiteral,
NullPartitionKeyType,
PrimitivePartitionKeyValue,
} from "../documents";

/**
* A type which could be any type but undefined
*/
Expand All @@ -19,3 +27,39 @@ export function assertNotUndefined<T>(value: T, msg?: string): NonUndefinable<T>
}
throw new Error(msg || "Unexpected 'undefined' value encountered");
}

/**
* Check for value being PrimitivePartitionKeyValue.
* @internal
*/
export function isPrimitivePartitionKeyValue(value: unknown): value is PrimitivePartitionKeyValue {
return (
isWellDefinedPartitionKeyValue(value) ||
isNonePartitionKeyValue(value) ||
isNullPartitionKeyValue(value)
);
}

/**
* Check for value being string, number or boolean.
* @internal
*/
export function isWellDefinedPartitionKeyValue(value: unknown): value is string | number | boolean {
return typeof value === "string" || typeof value === "boolean" || typeof value === "number";
}

/**
* Check for value being NonePartitionKeyType.
* @internal
*/
export function isNonePartitionKeyValue(value: unknown): value is NonePartitionKeyType {
return value !== undefined && JSON.stringify(value) === JSON.stringify(NonePartitionKeyLiteral);
}

/**
* Check for value being NullPartitionKeyType.
* @internal
*/
export function isNullPartitionKeyValue(value: unknown): value is NullPartitionKeyType {
return value === NullPartitionKeyLiteral;
}
Loading

0 comments on commit 220f752

Please sign in to comment.