Skip to content

Commit 77ce319

Browse files
dlarocquewu-hui
authored andcommitted
feat: [firestore] Add support for DML
1 parent e8755b5 commit 77ce319

4 files changed

Lines changed: 548 additions & 0 deletions

File tree

handwritten/firestore/dev/src/pipelines/pipelines.ts

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ import {
8181
Sample,
8282
Union,
8383
Unnest,
84+
DeleteStage,
85+
UpsertStage,
86+
InsertStage,
8487
InternalWhereStageOptions,
8588
InternalOffsetStageOptions,
8689
InternalLimitStageOptions,
@@ -95,6 +98,7 @@ import {
9598
InternalDocumentsStageOptions,
9699
InternalCollectionGroupStageOptions,
97100
InternalCollectionStageOptions,
101+
UpdateStage,
98102
} from './stage';
99103
import {StructuredPipeline} from './structured-pipeline';
100104
import Selectable = FirebaseFirestore.Pipelines.Selectable;
@@ -1486,6 +1490,200 @@ export class Pipeline implements firestore.Pipelines.Pipeline {
14861490
return this._addStage(new Sort(internalOptions));
14871491
}
14881492

1493+
/**
1494+
* @beta
1495+
* Performs a delete operation on documents from previous stages.
1496+
*
1497+
* @example
1498+
* ```typescript
1499+
* // Deletes all documents in the "books" collection.
1500+
* firestore.pipeline().collection("books")
1501+
* .delete();
1502+
* ```
1503+
*
1504+
* @return A new {@code Pipeline} object with this stage appended to the stage list.
1505+
*/
1506+
delete(): Pipeline;
1507+
/**
1508+
* @beta
1509+
* Performs a delete operation on documents from previous stages.
1510+
*
1511+
* TODO(dlarocque): Verify we want this function.
1512+
*
1513+
* @param collectionNameOrRef - The collection to delete from.
1514+
* @return A new {@code Pipeline} object with this stage appended to the stage list.
1515+
*/
1516+
delete(collectionNameOrRef: string | firestore.CollectionReference): Pipeline;
1517+
/**
1518+
* @beta
1519+
* Performs a delete operation on documents from previous stages.
1520+
*
1521+
* @example
1522+
* ```typescript
1523+
* // Deletes all documents in the books collection and returns their IDs.
1524+
* firestore.pipeline().collection("books")
1525+
* .delete({
1526+
* returns: "DOCUMENT_ID",
1527+
* });
1528+
* ```
1529+
*
1530+
* @param options - The {@code DeleteStageOptions} to apply to the stage.
1531+
* @return A new {@code Pipeline} object with this stage appended to the stage list.
1532+
*/
1533+
delete(options: firestore.Pipelines.DeleteStageOptions): Pipeline;
1534+
delete(
1535+
optionsOrCollection?:
1536+
| string
1537+
| firestore.CollectionReference
1538+
| firestore.Pipelines.DeleteStageOptions,
1539+
): Pipeline {
1540+
let target = undefined;
1541+
if (typeof optionsOrCollection === 'string') {
1542+
target = this.db.collection(optionsOrCollection);
1543+
} else if (isCollectionReference(optionsOrCollection)) {
1544+
target = optionsOrCollection;
1545+
}
1546+
const options = (
1547+
!isCollectionReference(optionsOrCollection) &&
1548+
typeof optionsOrCollection !== 'string'
1549+
? optionsOrCollection
1550+
: undefined
1551+
) as firestore.Pipelines.DeleteStageOptions | undefined;
1552+
return this._addStage(new DeleteStage(target, options));
1553+
}
1554+
1555+
/**
1556+
* @beta
1557+
* Performs an update operation using documents from previous stages.
1558+
*
1559+
* @return A new {@code Pipeline} object with this stage appended to the stage list.
1560+
*/
1561+
update(): Pipeline;
1562+
/**
1563+
* @beta
1564+
* Performs an update operation using documents from previous stages.
1565+
*
1566+
* @param collectionNameOrRef - The collection to update.
1567+
* @return A new {@code Pipeline} object with this stage appended to the stage list.
1568+
*/
1569+
update(collectionNameOrRef: string | firestore.CollectionReference): Pipeline;
1570+
/**
1571+
* @beta
1572+
* Performs an update operation using documents from previous stages.
1573+
*
1574+
* @param options - The {@code UpdateStageOptions} to apply to the stage.
1575+
* @return A new {@code Pipeline} object with this stage appended to the stage list.
1576+
*/
1577+
update(options: firestore.Pipelines.UpdateStageOptions): Pipeline;
1578+
update(
1579+
optionsOrCollection?:
1580+
| string
1581+
| firestore.CollectionReference
1582+
| firestore.Pipelines.UpdateStageOptions,
1583+
): Pipeline {
1584+
let target = undefined;
1585+
if (typeof optionsOrCollection === 'string') {
1586+
target = this.db.collection(optionsOrCollection);
1587+
} else if (isCollectionReference(optionsOrCollection)) {
1588+
target = optionsOrCollection;
1589+
}
1590+
const options = (
1591+
!isCollectionReference(optionsOrCollection) &&
1592+
typeof optionsOrCollection !== 'string'
1593+
? optionsOrCollection
1594+
: undefined
1595+
) as firestore.Pipelines.UpdateStageOptions | undefined;
1596+
return this._addStage(new UpdateStage(target, options));
1597+
}
1598+
1599+
/**
1600+
* @beta
1601+
* Performs an upsert operation using documents from previous stages.
1602+
*
1603+
* @return A new {@code Pipeline} object with this stage appended to the stage list.
1604+
*/
1605+
upsert(): Pipeline;
1606+
/**
1607+
* @beta
1608+
* Performs an upsert operation using documents from previous stages.
1609+
*
1610+
* @param collectionNameOrRef - The collection to upsert to.
1611+
* @return A new {@code Pipeline} object with this stage appended to the stage list.
1612+
*/
1613+
upsert(collectionNameOrRef: string | firestore.CollectionReference): Pipeline;
1614+
/**
1615+
* @beta
1616+
* Performs an upsert operation using documents from previous stages.
1617+
*
1618+
* @param options - The {@code UpsertStageOptions} to apply to the stage.
1619+
* @return A new {@code Pipeline} object with this stage appended to the stage list.
1620+
*/
1621+
upsert(options: firestore.Pipelines.UpsertStageOptions): Pipeline;
1622+
upsert(
1623+
optionsOrCollection?:
1624+
| string
1625+
| firestore.CollectionReference
1626+
| firestore.Pipelines.UpsertStageOptions,
1627+
): Pipeline {
1628+
let target = undefined;
1629+
if (typeof optionsOrCollection === 'string') {
1630+
target = this.db.collection(optionsOrCollection);
1631+
} else if (isCollectionReference(optionsOrCollection)) {
1632+
target = optionsOrCollection;
1633+
}
1634+
const options = (
1635+
!isCollectionReference(optionsOrCollection) &&
1636+
typeof optionsOrCollection !== 'string'
1637+
? optionsOrCollection
1638+
: undefined
1639+
) as firestore.Pipelines.UpsertStageOptions | undefined;
1640+
return this._addStage(new UpsertStage(target, options));
1641+
}
1642+
1643+
/**
1644+
* @beta
1645+
* Performs an insert operation using documents from previous stages.
1646+
*
1647+
* @return A new {@code Pipeline} object with this stage appended to the stage list.
1648+
*/
1649+
insert(): Pipeline;
1650+
/**
1651+
* @beta
1652+
* Performs an insert operation using documents from previous stages.
1653+
*
1654+
* @param collectionNameOrRef - The collection to insert to.
1655+
* @return A new {@code Pipeline} object with this stage appended to the stage list.
1656+
*/
1657+
insert(collectionNameOrRef: string | firestore.CollectionReference): Pipeline;
1658+
/**
1659+
* @beta
1660+
* Performs an insert operation using documents from previous stages.
1661+
*
1662+
* @param options - The {@code InsertStageOptions} to apply to the stage.
1663+
* @return A new {@code Pipeline} object with this stage appended to the stage list.
1664+
*/
1665+
insert(options: firestore.Pipelines.InsertStageOptions): Pipeline;
1666+
insert(
1667+
optionsOrCollection?:
1668+
| string
1669+
| firestore.CollectionReference
1670+
| firestore.Pipelines.InsertStageOptions,
1671+
): Pipeline {
1672+
let target = undefined;
1673+
if (typeof optionsOrCollection === 'string') {
1674+
target = this.db.collection(optionsOrCollection);
1675+
} else if (isCollectionReference(optionsOrCollection)) {
1676+
target = optionsOrCollection;
1677+
}
1678+
const options = (
1679+
!isCollectionReference(optionsOrCollection) &&
1680+
typeof optionsOrCollection !== 'string'
1681+
? optionsOrCollection
1682+
: undefined
1683+
) as firestore.Pipelines.InsertStageOptions | undefined;
1684+
return this._addStage(new InsertStage(target, options));
1685+
}
1686+
14891687
/**
14901688
* @beta
14911689
* Adds a raw stage to the pipeline.

handwritten/firestore/dev/src/pipelines/stage.ts

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,3 +759,138 @@ export class RawStage implements Stage {
759759
validateUserDataHelper(this.params, ignoreUndefinedProperties);
760760
}
761761
}
762+
763+
/**
764+
* Delete stage.
765+
*/
766+
export class DeleteStage implements Stage {
767+
name = 'delete';
768+
readonly optionsUtil = new OptionsUtil({
769+
returns: {serverName: 'returns'},
770+
});
771+
772+
constructor(
773+
private target?: firestore.CollectionReference,
774+
private rawOptions?: firestore.Pipelines.DeleteStageOptions,
775+
) {}
776+
777+
_toProto(serializer: Serializer): api.Pipeline.IStage {
778+
const args: api.IValue[] = [];
779+
if (this.target) {
780+
args.push({referenceValue: this.target.path});
781+
}
782+
783+
return {
784+
name: this.name,
785+
args,
786+
options: this.optionsUtil.getOptionsProto(
787+
serializer,
788+
{},
789+
this.rawOptions,
790+
),
791+
};
792+
}
793+
}
794+
/**
795+
* Update stage.
796+
*/
797+
export class UpdateStage implements Stage {
798+
name = 'update';
799+
readonly optionsUtil = new OptionsUtil({
800+
returns: {serverName: 'returns'},
801+
conflict_resolution: {serverName: 'conflict_resolution'},
802+
transformations: {serverName: 'transformations'},
803+
transactional: {serverName: 'transactional'},
804+
});
805+
806+
constructor(
807+
private target?: firestore.CollectionReference,
808+
private rawOptions?: firestore.Pipelines.UpdateStageOptions,
809+
) {}
810+
811+
_toProto(serializer: Serializer): api.Pipeline.IStage {
812+
const args: api.IValue[] = [];
813+
if (this.target) {
814+
args.push({referenceValue: this.target.path});
815+
}
816+
817+
return {
818+
name: this.name,
819+
args,
820+
options: this.optionsUtil.getOptionsProto(
821+
serializer,
822+
{},
823+
this.rawOptions,
824+
),
825+
};
826+
}
827+
}
828+
829+
/**
830+
* Upsert stage.
831+
*/
832+
export class UpsertStage implements Stage {
833+
name = 'upsert';
834+
readonly optionsUtil = new OptionsUtil({
835+
returns: {serverName: 'returns'},
836+
conflict_resolution: {serverName: 'conflict_resolution'},
837+
transformations: {serverName: 'transformations'},
838+
transactional: {serverName: 'transactional'},
839+
});
840+
841+
constructor(
842+
private target?: firestore.CollectionReference,
843+
private rawOptions?: firestore.Pipelines.UpsertStageOptions,
844+
) {}
845+
846+
_toProto(serializer: Serializer): api.Pipeline.IStage {
847+
const args: api.IValue[] = [];
848+
if (this.target) {
849+
args.push({referenceValue: this.target.path});
850+
}
851+
852+
return {
853+
name: this.name,
854+
args,
855+
options: this.optionsUtil.getOptionsProto(
856+
serializer,
857+
{},
858+
this.rawOptions,
859+
),
860+
};
861+
}
862+
}
863+
864+
/**
865+
* Insert stage.
866+
*/
867+
export class InsertStage implements Stage {
868+
name = 'insert';
869+
readonly optionsUtil = new OptionsUtil({
870+
returns: {serverName: 'returns'},
871+
transformations: {serverName: 'transformations'},
872+
transactional: {serverName: 'transactional'},
873+
});
874+
875+
constructor(
876+
private target?: firestore.CollectionReference,
877+
private rawOptions?: firestore.Pipelines.InsertStageOptions,
878+
) {}
879+
880+
_toProto(serializer: Serializer): api.Pipeline.IStage {
881+
const args: api.IValue[] = [];
882+
if (this.target) {
883+
args.push({referenceValue: this.target.path});
884+
}
885+
886+
return {
887+
name: this.name,
888+
args,
889+
options: this.optionsUtil.getOptionsProto(
890+
serializer,
891+
{},
892+
this.rawOptions,
893+
),
894+
};
895+
}
896+
}

0 commit comments

Comments
 (0)