@@ -440,3 +440,123 @@ def dependencies(self) -> List[str]:
440440 return result
441441 finally :
442442 core .BNFreeStringList (deps , count .value )
443+
444+
445+ class DiffState :
446+ def __init__ (self , logger = None , handle = None ):
447+ if handle is not None :
448+ self .handle = core .handle_of_type (handle , core .BNDiffState )
449+ else :
450+ assert logger is not None , "Need logger to construct diff state"
451+ self .handle = core .BNCreateDiffState (logger .handle )
452+
453+ def __del__ (self ):
454+ core .BNFreeDiffState (self .handle )
455+
456+ @property
457+ def errors (self ) -> List [str ]:
458+ """Get list of error messages (read-only)"""
459+ count = ctypes .c_size_t ()
460+ errors = core .BNGetDiffStateErrors (self .handle , ctypes .byref (count ))
461+ try :
462+ result = []
463+ for i in range (0 , count .value ):
464+ result .append (core .pyNativeStr (errors [i ]))
465+ return result
466+ finally :
467+ core .BNFreeStringList (errors , count .value )
468+
469+ def clear_errors (self ):
470+ """Clear all error messages"""
471+ core .BNClearDiffStateErrors (self .handle )
472+
473+ def generate_diff (
474+ self , base : DatabaseObject , left : DatabaseObject , right : DatabaseObject
475+ ) -> Optional ['DiffObject' ]:
476+ """Generate a three-way diff database objects"""
477+ handle = core .BNDiffStateGenerateDiff (
478+ self .handle , base .handle , left .handle , right .handle
479+ )
480+ if handle is None :
481+ return None
482+ return DiffObject (handle = handle )
483+
484+ def apply_diff (
485+ self , diff : 'DiffObject' , base : DatabaseObject , left : DatabaseObject ,
486+ right : DatabaseObject , result : DatabaseObject
487+ ) -> bool :
488+ """Apply a diff to database objects"""
489+ return core .BNDiffStateApplyDiff (
490+ self .handle , diff .handle , base .handle , left .handle , right .handle ,
491+ result .handle
492+ )
493+
494+ def is_diffed (self , object : DatabaseObject ) -> bool :
495+ """Check if an object was used during generate_diff"""
496+ return core .BNDiffStateIsDiffed (self .handle , object .handle )
497+
498+ def is_applied (self , object : 'DiffObject' ) -> bool :
499+ """Check if an object was used during apply_diff"""
500+ return core .BNDiffStateIsApplied (self .handle , object .handle )
501+
502+
503+ class DiffObject :
504+ def __init__ (self , handle ):
505+ self .handle = core .handle_of_type (handle , core .BNDiffObject )
506+
507+ def __del__ (self ):
508+ core .BNFreeDiffObject (self .handle )
509+
510+ @property
511+ def base (self ) -> Optional [str ]:
512+ """Get the base path for the diff object (read-only)"""
513+ value = core .BNGetDiffObjectBase (self .handle )
514+ if value is None :
515+ return None
516+ return value
517+
518+ @property
519+ def left (self ) -> Optional [str ]:
520+ """Get the left path for the diff object (read-only)"""
521+ value = core .BNGetDiffObjectLeft (self .handle )
522+ if value is None :
523+ return None
524+ return value
525+
526+ @property
527+ def right (self ) -> Optional [str ]:
528+ """Get the right path for the diff object (read-only)"""
529+ value = core .BNGetDiffObjectRight (self .handle )
530+ if value is None :
531+ return None
532+ return value
533+
534+ @property
535+ def children (self ) -> Dict [str , 'DiffObject' ]:
536+ """Get dictionary of child diff objects (read-only)"""
537+ names = ctypes .POINTER (ctypes .c_char_p )()
538+ objects = ctypes .POINTER (ctypes .POINTER (core .BNDiffObject ))()
539+ count = core .BNGetDiffObjectChildren (
540+ self .handle , ctypes .byref (names ), ctypes .byref (objects )
541+ )
542+
543+ result = {}
544+ try :
545+ for i in range (count ):
546+ name = core .pyNativeStr (names [i ])
547+ obj_handle = core .BNNewDiffObjectReference (objects [i ])
548+ result [name ] = DiffObject (handle = obj_handle )
549+ return result
550+ finally :
551+ core .BNFreeDiffObjectList (objects , count )
552+ core .BNFreeStringList (names , count )
553+
554+ @property
555+ def strategy (self ) -> 'MergeStrategy' :
556+ """Get the merge strategy for this diff object"""
557+ return core .BNGetDiffObjectMergeStrategy (self .handle )
558+
559+ @strategy .setter
560+ def strategy (self , value : 'MergeStrategy' ):
561+ """Set the merge strategy for this diff object"""
562+ core .BNSetDiffObjectMergeStrategy (self .handle , value )
0 commit comments