@@ -530,11 +530,41 @@ func (mc *mongoDBConnector) executeMigration(migration types.Migration, dbName s
530530func (mc * mongoDBConnector ) executeMongoDBCommand (targetDB * mongo.Database , command string ) error {
531531 command = strings .TrimSpace (command )
532532
533- // Match pattern: db.collectionName.operation(...)
533+ // Match pattern: db.collectionName.operation(...) or db.getSiblingDB('dbname').collectionName.operation(...)
534534 if ! strings .HasPrefix (command , "db." ) {
535535 return nil // Skip non-db commands
536536 }
537537
538+ // Check for getSiblingDB pattern
539+ if strings .HasPrefix (command , "db.getSiblingDB(" ) {
540+ // Extract database name from getSiblingDB('dbname')
541+ start := strings .Index (command , "'" )
542+ if start == - 1 {
543+ start = strings .Index (command , "\" " )
544+ }
545+ if start == - 1 {
546+ return fmt .Errorf ("invalid getSiblingDB syntax: %s" , command )
547+ }
548+
549+ end := strings .Index (command [start + 1 :], "'" )
550+ if end == - 1 {
551+ end = strings .Index (command [start + 1 :], "\" " )
552+ }
553+ if end == - 1 {
554+ return fmt .Errorf ("invalid getSiblingDB syntax: %s" , command )
555+ }
556+
557+ dbName := command [start + 1 : start + 1 + end ]
558+ targetDB = mc .client .Database (dbName )
559+
560+ // Find the collection part after getSiblingDB('dbname').
561+ dotAfterDB := strings .Index (command [start + 1 + end :], "." )
562+ if dotAfterDB == - 1 {
563+ return fmt .Errorf ("invalid getSiblingDB syntax: %s" , command )
564+ }
565+ command = "db." + command [start + 1 + end + dotAfterDB + 1 :]
566+ }
567+
538568 // Extract collection name and operation
539569 parts := strings .SplitN (command [3 :], "." , 2 ) // Remove "db." prefix
540570 if len (parts ) < 2 {
@@ -559,6 +589,10 @@ func (mc *mongoDBConnector) executeMongoDBCommand(targetDB *mongo.Database, comm
559589 return mc .handleInsertOne (col , rest [opEnd :])
560590 case "createIndex" :
561591 return mc .handleCreateIndex (col , rest [opEnd :])
592+ case "updateMany" :
593+ return mc .handleUpdateMany (col , rest [opEnd :])
594+ case "updateOne" :
595+ return mc .handleUpdateOne (col , rest [opEnd :])
562596 default :
563597 common .LogWarn (mc .ctx , "Unsupported operation: %s" , operation )
564598 return nil
@@ -653,6 +687,104 @@ func (mc *mongoDBConnector) handleCreateIndex(col *mongo.Collection, args string
653687 return err
654688}
655689
690+ // handleUpdateMany executes updateMany operation
691+ func (mc * mongoDBConnector ) handleUpdateMany (col * mongo.Collection , args string ) error {
692+ return mc .handleUpdate (col , args , true )
693+ }
694+
695+ // handleUpdateOne executes updateOne operation
696+ func (mc * mongoDBConnector ) handleUpdateOne (col * mongo.Collection , args string ) error {
697+ return mc .handleUpdate (col , args , false )
698+ }
699+
700+ // handleUpdate executes update operations (updateOne or updateMany)
701+ func (mc * mongoDBConnector ) handleUpdate (col * mongo.Collection , args string , many bool ) error {
702+ // Extract filter and update documents from updateMany({filter}, {update}, {options})
703+ start := strings .Index (args , "{" )
704+ if start == - 1 {
705+ return fmt .Errorf ("invalid update syntax" )
706+ }
707+
708+ // Find the matching closing brace for the first argument (filter)
709+ braceCount := 0
710+ firstArgEnd := - 1
711+ for i := start ; i < len (args ); i ++ {
712+ if args [i ] == '{' {
713+ braceCount ++
714+ } else if args [i ] == '}' {
715+ braceCount --
716+ if braceCount == 0 {
717+ firstArgEnd = i
718+ break
719+ }
720+ }
721+ }
722+
723+ if firstArgEnd == - 1 {
724+ return fmt .Errorf ("invalid update syntax" )
725+ }
726+
727+ filterJSON := args [start : firstArgEnd + 1 ]
728+ filterJSON = mc .jsToJSON (filterJSON )
729+
730+ // Parse filter
731+ var filter bson.M
732+ if err := bson .UnmarshalExtJSON ([]byte (filterJSON ), false , & filter ); err != nil {
733+ return fmt .Errorf ("failed to parse filter: %v" , err )
734+ }
735+
736+ // Find second argument (update document)
737+ remaining := strings .TrimSpace (args [firstArgEnd + 1 :])
738+ if ! strings .HasPrefix (remaining , "," ) {
739+ return fmt .Errorf ("missing update document" )
740+ }
741+ remaining = strings .TrimSpace (remaining [1 :])
742+
743+ updateStart := strings .Index (remaining , "{" )
744+ if updateStart == - 1 {
745+ return fmt .Errorf ("invalid update document" )
746+ }
747+
748+ // Find the matching closing brace for the update document
749+ braceCount = 0
750+ updateEnd := - 1
751+ for i := updateStart ; i < len (remaining ); i ++ {
752+ if remaining [i ] == '{' {
753+ braceCount ++
754+ } else if remaining [i ] == '}' {
755+ braceCount --
756+ if braceCount == 0 {
757+ updateEnd = i
758+ break
759+ }
760+ }
761+ }
762+
763+ if updateEnd == - 1 {
764+ return fmt .Errorf ("invalid update document" )
765+ }
766+
767+ updateJSON := remaining [updateStart : updateEnd + 1 ]
768+ updateJSON = mc .jsToJSON (updateJSON )
769+
770+ // Handle new Date() - replace with current time in extended JSON format
771+ updateJSON = strings .ReplaceAll (updateJSON , "new Date()" , fmt .Sprintf ("{\" $date\" :\" %s\" }" , time .Now ().Format (time .RFC3339Nano )))
772+
773+ // Parse update document
774+ var update bson.M
775+ if err := bson .UnmarshalExtJSON ([]byte (updateJSON ), false , & update ); err != nil {
776+ return fmt .Errorf ("failed to parse update document: %v" , err )
777+ }
778+
779+ // Execute update
780+ if many {
781+ _ , err := col .UpdateMany (mc .ctx , filter , update )
782+ return err
783+ }
784+ _ , err := col .UpdateOne (mc .ctx , filter , update )
785+ return err
786+ }
787+
656788// jsToJSON converts JavaScript object notation to proper JSON
657789// Handles: {key: value} -> {"key": value}, {key: 'value'} -> {"key": "value"}
658790func (mc * mongoDBConnector ) jsToJSON (js string ) string {
0 commit comments