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

DatabaseFactory::nextId()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

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