typesense 0.1.1 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.circleci/config.yml +4 -2
- data/.gitignore +2 -0
- data/.rubocop.yml +7 -0
- data/.rubocop_todo.yml +36 -27
- data/LICENSE +198 -10
- data/README.md +10 -2
- data/codecov.yml +10 -0
- data/examples/aliases.rb +58 -0
- data/examples/client_initialization.rb +67 -0
- data/examples/collections_and_documents.rb +45 -68
- data/examples/keys.rb +127 -0
- data/examples/overrides.rb +108 -0
- data/examples/search.rb +26 -53
- data/lib/typesense.rb +8 -0
- data/lib/typesense/alias.rb +24 -0
- data/lib/typesense/aliases.rb +30 -0
- data/lib/typesense/api_call.rb +186 -69
- data/lib/typesense/client.rb +12 -3
- data/lib/typesense/collection.rb +8 -6
- data/lib/typesense/collections.rb +6 -6
- data/lib/typesense/configuration.rb +35 -19
- data/lib/typesense/debug.rb +3 -3
- data/lib/typesense/document.rb +4 -4
- data/lib/typesense/documents.rb +11 -6
- data/lib/typesense/error.rb +6 -0
- data/lib/typesense/health.rb +15 -0
- data/lib/typesense/key.rb +24 -0
- data/lib/typesense/keys.rb +34 -0
- data/lib/typesense/metrics.rb +15 -0
- data/lib/typesense/override.rb +25 -0
- data/lib/typesense/overrides.rb +31 -0
- data/lib/typesense/version.rb +1 -1
- data/typesense.gemspec +14 -11
- metadata +79 -25
data/lib/typesense/client.rb
CHANGED
@@ -4,12 +4,21 @@ module Typesense
|
|
4
4
|
class Client
|
5
5
|
attr_reader :configuration
|
6
6
|
attr_reader :collections
|
7
|
+
attr_reader :aliases
|
8
|
+
attr_reader :keys
|
7
9
|
attr_reader :debug
|
10
|
+
attr_reader :health
|
11
|
+
attr_reader :metrics
|
8
12
|
|
9
13
|
def initialize(options = {})
|
10
|
-
@configuration
|
11
|
-
@
|
12
|
-
@
|
14
|
+
@configuration = Configuration.new(options)
|
15
|
+
@api_call = ApiCall.new(@configuration)
|
16
|
+
@collections = Collections.new(@api_call)
|
17
|
+
@aliases = Aliases.new(@api_call)
|
18
|
+
@keys = Keys.new(@api_call)
|
19
|
+
@debug = Debug.new(@api_call)
|
20
|
+
@health = Health.new(@api_call)
|
21
|
+
@metrics = Metrics.new(@api_call)
|
13
22
|
end
|
14
23
|
end
|
15
24
|
end
|
data/lib/typesense/collection.rb
CHANGED
@@ -3,19 +3,21 @@
|
|
3
3
|
module Typesense
|
4
4
|
class Collection
|
5
5
|
attr_reader :documents
|
6
|
+
attr_reader :overrides
|
6
7
|
|
7
|
-
def initialize(
|
8
|
-
@
|
9
|
-
@
|
10
|
-
@documents
|
8
|
+
def initialize(name, api_call)
|
9
|
+
@name = name
|
10
|
+
@api_call = api_call
|
11
|
+
@documents = Documents.new(@name, @api_call)
|
12
|
+
@overrides = Overrides.new(@name, @api_call)
|
11
13
|
end
|
12
14
|
|
13
15
|
def retrieve
|
14
|
-
|
16
|
+
@api_call.get(endpoint_path)
|
15
17
|
end
|
16
18
|
|
17
19
|
def delete
|
18
|
-
|
20
|
+
@api_call.delete(endpoint_path)
|
19
21
|
end
|
20
22
|
|
21
23
|
private
|
@@ -4,21 +4,21 @@ module Typesense
|
|
4
4
|
class Collections
|
5
5
|
RESOURCE_PATH = '/collections'
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
@
|
9
|
-
@collections
|
7
|
+
def initialize(api_call)
|
8
|
+
@api_call = api_call
|
9
|
+
@collections = {}
|
10
10
|
end
|
11
11
|
|
12
12
|
def create(schema)
|
13
|
-
|
13
|
+
@api_call.post(RESOURCE_PATH, schema)
|
14
14
|
end
|
15
15
|
|
16
16
|
def retrieve
|
17
|
-
|
17
|
+
@api_call.get(RESOURCE_PATH)
|
18
18
|
end
|
19
19
|
|
20
20
|
def [](collection_name)
|
21
|
-
@collections[collection_name] ||= Collection.new(
|
21
|
+
@collections[collection_name] ||= Collection.new(collection_name, @api_call)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -2,37 +2,53 @@
|
|
2
2
|
|
3
3
|
module Typesense
|
4
4
|
class Configuration
|
5
|
-
attr_accessor :
|
6
|
-
attr_accessor :
|
7
|
-
attr_accessor :
|
5
|
+
attr_accessor :nodes
|
6
|
+
attr_accessor :nearest_node
|
7
|
+
attr_accessor :connection_timeout_seconds
|
8
|
+
attr_accessor :healthcheck_interval_seconds
|
9
|
+
attr_accessor :num_retries
|
10
|
+
attr_accessor :retry_interval_seconds
|
11
|
+
attr_accessor :api_key
|
12
|
+
attr_accessor :logger
|
13
|
+
attr_accessor :log_level
|
8
14
|
|
9
15
|
def initialize(options = {})
|
10
|
-
@
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
@
|
17
|
-
|
16
|
+
@nodes = options[:nodes] || []
|
17
|
+
@nearest_node = options[:nearest_node]
|
18
|
+
@connection_timeout_seconds = options[:connection_timeout_seconds] || options[:timeout_seconds] || 10
|
19
|
+
@healthcheck_interval_seconds = options[:healthcheck_interval_seconds] || 15
|
20
|
+
@num_retries = options[:num_retries] || @nodes.length + (@nearest_node.nil? ? 0 : 1) || 3
|
21
|
+
@retry_interval_seconds = options[:retry_interval_seconds] || 0.1
|
22
|
+
@api_key = options[:api_key]
|
23
|
+
|
24
|
+
@logger = options[:logger] || Logger.new(STDOUT)
|
25
|
+
@log_level = options[:log_level] || Logger::WARN
|
26
|
+
@logger.level = @log_level
|
27
|
+
|
28
|
+
show_deprecation_warnings(options)
|
29
|
+
validate!
|
18
30
|
end
|
19
31
|
|
20
32
|
def validate!
|
21
|
-
if @
|
22
|
-
|
23
|
-
|
33
|
+
if @nodes.nil? ||
|
34
|
+
@nodes.empty? ||
|
35
|
+
@nodes.any? { |node| node_missing_parameters?(node) }
|
36
|
+
raise Error::MissingConfiguration, 'Missing required configuration. Ensure that nodes[][:protocol], nodes[][:host] and nodes[][:port] are set.'
|
24
37
|
end
|
25
38
|
|
26
|
-
if
|
27
|
-
@read_replica_nodes.any? { |node| node_missing_parameters?(node) }
|
28
|
-
raise Error::MissingConfiguration, 'Missing required configuration for read_replica_nodes. Ensure that read_replica_nodes[][:protocol], read_replica_nodes[][:host], read_replica_nodes[][:port] and read_replica_nodes[][:api_key] are set.'
|
29
|
-
end
|
39
|
+
raise Error::MissingConfiguration, 'Missing required configuration. Ensure that api_key is set.' if @api_key.nil?
|
30
40
|
end
|
31
41
|
|
32
42
|
private
|
33
43
|
|
34
44
|
def node_missing_parameters?(node)
|
35
|
-
%i[protocol host port
|
45
|
+
%i[protocol host port].any? { |attr| node.send(:[], attr).nil? }
|
46
|
+
end
|
47
|
+
|
48
|
+
def show_deprecation_warnings(options)
|
49
|
+
@logger.warn 'Deprecation warning: timeout_seconds is now renamed to connection_timeout_seconds' unless options[:timeout_seconds].nil?
|
50
|
+
@logger.warn 'Deprecation warning: master_node is now consolidated to nodes, starting with Typesense Server v0.12' unless options[:master_node].nil?
|
51
|
+
@logger.warn 'Deprecation warning: read_replica_nodes is now consolidated to nodes, starting with Typesense Server v0.12' unless options[:read_replica_nodes].nil?
|
36
52
|
end
|
37
53
|
end
|
38
54
|
end
|
data/lib/typesense/debug.rb
CHANGED
@@ -4,12 +4,12 @@ module Typesense
|
|
4
4
|
class Debug
|
5
5
|
RESOURCE_PATH = '/debug'
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
@
|
7
|
+
def initialize(api_call)
|
8
|
+
@api_call = api_call
|
9
9
|
end
|
10
10
|
|
11
11
|
def retrieve
|
12
|
-
|
12
|
+
@api_call.get(RESOURCE_PATH)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
data/lib/typesense/document.rb
CHANGED
@@ -2,18 +2,18 @@
|
|
2
2
|
|
3
3
|
module Typesense
|
4
4
|
class Document
|
5
|
-
def initialize(
|
6
|
-
@configuration = configuration
|
5
|
+
def initialize(collection_name, document_id, api_call)
|
7
6
|
@collection_name = collection_name
|
8
7
|
@document_id = document_id
|
8
|
+
@api_call = api_call
|
9
9
|
end
|
10
10
|
|
11
11
|
def retrieve
|
12
|
-
|
12
|
+
@api_call.get(endpoint_path)
|
13
13
|
end
|
14
14
|
|
15
15
|
def delete
|
16
|
-
|
16
|
+
@api_call.delete(endpoint_path)
|
17
17
|
end
|
18
18
|
|
19
19
|
private
|
data/lib/typesense/documents.rb
CHANGED
@@ -4,26 +4,31 @@ module Typesense
|
|
4
4
|
class Documents
|
5
5
|
RESOURCE_PATH = '/documents'
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
@configuration = configuration
|
7
|
+
def initialize(collection_name, api_call)
|
9
8
|
@collection_name = collection_name
|
9
|
+
@api_call = api_call
|
10
10
|
@documents = {}
|
11
11
|
end
|
12
12
|
|
13
13
|
def create(document)
|
14
|
-
|
14
|
+
@api_call.post(endpoint_path, document)
|
15
|
+
end
|
16
|
+
|
17
|
+
def create_many(documents)
|
18
|
+
documents_in_jsonl_format = documents.map { |document| JSON.dump(document) }.join("\n")
|
19
|
+
@api_call.post(endpoint_path('import'), as_json: false, body: documents_in_jsonl_format)
|
15
20
|
end
|
16
21
|
|
17
22
|
def export
|
18
|
-
|
23
|
+
(@api_call.get(endpoint_path('export')) || '').split("\n")
|
19
24
|
end
|
20
25
|
|
21
26
|
def search(search_parameters)
|
22
|
-
|
27
|
+
@api_call.get(endpoint_path('search'), search_parameters)
|
23
28
|
end
|
24
29
|
|
25
30
|
def [](document_id)
|
26
|
-
@documents[document_id] ||= Document.new(@
|
31
|
+
@documents[document_id] ||= Document.new(@collection_name, document_id, @api_call)
|
27
32
|
end
|
28
33
|
|
29
34
|
private
|
data/lib/typesense/error.rb
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Typesense
|
4
|
+
class Key
|
5
|
+
def initialize(id, api_call)
|
6
|
+
@id = id
|
7
|
+
@api_call = api_call
|
8
|
+
end
|
9
|
+
|
10
|
+
def retrieve
|
11
|
+
@api_call.get(endpoint_path)
|
12
|
+
end
|
13
|
+
|
14
|
+
def delete
|
15
|
+
@api_call.delete(endpoint_path)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def endpoint_path
|
21
|
+
"#{Keys::RESOURCE_PATH}/#{@id}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'base64'
|
4
|
+
|
5
|
+
module Typesense
|
6
|
+
class Keys
|
7
|
+
RESOURCE_PATH = '/keys'
|
8
|
+
|
9
|
+
def initialize(api_call)
|
10
|
+
@api_call = api_call
|
11
|
+
@keys = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def create(parameters)
|
15
|
+
@api_call.post(RESOURCE_PATH, parameters)
|
16
|
+
end
|
17
|
+
|
18
|
+
def retrieve
|
19
|
+
@api_call.get(RESOURCE_PATH)
|
20
|
+
end
|
21
|
+
|
22
|
+
def generate_scoped_search_key(search_key, parameters)
|
23
|
+
parameters_json = JSON.dump(parameters)
|
24
|
+
digest = Base64.encode64(OpenSSL::HMAC.digest('sha256', search_key, parameters_json)).gsub("\n", '')
|
25
|
+
key_prefix = search_key[0...4]
|
26
|
+
raw_scoped_key = "#{digest}#{key_prefix}#{parameters_json}"
|
27
|
+
Base64.encode64(raw_scoped_key).gsub("\n", '')
|
28
|
+
end
|
29
|
+
|
30
|
+
def [](id)
|
31
|
+
@keys[id] ||= Key.new(id, @api_call)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Typesense
|
4
|
+
class Override
|
5
|
+
def initialize(collection_name, override_id, api_call)
|
6
|
+
@collection_name = collection_name
|
7
|
+
@override_id = override_id
|
8
|
+
@api_call = api_call
|
9
|
+
end
|
10
|
+
|
11
|
+
def retrieve
|
12
|
+
@api_call.get(endpoint_path)
|
13
|
+
end
|
14
|
+
|
15
|
+
def delete
|
16
|
+
@api_call.delete(endpoint_path)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def endpoint_path
|
22
|
+
"#{Collections::RESOURCE_PATH}/#{@collection_name}#{Overrides::RESOURCE_PATH}/#{@override_id}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Typesense
|
4
|
+
class Overrides
|
5
|
+
RESOURCE_PATH = '/overrides'
|
6
|
+
|
7
|
+
def initialize(collection_name, api_call)
|
8
|
+
@collection_name = collection_name
|
9
|
+
@api_call = api_call
|
10
|
+
@overrides = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def create(params)
|
14
|
+
@api_call.put(endpoint_path, params)
|
15
|
+
end
|
16
|
+
|
17
|
+
def retrieve
|
18
|
+
@api_call.get(endpoint_path)
|
19
|
+
end
|
20
|
+
|
21
|
+
def [](override_id)
|
22
|
+
@overrides[override_id] ||= Override.new(@collection_name, override_id, @api_call)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def endpoint_path(operation = nil)
|
28
|
+
"#{Collections::RESOURCE_PATH}/#{@collection_name}#{Overrides::RESOURCE_PATH}#{operation.nil? ? '' : '/' + operation}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/typesense/version.rb
CHANGED
data/typesense.gemspec
CHANGED
@@ -7,7 +7,7 @@ require 'typesense/version'
|
|
7
7
|
Gem::Specification.new do |spec|
|
8
8
|
spec.name = 'typesense'
|
9
9
|
spec.version = Typesense::VERSION
|
10
|
-
spec.authors = ['
|
10
|
+
spec.authors = ['Typesense, Inc.']
|
11
11
|
spec.email = ['contact@typesense.org']
|
12
12
|
|
13
13
|
spec.summary = 'Ruby Library for Typesense'
|
@@ -23,15 +23,18 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.require_paths = ['lib']
|
24
24
|
|
25
25
|
spec.add_development_dependency 'awesome_print', '~> 1.8'
|
26
|
-
spec.add_development_dependency 'bundler', '~>
|
27
|
-
spec.add_development_dependency '
|
28
|
-
spec.add_development_dependency '
|
29
|
-
spec.add_development_dependency '
|
30
|
-
spec.add_development_dependency '
|
31
|
-
spec.add_development_dependency '
|
32
|
-
spec.add_development_dependency '
|
33
|
-
spec.add_development_dependency '
|
34
|
-
spec.add_development_dependency '
|
26
|
+
spec.add_development_dependency 'bundler', '~> 2.0'
|
27
|
+
spec.add_development_dependency 'codecov', '~> 0.1'
|
28
|
+
spec.add_development_dependency 'pry-byebug', '~> 3.9'
|
29
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
30
|
+
spec.add_development_dependency 'rspec', '~> 3.9'
|
31
|
+
spec.add_development_dependency 'rspec-legacy_formatters', '~> 1.0' # For codecov formatter
|
32
|
+
spec.add_development_dependency 'rspec_junit_formatter', '~> 0.4'
|
33
|
+
spec.add_development_dependency 'rubocop', '~> 0.83'
|
34
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 1.39'
|
35
|
+
spec.add_development_dependency 'simplecov', '~> 0.18'
|
36
|
+
spec.add_development_dependency 'timecop', '~> 0.9'
|
37
|
+
spec.add_development_dependency 'webmock', '~> 3.8'
|
35
38
|
|
36
|
-
spec.add_dependency 'httparty', '~> 0.
|
39
|
+
spec.add_dependency 'httparty', '~> 0.18'
|
37
40
|
end
|