Passed
Push — master ( e0c5e8...7926db )
by P.R.
04:00
created

MySqlWorker::writeTwoPhases()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 4.7691

Importance

Changes 0
Metric Value
cc 4
eloc 11
nc 6
nop 2
dl 0
loc 20
ccs 7
cts 11
cp 0.6364
crap 4.7691
rs 9.9
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace SetBased\Stratum\MySql\Backend;
5
6
use SetBased\Stratum\Backend\Config;
7
use SetBased\Stratum\Backend\StratumStyle;
8
use SetBased\Stratum\MySql\Exception\MySqlConnectFailedException;
9
use SetBased\Stratum\MySql\Exception\MySqlDataLayerException;
10
use SetBased\Stratum\MySql\MySqlDataLayer;
11
use SetBased\Stratum\MySql\MySqlDefaultConnector;
12
use SetBased\Stratum\MySql\MySqlMetaDataLayer;
13
use Symfony\Component\Console\Formatter\OutputFormatter;
14
15
/**
16
 * Base class for commands which needs a connection to a MySQL instance.
17
 */
18
class MySqlWorker
19
{
20
  //--------------------------------------------------------------------------------------------------------------------
21
  /**
22
   * The meta data layer.
23
   *
24
   * @var MySqlMetaDataLayer
25
   */
26
  protected $dl;
27
28
  /**
29
   * The output object.
30
   *
31
   * @var StratumStyle
32
   */
33
  protected $io;
34
35
  /**
36
   * The settings from the PhpStratum configuration file.
37
   *
38
   * @var Config
39
   */
40
  protected $settings;
41
42
  //--------------------------------------------------------------------------------------------------------------------
43
  /**
44
   * Object constructor.
45
   *
46
   * @param Config       $settings The settings from the PhpStratum configuration file.
47
   * @param StratumStyle $io       The output object.
48
   */
49 1
  public function __construct(Config $settings, StratumStyle $io)
50
  {
51 1
    $this->settings = $settings;
52 1
    $this->io       = $io;
53 1
  }
54
55
  //--------------------------------------------------------------------------------------------------------------------
56
  /**
57
   * Disconnects from MySQL instance.
58
   */
59 1
  public function disconnect()
60
  {
61 1
    if ($this->dl!==null)
62
    {
63 1
      $this->dl->disconnect();
64 1
      $this->dl = null;
65
    }
66 1
  }
67
68
  //--------------------------------------------------------------------------------------------------------------------
69
  /**
70
   * Connects to a MySQL instance.
71
   *
72
   * @throws MySqlConnectFailedException
73
   * @throws MySqlDataLayerException
74
   */
75 1
  protected function connect(): void
76
  {
77 1
    $host     = $this->settings->manString('database.host');
78 1
    $user     = $this->settings->manString('database.user');
79 1
    $password = $this->settings->manString('database.password');
80 1
    $database = $this->settings->manString('database.database');
81 1
    $port     = $this->settings->manInt('database.port', 3306);
82
83 1
    $connector = new MySqlDefaultConnector($host, $user, $password, $database, $port);
84 1
    $dataLayer = new MySqlDataLayer($connector);
85 1
    $dataLayer->connect();
86
87 1
    $this->dl = new MySqlMetaDataLayer($dataLayer, $this->io);
88 1
  }
89
90
  //--------------------------------------------------------------------------------------------------------------------
91
  /**
92
   * Writes a file in two phase to the filesystem.
93
   *
94
   * First write the data to a temporary file (in the same directory) and than renames the temporary file. If the file
95
   * already exists and its content is equal to the data that must be written no action  is taken. This has the
96
   * following advantages:
97
   * * In case of some write error (e.g. disk full) the original file is kept in tact and no file with partially data
98
   * is written.
99
   * * Renaming a file is atomic. So, running processes will never read a partially written data.
100
   *
101
   * @param string $filename The name of the file were the data must be stored.
102
   * @param string $data     The data that must be written.
103
   */
104 1
  protected function writeTwoPhases(string $filename, string $data): void
105
  {
106 1
    $write_flag = true;
107 1
    if (file_exists($filename))
108
    {
109 1
      $old_data = file_get_contents($filename);
110 1
      if ($data==$old_data) $write_flag = false;
111
    }
112
113 1
    if ($write_flag)
114
    {
115
      $tmp_filename = $filename.'.tmp';
116
      file_put_contents($tmp_filename, $data);
117
      rename($tmp_filename, $filename);
118
119
      $this->io->text(sprintf('Wrote <fso>%s</fso>', OutputFormatter::escape($filename)));
120
    }
121
    else
122
    {
123 1
      $this->io->text(sprintf('File <fso>%s</fso> is up to date', OutputFormatter::escape($filename)));
124
    }
125 1
  }
126
127
  //--------------------------------------------------------------------------------------------------------------------
128
}
129
130
//----------------------------------------------------------------------------------------------------------------------
131