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 }