github.com/christoph-karpowicz/db_mediator@v0.0.0-20210207102849-61a28a1071d8/internal/server/synch/link.go (about)

     1  package synch
     2  
     3  import (
     4  	"log"
     5  	"strings"
     6  	"sync"
     7  
     8  	"github.com/christoph-karpowicz/db_mediator/internal/server/cfg"
     9  	"github.com/google/uuid"
    10  )
    11  
    12  // Link represents a single link in the config file like:
    13  // [example_node1.example_column1 WHERE ...] TO [example_node2.example_column2 WHERE ...]
    14  type Link struct {
    15  	id           string
    16  	synch        Synchronizer
    17  	Cmd          string
    18  	source       *node
    19  	target       *node
    20  	sourceTable  *table
    21  	targetTable  *table
    22  	sourceColumn string
    23  	targetColumn string
    24  	sourceWhere  string
    25  	targetWhere  string
    26  	sourceExID   string
    27  	targetExID   string
    28  	pairs        []*Pair
    29  }
    30  
    31  func createLink(synch Synchronizer, link map[string]string) *Link {
    32  
    33  	sourceNode, sourceNodeFound := synch.GetNodes()[link[cfg.PSUBEXP_SOURCE_NODE]]
    34  	if !sourceNodeFound {
    35  		panic("[create link] ERROR: source node not found.")
    36  	}
    37  	targetNode, targetNodeFound := synch.GetNodes()[link[cfg.PSUBEXP_TARGET_NODE]]
    38  	if !targetNodeFound {
    39  		panic("[create link] ERROR: target node not found.")
    40  	}
    41  
    42  	newLink := Link{
    43  		id:           uuid.New().String(),
    44  		synch:        synch,
    45  		Cmd:          link["cmd"],
    46  		source:       sourceNode,
    47  		target:       targetNode,
    48  		sourceTable:  sourceNode.tbl,
    49  		targetTable:  targetNode.tbl,
    50  		sourceColumn: link[cfg.PSUBEXP_SOURCE_COLUMN],
    51  		targetColumn: link[cfg.PSUBEXP_TARGET_COLUMN],
    52  		sourceWhere:  link[cfg.PSUBEXP_SOURCE_WHERE],
    53  		targetWhere:  link[cfg.PSUBEXP_TARGET_WHERE],
    54  	}
    55  
    56  	if synch.GetConfig().Match.Method == "ids" {
    57  		for _, marg := range synch.GetConfig().Match.Args {
    58  			margSplt := strings.Split(marg, ".")
    59  			margNode := margSplt[0]
    60  			margColumn := margSplt[1]
    61  			if margNode == newLink.source.cfg.Name {
    62  				newLink.sourceExID = margColumn
    63  			} else if margNode == newLink.target.cfg.Name {
    64  				newLink.targetExID = margColumn
    65  			}
    66  		}
    67  	}
    68  
    69  	return &newLink
    70  }
    71  
    72  func (l Link) GetID() string {
    73  	return l.id
    74  }
    75  
    76  func (l *Link) comparePair(src *record, c chan bool) {
    77  	var pairFound bool = false
    78  
    79  	for j := range *l.targetTable.activeRecords {
    80  		target := (*l.targetTable.activeRecords)[j]
    81  
    82  		if l.synch.GetConfig().Match.Method == "ids" {
    83  			sourceExternalID, sourceOk := src.Data[l.sourceExID]
    84  			targetExternalID, targetOk := target.Data[l.targetExID]
    85  
    86  			if !sourceOk || !targetOk {
    87  				continue
    88  			}
    89  
    90  			if areEqual, err := areEqual(sourceExternalID, targetExternalID); err != nil {
    91  				log.Println(err)
    92  			} else if areEqual {
    93  				newPair := createPair(l, src, target)
    94  				l.pairs = append(l.pairs, newPair)
    95  				pairFound = true
    96  				src.PairedIn = append(src.PairedIn, l)
    97  				target.PairedIn = append(target.PairedIn, l)
    98  			}
    99  		}
   100  	}
   101  
   102  	c <- pairFound
   103  }
   104  
   105  // createPairs for each active record in source database finds a corresponding acitve record in target database.
   106  func (l *Link) createPairs(wg *sync.WaitGroup) {
   107  	for i := range *l.sourceTable.activeRecords {
   108  		ch := make(chan bool)
   109  		source := (*l.sourceTable.activeRecords)[i]
   110  
   111  		go l.comparePair(source, ch)
   112  
   113  		if !<-ch {
   114  			newPair := createPair(l, source, nil)
   115  			l.pairs = append(l.pairs, newPair)
   116  		}
   117  	}
   118  	wg.Done()
   119  }
   120  
   121  func (l *Link) reset() {
   122  	l.sourceTable.activeRecords = nil
   123  	l.targetTable.activeRecords = nil
   124  	l.pairs = nil
   125  }