@@ -520,43 +520,7 @@ export class DataConnectApiClient {
520520 tableName : string ,
521521 data : Variables ,
522522 ) : Promise < ExecuteGraphqlResponse < GraphQlResponse > > {
523- if ( ! validator . isNonEmptyString ( tableName ) ) {
524- throw new FirebaseDataConnectError ( {
525- code : DATA_CONNECT_ERROR_CODE_MAPPING . INVALID_ARGUMENT ,
526- message : '`tableName` must be a non-empty string.'
527- } ) ;
528- }
529- if ( validator . isArray ( data ) ) {
530- throw new FirebaseDataConnectError ( {
531- code : DATA_CONNECT_ERROR_CODE_MAPPING . INVALID_ARGUMENT ,
532- message : '`data` must be an object, not an array, for single insert. For arrays, please use '
533- + '`insertMany` function.'
534- } ) ;
535- }
536- if ( ! validator . isNonNullObject ( data ) ) {
537- throw new FirebaseDataConnectError ( {
538- code : DATA_CONNECT_ERROR_CODE_MAPPING . INVALID_ARGUMENT ,
539- message : '`data` must be a non-null object.'
540- } ) ;
541- }
542-
543- try {
544- const { capitalized, camelCase } = this . getTableNames ( tableName ) ;
545- const keys = this . getFieldsString ( data ) ;
546- const mutation =
547- `mutation($data: ${ capitalized } _Data! @allow(fields: "${ keys } ")) {
548- ${ camelCase } _insert(data: $data)
549- }` ;
550-
551- return this . executeGraphql < GraphQlResponse , { data : Variables } > ( mutation , { variables : { data } } )
552- . catch ( this . handleBulkImportErrors ) ;
553- } catch ( e : any ) {
554- throw new FirebaseDataConnectError ( {
555- code : DATA_CONNECT_ERROR_CODE_MAPPING . INTERNAL ,
556- message : `Failed to construct insert mutation: ${ e . message } ` ,
557- cause : e ,
558- } ) ;
559- }
523+ return this . executeSingleMutation < GraphQlResponse , Variables > ( tableName , data , 'insert' ) ;
560524 }
561525
562526 /**
@@ -566,42 +530,7 @@ export class DataConnectApiClient {
566530 tableName : string ,
567531 data : Variables ,
568532 ) : Promise < ExecuteGraphqlResponse < GraphQlResponse > > {
569- if ( ! validator . isNonEmptyString ( tableName ) ) {
570- throw new FirebaseDataConnectError ( {
571- code : DATA_CONNECT_ERROR_CODE_MAPPING . INVALID_ARGUMENT ,
572- message : '`tableName` must be a non-empty string.'
573- } ) ;
574- }
575- if ( ! validator . isNonEmptyArray ( data ) ) {
576- throw new FirebaseDataConnectError ( {
577- code : DATA_CONNECT_ERROR_CODE_MAPPING . INVALID_ARGUMENT ,
578- message : '`data` must be a non-empty array for insertMany.' ,
579- } ) ;
580- }
581- if ( data . length > 10000 ) {
582- throw new FirebaseDataConnectError ( {
583- code : DATA_CONNECT_ERROR_CODE_MAPPING . INVALID_ARGUMENT ,
584- message : '`data` array exceeds the maximum limit of 10,000 items.'
585- } ) ;
586- }
587-
588- try {
589- const { capitalized, camelCase } = this . getTableNames ( tableName ) ;
590- const keys = this . getFieldsString ( data ) ;
591- const mutation =
592- `mutation($data: [${ capitalized } _Data!]! @allow(fields: "${ keys } ")) {
593- ${ camelCase } _insertMany(data: $data)
594- }` ;
595-
596- return this . executeGraphql < GraphQlResponse , { data : Variables } > ( mutation , { variables : { data } } )
597- . catch ( this . handleBulkImportErrors ) ;
598- } catch ( e : any ) {
599- throw new FirebaseDataConnectError ( {
600- code : DATA_CONNECT_ERROR_CODE_MAPPING . INTERNAL ,
601- message : `Failed to construct insertMany mutation: ${ e . message } ` ,
602- cause : e ,
603- } ) ;
604- }
533+ return this . executeBulkMutation < GraphQlResponse , Variables > ( tableName , data , 'insertMany' ) ;
605534 }
606535
607536 /**
@@ -610,6 +539,24 @@ export class DataConnectApiClient {
610539 public async upsert < GraphQlResponse , Variables extends object > (
611540 tableName : string ,
612541 data : Variables ,
542+ ) : Promise < ExecuteGraphqlResponse < GraphQlResponse > > {
543+ return this . executeSingleMutation < GraphQlResponse , Variables > ( tableName , data , 'upsert' ) ;
544+ }
545+
546+ /**
547+ * Insert multiple rows into the specified table, or update them if they already exist.
548+ */
549+ public async upsertMany < GraphQlResponse , Variables extends Array < unknown > > (
550+ tableName : string ,
551+ data : Variables ,
552+ ) : Promise < ExecuteGraphqlResponse < GraphQlResponse > > {
553+ return this . executeBulkMutation < GraphQlResponse , Variables > ( tableName , data , 'upsertMany' ) ;
554+ }
555+
556+ private async executeSingleMutation < GraphQlResponse , Variables extends object > (
557+ tableName : string ,
558+ data : Variables ,
559+ operationType : 'insert' | 'upsert'
613560 ) : Promise < ExecuteGraphqlResponse < GraphQlResponse > > {
614561 if ( ! validator . isNonEmptyString ( tableName ) ) {
615562 throw new FirebaseDataConnectError ( {
@@ -620,8 +567,8 @@ export class DataConnectApiClient {
620567 if ( validator . isArray ( data ) ) {
621568 throw new FirebaseDataConnectError ( {
622569 code : DATA_CONNECT_ERROR_CODE_MAPPING . INVALID_ARGUMENT ,
623- message : '` data` must be an object, not an array, for single upsert. For arrays, please use '
624- + '`upsertMany ` function.'
570+ message : `\` data\ ` must be an object, not an array, for single ${ operationType } .\
571+ For arrays, please use \` ${ operationType } Many\ ` function.`
625572 } ) ;
626573 }
627574 if ( ! validator . isNonNullObject ( data ) ) {
@@ -636,26 +583,24 @@ export class DataConnectApiClient {
636583 const keys = this . getFieldsString ( data ) ;
637584 const mutation =
638585 `mutation($data: ${ capitalized } _Data! @allow(fields: "${ keys } ")) {
639- ${ camelCase } _upsert (data: $data)
586+ ${ camelCase } _ ${ operationType } (data: $data)
640587 }` ;
641588
642589 return this . executeGraphql < GraphQlResponse , { data : Variables } > ( mutation , { variables : { data } } )
643590 . catch ( this . handleBulkImportErrors ) ;
644591 } catch ( e : any ) {
645592 throw new FirebaseDataConnectError ( {
646593 code : DATA_CONNECT_ERROR_CODE_MAPPING . INTERNAL ,
647- message : `Failed to construct upsert mutation: ${ e . message } ` ,
594+ message : `Failed to construct ${ operationType } mutation: ${ e . message } ` ,
648595 cause : e ,
649596 } ) ;
650597 }
651598 }
652599
653- /**
654- * Insert multiple rows into the specified table, or update them if they already exist.
655- */
656- public async upsertMany < GraphQlResponse , Variables extends Array < unknown > > (
600+ private async executeBulkMutation < GraphQlResponse , Variables extends Array < unknown > > (
657601 tableName : string ,
658602 data : Variables ,
603+ operationType : 'insertMany' | 'upsertMany'
659604 ) : Promise < ExecuteGraphqlResponse < GraphQlResponse > > {
660605 if ( ! validator . isNonEmptyString ( tableName ) ) {
661606 throw new FirebaseDataConnectError ( {
@@ -666,7 +611,7 @@ export class DataConnectApiClient {
666611 if ( ! validator . isNonEmptyArray ( data ) ) {
667612 throw new FirebaseDataConnectError ( {
668613 code : DATA_CONNECT_ERROR_CODE_MAPPING . INVALID_ARGUMENT ,
669- message : '` data` must be a non-empty array for upsertMany.'
614+ message : `\` data\ ` must be a non-empty array for ${ operationType } .`
670615 } ) ;
671616 }
672617 if ( data . length > 10000 ) {
@@ -681,15 +626,15 @@ export class DataConnectApiClient {
681626 const keys = this . getFieldsString ( data ) ;
682627 const mutation =
683628 `mutation($data: [${ capitalized } _Data!]! @allow(fields: "${ keys } ")) {
684- ${ camelCase } _upsertMany (data: $data)
629+ ${ camelCase } _ ${ operationType } (data: $data)
685630 }` ;
686631
687632 return this . executeGraphql < GraphQlResponse , { data : Variables } > ( mutation , { variables : { data } } )
688633 . catch ( this . handleBulkImportErrors ) ;
689634 } catch ( e : any ) {
690635 throw new FirebaseDataConnectError ( {
691636 code : DATA_CONNECT_ERROR_CODE_MAPPING . INTERNAL ,
692- message : `Failed to construct upsertMany mutation: ${ e . message } ` ,
637+ message : `Failed to construct ${ operationType } mutation: ${ e . message } ` ,
693638 cause : e ,
694639 } ) ;
695640 }
0 commit comments