Passed
Push — master ( 564e06...aaf712 )
by Darko
08:16
created

CreateManticoreIndexes::handle()   B

Complexity

Conditions 5
Paths 7

Size

Total Lines 80
Code Lines 43

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 43
c 2
b 1
f 0
dl 0
loc 80
rs 8.9208
cc 5
nc 7
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace App\Console\Commands;
4
5
use Illuminate\Console\Command;
6
use Manticoresearch\Client;
7
use Manticoresearch\Exceptions\ResponseException;
8
use Manticoresearch\Index;
0 ignored issues
show
Bug introduced by
The type Manticoresearch\Index was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
10
class CreateManticoreIndexes extends Command
11
{
12
    /**
13
     * The name and signature of the console command.
14
     *
15
     * @var string
16
     */
17
    protected $signature = 'manticore:create-indexes
18
                                        {--drop : Drop existing indexes before creating}';
19
20
    /**
21
     * The console command description.
22
     *
23
     * @var string
24
     */
25
    protected $description = 'Create Manticore Search indexes based on configuration';
26
27
    protected Client $client;
28
29
    /**
30
     * Execute the console command.
31
     */
32
    public function handle(): int
33
    {
34
        $this->info('Creating Manticore Search indexes...');
35
36
        $dropExisting = $this->option('drop');
37
38
        // Get connection details from config
39
        $host = config('sphinxsearch.host', '127.0.0.1');
40
        $port = config('sphinxsearch.port', 9308);
41
42
        // Create client
43
        $this->client = new Client([
44
            'host' => $host,
45
            'port' => $port,
46
        ]);
47
48
        // We'll skip checking for data_dir this way since it may not be accessible via API
49
        // but instead provide better error handling during index creation
50
51
        // If you encounter data_dir errors, ensure it's properly set in manticore.conf:
52
        // data_dir = /path/to/data
53
        // And make sure the path exists and has proper permissions
54
55
        try {
56
            $this->client->nodes()->status();
57
        } catch (\Exception $e) {
58
            $this->error('Failed to connect to Manticore Search: '.$e->getMessage());
59
            $this->info('Please check if Manticore Search is running and properly configured.');
60
61
            return 1;
62
        }
63
64
        // Define indexes and their schema
65
        $indexes = [
66
            'releases_rt' => [
67
                'settings' => [
68
                    'min_prefix_len' => 0,
69
                    'min_infix_len' => 2,
70
                ],
71
                'columns' => [
72
                    'name' => ['type' => 'text'],
73
                    'searchname' => ['type' => 'text'],
74
                    'fromname' => ['type' => 'text'],
75
                    'filename' => ['type' => 'text'],
76
                    'categories_id' => ['type' => 'text'],
77
                    'dummy' => ['type' => 'integer', 'attribute' => true],
78
                ],
79
            ],
80
            'predb_rt' => [
81
                'settings' => [
82
                    'min_prefix_len' => 0,
83
                    'min_infix_len' => 2,
84
                ],
85
                'columns' => [
86
                    'title' => ['type' => 'text', 'attribute' => true],
87
                    'filename' => ['type' => 'text', 'attribute' => true],
88
                    'dummy' => ['type' => 'integer', 'attribute' => true],
89
                    'source' => ['type' => 'string', 'attribute' => true],
90
                ],
91
            ],
92
        ];
93
94
        $hasErrors = false;
95
96
        // Create each index
97
        foreach ($indexes as $indexName => $schema) {
98
            if (! $this->createIndex($indexName, $schema, $dropExisting)) {
0 ignored issues
show
Bug introduced by
$dropExisting of type string is incompatible with the type boolean expected by parameter $dropExisting of App\Console\Commands\Cre...eIndexes::createIndex(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

98
            if (! $this->createIndex($indexName, $schema, /** @scrutinizer ignore-type */ $dropExisting)) {
Loading history...
99
                $hasErrors = true;
100
            }
101
        }
102
103
        if ($hasErrors) {
104
            $this->error('Some errors occurred during index creation.');
105
106
            return 1;
107
        }
108
109
        $this->info('All Manticore Search indexes created successfully!');
110
111
        return 0;
112
    }
113
114
    /**
115
     * Create a single index with error handling.
116
     */
117
    protected function createIndex(string $indexName, array $schema, bool $dropExisting): bool
118
    {
119
        $this->info("Creating {$indexName} index...");
120
        $indices = $this->client->tables();
121
122
        try {
123
            // Optionally drop existing index
124
            if ($dropExisting) {
125
                try {
126
                    $this->info("Dropping existing {$indexName} index...");
127
                    $indices->drop(['index' => $indexName, 'body' => ['silent' => true]]);
128
                    $this->info("Successfully dropped {$indexName} index.");
129
                } catch (ResponseException $e) {
130
                    if (! str_contains($e->getMessage(), 'unknown index')) {
131
                        $this->warn("Warning when dropping {$indexName} index: ".$e->getMessage());
132
                    }
133
                }
134
            }
135
136
            // Instead of checking if index exists (which doesn't work),
137
            // try to create it directly and handle any errors
138
            // that might occur if it already exists
139
            $response = $indices->create([
140
                'index' => $indexName,
141
                'body' => $schema,
142
            ]);
143
144
            $this->info("Successfully created {$indexName} index.");
145
            $this->line('Response: '.json_encode($response, JSON_PRETTY_PRINT));
146
147
            return true;
148
        } catch (ResponseException $e) {
149
            // Check if the error is because the index already exists
150
            if (str_contains($e->getMessage(), 'already exists')) {
151
                $this->warn("Index {$indexName} already exists. Use --drop option to recreate it.");
152
153
                return true;
154
            }
155
156
            $this->error("Failed to create {$indexName} index: ".$e->getMessage());
157
158
            return false;
159
        } catch (\Exception $e) {
160
            $this->error("Failed to create {$indexName} index: ".$e->getMessage());
161
162
            return false;
163
        }
164
    }
165
}
166