1
- require 'oj'
2
- require_relative ' ./schema.rb'
1
+ require "oj"
2
+ require_relative " ./schema"
3
3
4
4
class Litesearch ::Index
5
-
6
5
DEFAULT_SEARCH_OPTIONS = { limit : 25 , offset : 0 }
7
6
8
7
def initialize ( db , name )
@@ -17,7 +16,7 @@ def initialize(db, name)
17
16
# if they differ in tokenizer then rebuild if auto-rebuild is on (error otherwise)
18
17
# if they differ in both then update the structure and rebuild if auto-rebuild is on (error otherwise)
19
18
load_index ( name ) if exists? ( name )
20
-
19
+
21
20
if block_given?
22
21
schema = Litesearch ::Schema . new
23
22
schema . schema [ :name ] = name
@@ -33,54 +32,56 @@ def initialize(db, name)
33
32
end
34
33
prepare_statements
35
34
end
35
+ elsif exists? ( name )
36
+ load_index ( name )
37
+ prepare_statements
38
+ # an index already exists, load it from the database and return the index instance to the caller
36
39
else
37
- if exists? ( name )
38
- # an index already exists, load it from the database and return the index instance to the caller
39
- load_index ( name )
40
- prepare_statements
41
- else
42
- raise "index does not exist and no schema was supplied"
43
- end
40
+ raise "index does not exist and no schema was supplied"
44
41
end
45
42
end
46
-
43
+
47
44
def load_index ( name )
48
45
# we cannot use get_config_value here since the schema object is not created yet, should we allow something here?
49
- @schema = Litesearch ::Schema . new ( Oj . load ( @db . get_first_value ( "SELECT v from #{ name } _config where k = ?" , :litesearch_schema . to_s ) ) ) rescue nil
46
+ @schema = begin
47
+ Litesearch ::Schema . new ( Oj . load ( @db . get_first_value ( "SELECT v from #{ name } _config where k = ?" , :litesearch_schema . to_s ) ) )
48
+ rescue
49
+ nil
50
+ end
50
51
raise "index configuration not found, either corrupted or not a litesearch index!" if @schema . nil?
51
52
self
52
53
end
53
-
54
+
54
55
def modify
55
56
schema = Litesearch ::Schema . new
56
57
yield schema
57
58
schema . schema [ :name ] = @schema . schema [ :name ]
58
59
do_modify ( schema )
59
60
end
60
-
61
+
61
62
def rebuild!
62
63
@db . transaction ( :immediate ) do
63
64
do_rebuild
64
65
end
65
66
end
66
-
67
+
67
68
def add ( document )
68
69
@stmts [ :insert ] . execute! ( document )
69
- return @db . last_insert_row_id
70
+ @db . last_insert_row_id
70
71
end
71
-
72
+
72
73
def remove ( id )
73
74
@stmts [ :delete ] . execute! ( id )
74
75
end
75
-
76
+
76
77
def count ( term = nil )
77
78
if term
78
79
@stmts [ :count ] . execute! ( term ) [ 0 ] [ 0 ]
79
80
else
80
- @stmts [ :count_all ] . execute! ( ) [ 0 ] [ 0 ]
81
+ @stmts [ :count_all ] . execute! [ 0 ] [ 0 ]
81
82
end
82
83
end
83
-
84
+
84
85
# search options include
85
86
# limit: how many records to return
86
87
# offset: start from which record
@@ -90,31 +91,30 @@ def search(term, options = {})
90
91
rs = @stmts [ :search ] . execute ( term , options [ :limit ] , options [ :offset ] )
91
92
if @db . results_as_hash
92
93
rs . each_hash do |hash |
93
- result << hash
94
+ result << hash
94
95
end
95
96
else
96
97
result = rs . to_a
97
- end
98
+ end
98
99
result
99
100
end
100
-
101
+
101
102
def clear!
102
103
@stmts [ :delete_all ] . execute! ( id )
103
104
end
104
-
105
+
105
106
def drop!
106
107
if @schema . get ( :type ) == :backed
107
108
@db . execute_batch ( @schema . sql_for ( :drop_primary_triggers ) )
108
- if secondary_triggers_sql = @schema . sql_for ( :create_secondary_triggers )
109
+ if @schema . sql_for ( :create_secondary_triggers )
109
110
@db . execute_batch ( @schema . sql_for ( :drop_secondary_triggers ) )
110
111
end
111
112
end
112
113
@db . execute ( @schema . sql_for ( :drop ) )
113
114
end
114
-
115
-
115
+
116
116
private
117
-
117
+
118
118
def exists? ( name )
119
119
@db . get_first_value ( "SELECT count(*) FROM SQLITE_MASTER WHERE name = ? AND type = 'table' AND (sql like '%fts5%' OR sql like '%FTS5%')" , name . to_s ) == 1
120
120
end
@@ -123,11 +123,11 @@ def prepare_statements
123
123
stmt_names = [ :insert , :delete , :delete_all , :drop , :count , :count_all , :search ]
124
124
stmt_names . each do |stmt_name |
125
125
@stmts [ stmt_name ] = @db . prepare ( @schema . sql_for ( stmt_name ) )
126
- end
126
+ end
127
127
end
128
-
129
- def do_create ( schema )
130
- @schema = schema
128
+
129
+ def do_create ( schema )
130
+ @schema = schema
131
131
@schema . clean
132
132
# create index
133
133
@db . execute ( schema . sql_for ( :create_index , true ) )
@@ -136,7 +136,7 @@ def do_create(schema)
136
136
# create triggers (if any)
137
137
if @schema . get ( :type ) == :backed
138
138
@db . execute_batch ( @schema . sql_for ( :create_primary_triggers ) )
139
- if secondary_triggers_sql = @schema . sql_for ( :create_secondary_triggers )
139
+ if ( secondary_triggers_sql = @schema . sql_for ( :create_secondary_triggers ) )
140
140
@db . execute_batch ( secondary_triggers_sql )
141
141
end
142
142
@db . execute ( @schema . sql_for ( :rebuild ) ) if @schema . get ( :rebuild_on_create )
@@ -152,11 +152,11 @@ def do_modify(new_schema)
152
152
requires_schema_change = false
153
153
requires_trigger_change = false
154
154
requires_rebuild = false
155
- if changes [ :fields ] || changes [ :table ] || changes [ :tokenizer ] || changes [ :filter_column ] || changes [ :removed_fields_count ] > 0 # any change here will require a schema change
155
+ if changes [ :fields ] || changes [ :table ] || changes [ :tokenizer ] || changes [ :filter_column ] || changes [ :removed_fields_count ] > 0 # any change here will require a schema change
156
156
requires_schema_change = true
157
157
# only a change in tokenizer
158
158
requires_rebuild = changes [ :tokenizer ] || new_schema . get ( :rebuild_on_modify )
159
- requires_trigger_change = ( changes [ :table ] || changes [ :fields ] || changes [ :filter_column ] ) && @schema . get ( :type ) == :backed
159
+ requires_trigger_change = ( changes [ :table ] || changes [ :fields ] || changes [ :filter_column ] ) && @schema . get ( :type ) == :backed
160
160
end
161
161
if requires_schema_change
162
162
# 1. enable schema editing
@@ -169,12 +169,12 @@ def do_modify(new_schema)
169
169
@db . execute ( new_schema . sql_for ( :expand_data ) , changes [ :extra_fields_count ] )
170
170
@db . execute ( new_schema . sql_for ( :expand_docsize ) , changes [ :extra_fields_count ] )
171
171
@db . execute ( "PRAGMA WRITABLE_SCHEMA = RESET" )
172
- # need to reprepare statements
172
+ # need to reprepare statements
173
173
end
174
174
if requires_trigger_change
175
175
@db . execute_batch ( new_schema . sql_for ( :drop_primary_triggers ) )
176
176
@db . execute_batch ( new_schema . sql_for ( :create_primary_triggers ) )
177
- if secondary_triggers_sql = new_schema . sql_for ( :create_secondary_triggers )
177
+ if ( secondary_triggers_sql = new_schema . sql_for ( :create_secondary_triggers ) )
178
178
@db . execute_batch ( new_schema . sql_for ( :drop_secondary_triggers ) )
179
179
@db . execute_batch ( secondary_triggers_sql )
180
180
end
@@ -183,48 +183,47 @@ def do_modify(new_schema)
183
183
@schema = new_schema
184
184
set_config_value ( :litesearch_schema , @schema . schema )
185
185
prepare_statements
186
- #save_schema
186
+ # save_schema
187
187
end
188
188
do_rebuild if requires_rebuild
189
- # update the weights if they changed
189
+ # update the weights if they changed
190
190
@db . execute ( @schema . sql_for ( :ranks ) ) if changes [ :weights ]
191
191
end
192
192
193
193
def do_rebuild
194
194
# remove any zero weight columns
195
195
if @schema . get ( :type ) == :backed
196
196
@db . execute_batch ( @schema . sql_for ( :drop_primary_triggers ) )
197
- if secondary_triggers_sql = @schema . sql_for ( :create_secondary_triggers )
197
+ if ( secondary_triggers_sql = @schema . sql_for ( :create_secondary_triggers ) )
198
198
@db . execute_batch ( @schema . sql_for ( :drop_secondary_triggers ) )
199
199
end
200
200
@db . execute ( @schema . sql_for ( :drop ) )
201
201
@db . execute ( @schema . sql_for ( :create_index , true ) )
202
202
@db . execute_batch ( @schema . sql_for ( :create_primary_triggers ) )
203
203
@db . execute_batch ( secondary_triggers_sql ) if secondary_triggers_sql
204
- @db . execute ( @schema . sql_for ( :rebuild ) )
204
+ @db . execute ( @schema . sql_for ( :rebuild ) )
205
205
elsif @schema . get ( :type ) == :standalone
206
206
removables = [ ]
207
- @schema . get ( :fields ) . each_with_index { |f , i | removables << [ f [ 0 ] , i ] if f [ 1 ] [ :weight ] == 0 }
207
+ @schema . get ( :fields ) . each_with_index { |f , i | removables << [ f [ 0 ] , i ] if f [ 1 ] [ :weight ] == 0 }
208
208
removables . each do |col |
209
209
@db . execute ( @schema . sql_for ( :drop_content_col , col [ 1 ] ) )
210
- @schema . get ( :fields ) . delete ( col [ 0 ] )
210
+ @schema . get ( :fields ) . delete ( col [ 0 ] )
211
211
end
212
212
@db . execute ( "PRAGMA WRITABLE_SCHEMA = TRUE" )
213
213
@db . execute ( @schema . sql_for ( :update_index ) , @schema . sql_for ( :create_index , true ) )
214
- @db . execute ( @schema . sql_for ( :update_content_table ) , @schema . sql_for ( :create_content_table , @schema . schema [ :fields ] . count ) )
214
+ @db . execute ( @schema . sql_for ( :update_content_table ) , @schema . sql_for ( :create_content_table , @schema . schema [ :fields ] . count ) )
215
215
@db . execute ( "PRAGMA WRITABLE_SCHEMA = RESET" )
216
- @db . execute ( @schema . sql_for ( :rebuild ) )
216
+ @db . execute ( @schema . sql_for ( :rebuild ) )
217
217
end
218
218
set_config_value ( :litesearch_schema , @schema . schema )
219
- @db . execute ( @schema . sql_for ( :ranks , true ) )
220
- end
221
-
219
+ @db . execute ( @schema . sql_for ( :ranks , true ) )
220
+ end
221
+
222
222
def get_config_value ( key )
223
- Oj . load ( @db . get_first_value ( @schema . sql_for ( :get_config_value ) , key . to_s ) ) #rescue nil
223
+ Oj . load ( @db . get_first_value ( @schema . sql_for ( :get_config_value ) , key . to_s ) ) # rescue nil
224
224
end
225
-
225
+
226
226
def set_config_value ( key , value )
227
227
@db . execute ( @schema . sql_for ( :set_config_value ) , key . to_s , Oj . dump ( value ) )
228
228
end
229
-
230
229
end
0 commit comments