method sync documentation in bbn\Db\Sync2
function(bbn\Db $db, $dbs = '', $sync_table = '', $num_try = 0)
  {
    if (!self::isInit()) {
      die("DB sync is not initiated");
    }
    self::disable();
    $mode_db = $this->current_connection->getErrorMode();
    $mode_dbs = $this->sync_connection->getErrorMode();
    $this->current_connection->setErrorMode("continue");
    $this->sync_connection->setErrorMode("continue");
    $num_try++;
    $to_log = [
      'deleted_sync' => 0,
      'deleted_real' => 0,
      'updated_sync' => 0,
      'updated_real' => 0,
      'inserted_sync' => 0,
      'inserted_real' => 0,
      'num_problems' => 0,
      'problems' => []
    ];
    $to_log['deleted_sync'] = self::deleteCompleted();
    $retry = false;
    // Selecting the entries inserted
    $ds = $this->sync_connection->rselectAll(
      $this->sync_table, ['id', 'tab', 'vals', 'chrono'], [
      ['db', '!=', $this->current_connection->getCurrent()],
      ['state', '=', 0],
      ['action', 'LIKE', 'INSERT']
      ], [
      'chrono' => 'ASC',
      'id' => 'ASC'
      ]
    );
    // They just have to be inserted
    foreach ($ds as $i => $d){
      if (isset($this->methods['cbf1'])) {
        self::cbf1($d);
      }
      $vals = X::jsonBase64Decode($d['vals']);
      if (!\is_array($vals)) {
        $to_log['num_problems']++;
        $to_log['problems'][] = "Hey, look urgently at the row $d[id]!";
      }
      elseif ($this->current_connection->insert($d['tab'], $vals)) {
        if (isset($this->methods['cbf2'])) {
          self::cbf2($d);
        }
        $to_log['inserted_sync']++;
        $this->sync_connection->update($this->sync_table, ["state" => 1], ["id" => $d['id']]);
      }
      elseif ($this->current_connection->select($d['tab'], [], $vals)) {
        $this->sync_connection->update($this->sync_table, ["state" => 1], ["id" => $d['id']]);
      }
      else{
        if ($num_try > $this->max_retry) {
          $to_log['num_problems']++;
          $to_log['problems'][] = "Problem while syncing (insert), check data with status 5 and ID ".$d['id'];
          $this->sync_connection->update($this->sync_table, ["state" => 5], ["id" => $d['id']]);
        }
        $retry = 1;
      }
    }
    // Selecting the entries modified and deleted in the twin DB,
    // ordered by table and rows (so the same go together)
    $ds = $this->sync_connection->rselectAll(
      $this->sync_table, ['id', 'tab', 'action', 'rows', 'vals', 'chrono'], [
      ['db', '!=', $this->current_connection->getCurrent()],
      ['state', '=', 0],
      ['rows', '!=', '[]'],
      ['action', '!=', 'insert']
      ], [
      'tab' => 'ASC',
      'rows' => 'ASC',
      'chrono' => 'ASC',
      'id' => 'ASC'
      ]
    );
    foreach ($ds as $i => $d){
      // Executing the first callback
      $d['rows'] = X::jsonBase64Decode($d['rows']);
      $d['vals'] = X::jsonBase64Decode($d['vals']);
      if (isset($this->methods['cbf1'])) {
        self::cbf1($d);
      }
      // Proceeding to the actions: delete is before
      if (strtolower($d['action']) === 'delete') {
        if ($this->current_connection->delete($d['tab'], $d['rows'])) {
          $this->sync_connection->update($this->sync_table, ["state" => 1], ["id" => $d['id']]);
          $to_log['deleted_real']++;
        }
        elseif (!$this->current_connection->select($d['tab'], [], $d['rows'])) {
          $this->sync_connection->update($this->sync_table, ["state" => 1], ["id" => $d['id']]);
        }
        else{
          if ($num_try > $this->max_retry) {
            $this->sync_connection->update($this->sync_table, ["state" => 5], ["id" => $d['id']]);
            $to_log['num_problems']++;
            $to_log['problems'][] = "Problem while syncing (delete), check data with status 5 and ID ".$d['id'];
          }
          $retry = 1;
        }
      }
      // Checking if there is another change done to this record and when in the twin DB
      $next_time = (
              isset($ds[$i+1]) &&
              ($ds[$i+1]['tab'] === $d['tab']) &&
              ($ds[$i+1]['rows'] === $d['rows'])
            ) ? $ds[$i+1]['chrono'] : microtime();
      // Looking for the actions done on this specific record in our database
      // between the twin change and the next (or now if there is no other change)
      $each = $this->sync_connection->rselectAll(
        $this->sync_table, ['id', 'chrono', 'action', 'vals'], [
        ['db', '=', $this->current_connection->getCurrent()],
        ['tab', '=', $d['tab']],
        ['rows', '=', $d['rows']],
        ['chrono', '>=', $d['chrono']],
        ['chrono', '<', $next_time],
        ]
      );
      if (\count($each) > 0) {
        $to_log['num_problems']++;
        $to_log['problems'][] = "Conflict!";
        $to_log['problems'][] = $d;
        foreach ($each as $e){
          $e['vals'] = X::jsonBase64Decode($e['vals']);
          // If it's deleted locally and updated on the twin we restore
          if (strtolower($e['action']) === 'delete') {
            if (strtolower($d['action']) === 'update') {
              if (!$this->current_connection->insertUpdate(
                $d['tab'],
                X::mergeArrays(
                  $e['vals'],
                  $d['vals']
                )
              )
              ) {
                $to_log['num_problems']++;
                $to_log['problems'][] = "insert_update number 1 had a problem";
              }
            }
          }
          // If it's updated locally and deleted in the twin we restore
          elseif (strtolower($e['action']) === 'update') {
            if (strtolower($d['action']) === 'delete') {
              if (!$this->current_connection->insertUpdate($d['tab'], X::mergeArrays($d['vals'], $e['vals']))) {
                $to_log['num_problems']++;
                $to_log['problems'][] = "insert_update had a problem";
              }
            }
            // If it's updated locally and in the twin we merge the values for the update
            elseif (strtolower($d['action']) === 'update') {
              $d['vals'] = X::mergeArrays($d['vals'], $e['vals']);
            }
          }
        }
      }
      // Proceeding to the actions update is after in case we needed to restore
      if (strtolower($d['action']) === 'update') {
        X::log(X::mergeArrays($d['rows'], $d['vals']), 'synct');
        if ($this->current_connection->update($d['tab'], $d['vals'], $d['rows'])) {
          $this->sync_connection->update($this->sync_table, ["state" => 1], ["id" => $d['id']]);
          $to_log['updated_real']++;
        }
        elseif ($this->current_connection->count($d['tab'], X::mergeArrays($d['rows'], $d['vals']))) {
          $this->sync_connection->update($this->sync_table, ["state" => 1], ["id" => $d['id']]);
        }
        else{
          if ($num_try > $this->max_retry) {
            $this->sync_connection->update($this->sync_table, ["state" => 5], ["id" => $d['id']]);
            $to_log['num_problems']++;
            $to_log['problems'][] = "Problem while syncing (update), check data with status 5 and ID ".$d['id'];
          }
          $retry = 1;
        }
      }
      // Callback number 2
      if (isset($this->methods['cbf2'])) {
        self::cbf2($d);
      }
    }
    $res = [];
    foreach ($to_log as $k => $v){
      if (!empty($v)) {
        $res[$k] = $v;
      }
    }
    $this->current_connection->setErrorMode($mode_db);
    $this->sync_connection->setErrorMode($mode_dbs);
    self::enable();
    if ($retry && ( $num_try <= $this->max_retry )) {
      $res = X::mergeArrays($res, self::sync($db, $dbs, $sync_table, $num_try));
    }
    return $res;
  }
  BBN is a suite of PHP and JS libraries and VueJS components - all open-source! bbn.io, build applications, the quick way
  
  
    
    
      
        
        
      
    
    
    
      
      
      
      
      
        
          
          
          
          
          
          
          
          
            
              
                
              
            
            
              
              This website uses cookies to ensure you get the best experience on our website.                
                
              
              
                
                
              
             
           
          
          
          
            
            © 2011-2025 
BBN Solutions