Completed
Pull Request — 8.x-2.x (#27)
by Frédéric G.
02:43
created

DatabaseFactory::nextId()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 28
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 18
nc 2
nop 2
dl 0
loc 28
rs 8.8571
c 0
b 0
f 0
1
<?php
2
namespace Drupal\mongodb;
3
4
use Drupal\Component\Render\FormattableMarkup;
5
use Drupal\Core\Site\Settings;
6
7
/**
8
 * Class DatabaseFactory.
9
 *
10
 * @package Drupal\mongodb
11
 */
12
class DatabaseFactory {
13
14
  /**
15
   * The Client factory service.
16
   *
17
   * @var \Drupal\mongodb\ClientFactory
18
   */
19
  protected $clientFactory;
20
21
  /**
22
   * The 'mongodb' database settings array.
23
   *
24
   * @var string[][]
25
   */
26
  protected $settings;
27
28
  /**
29
   * Constructor.
30
   *
31
   * @param \Drupal\mongodb\ClientFactory $client_factory
32
   *   The Client factory service.
33
   */
34
  public function __construct(ClientFactory $client_factory, Settings $settings) {
35
    $this->clientFactory = $client_factory;
36
    $this->settings = $settings->get('mongodb')['databases'];
37
  }
38
39
  /**
40
   * Return the MongoDB database matching an alias.
41
   *
42
   * @param string $alias
43
   *   The alias string, like "default".
44
   *
45
   * @return \MongoDB\Database|null
46
   *   The selected database, or NULL if an error occurred.
47
   */
48
  public function get($alias) {
49
    if (!isset($this->settings[$alias])) {
50
      throw new \InvalidArgumentException(new FormattableMarkup('Nonexistent database alias: @alias', [
51
        '@alias' => $alias,
52
      ]));
53
    }
54
    try {
55
      list($client_alias, $database) = $this->settings[$alias];
56
      $client = $this->clientFactory->get($client_alias);
57
      $result = $client->selectDatabase($database);
58
    }
59
    // Includes its descendant \MongoDb\Exception\InvalidArgumentException.
60
    catch (\InvalidArgumentException $e) {
61
      $result = NULL;
62
    }
63
64
    return $result;
65
  }
66
67
  /**
68
   * Return the next integer ID in a sequence. For numeric ids in collections.
69
   *
70
   * @param string $sequenceId
71
   *   The name of the sequence, typically a collection name in the current
72
   *   database.
73
   * @param int $value
74
   *   Optional. If given, the result will be at least 1 more that this.
75
   *
76
   * @return int
77
   *   The next id. It will be greater than $value, possibly by more than 1.
78
   */
79
  public function nextId($sequenceId = 'sequences', $value = 0) {
80
    $collection = $this->get('default')
81
      ->selectCollection('sequences');
82
    $sequenceSelector = ['_id' => $sequenceId];
83
84
    // Force the minimum if given.
85
    if ($value) {
86
      $selector = $sequenceSelector + [
87
          'value' => ['$lt' => $value],
88
        ];
89
      $update = [
90
        '$set' => ['value' => $value],
91
      ];
92
      $collection->updateOne($selector, $update);
93
    }
94
95
    // Then increment it.
96
    $update = [
97
      '$inc' => ['value' => 1],
98
    ];
99
    $options = [
100
      'upsert' => TRUE,
101
      'returnDocument' => FindOneAndUpdate::RETURN_DOCUMENT_AFTER,
102
    ];
103
    $document = $collection->findOneAndUpdate($sequenceSelector, $update, $options);
104
    $result = $document->value ?? 1;
105
    return $result;
106
  }
107
108
}
109