From 2a2514f06be32cedf9322aec1717bea8e0293013 Mon Sep 17 00:00:00 2001 From: Ilgiz Mustafin Date: Wed, 22 Jan 2020 05:55:52 +0300 Subject: [PATCH 1/3] Add spec for having full text indexes --- spec/neo4j/core/shared_examples/adaptor.rb | 29 +++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/spec/neo4j/core/shared_examples/adaptor.rb b/spec/neo4j/core/shared_examples/adaptor.rb index e22ae3e6..afb93212 100644 --- a/spec/neo4j/core/shared_examples/adaptor.rb +++ b/spec/neo4j/core/shared_examples/adaptor.rb @@ -388,7 +388,28 @@ def get_object_by_id(id, adaptor) end describe 'schema inspection' do - before { delete_schema(real_session) } + def supports_full_text? + Gem::Version.new(adaptor.version(real_session)) >= Gem::Version.new('3.5.0') + end + + before do + delete_schema(real_session) + + if supports_full_text? + adaptor.query( + real_session, + <<-CYPHER + CALL db.indexes() + YIELD indexName WHERE indexName STARTS WITH "ftIndex" + WITH COLLECT(indexName) AS names + UNWIND names AS n + CALL db.index.fulltext.drop(n) + RETURN null + CYPHER + ) + end + end + before do create_constraint(real_session, :Album, :al_id, type: :unique) create_constraint(real_session, :Album, :name, type: :unique) @@ -397,6 +418,12 @@ def get_object_by_id(id, adaptor) create_index(real_session, :Band, :ba_id) create_index(real_session, :Band, :fisk) create_index(real_session, :Person, :name) + + if supports_full_text? + adaptor.query(real_session, 'CALL db.index.fulltext.createNodeIndex("ftIndex1", ["Album"], ["name"])') + adaptor.query(real_session, 'CALL db.index.fulltext.createNodeIndex("ftIndex2", ["Album", "Song"], ["name", "al_id", "so_id"])') + adaptor.query(real_session, 'CALL db.index.fulltext.createRelationshipIndex("ftIndex3", ["ALBUM_SONG"], ["songNumber"])') + end end describe 'constraints' do From 03faeab7e935a5589c9e19934028334e3b5d549d Mon Sep 17 00:00:00 2001 From: Ilgiz Mustafin Date: Wed, 22 Jan 2020 07:29:09 +0300 Subject: [PATCH 2/3] Use Cypher for querying indexes in HTTP adaptor when possible --- lib/neo4j/core/cypher_session/adaptors/http.rb | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/neo4j/core/cypher_session/adaptors/http.rb b/lib/neo4j/core/cypher_session/adaptors/http.rb index 5c3e3836..a0ff648d 100644 --- a/lib/neo4j/core/cypher_session/adaptors/http.rb +++ b/lib/neo4j/core/cypher_session/adaptors/http.rb @@ -1,6 +1,7 @@ require 'neo4j/core/cypher_session/adaptors' require 'neo4j/core/cypher_session/adaptors/has_uri' require 'neo4j/core/cypher_session/responses/http' +require 'neo4j/core/cypher_session/adaptors/schema' require 'uri' # TODO: Work with `Query` objects @@ -9,6 +10,7 @@ module Core class CypherSession module Adaptors class HTTP < Base + include Adaptors::Schema attr_reader :requestor, :url def initialize(url, options = {}) @@ -46,7 +48,15 @@ def version(_session) end # Schema inspection methods - def indexes(_session) + + # Does this version support CALL clause? + def supports_call? + Gem::Version.new(version(nil)) >= Gem::Version.new('3.0.0') + end + + def indexes(session) + return super(session) if supports_call? + response = @requestor.get('db/data/schema/index') check_for_schema_response_error!(response) @@ -61,7 +71,9 @@ def indexes(_session) CONSTRAINT_TYPES = { 'UNIQUENESS' => :uniqueness } - def constraints(_session, _label = nil, _options = {}) + def constraints(session, _label = nil, _options = {}) + return super(session) if supports_call? + response = @requestor.get('db/data/schema/constraint') check_for_schema_response_error!(response) From aada1715d51a24c04a22c74c51c785240385caa1 Mon Sep 17 00:00:00 2001 From: Ilgiz Mustafin Date: Wed, 22 Jan 2020 05:57:31 +0300 Subject: [PATCH 3/3] Don't fail schema inspection when full text indexes exist --- lib/neo4j/core/cypher_session/adaptors/schema.rb | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/neo4j/core/cypher_session/adaptors/schema.rb b/lib/neo4j/core/cypher_session/adaptors/schema.rb index c1b96bd9..4d2b0250 100644 --- a/lib/neo4j/core/cypher_session/adaptors/schema.rb +++ b/lib/neo4j/core/cypher_session/adaptors/schema.rb @@ -14,18 +14,24 @@ def indexes(session) result = query(session, 'CALL db.indexes()', {}, skip_instrumentation: true) result.map do |row| - label, property = row.description.match(/INDEX ON :([^\(]+)\(([^\)]+)\)/)[1, 2] + match = row.description.match(/INDEX ON :([^\(]+)\(([^\)]+)\)/) + next unless match + + label, property = match[1, 2] {type: row.type.to_sym, label: label.to_sym, properties: [property.to_sym], state: row.state.to_sym} - end + end.compact end def constraints(session) result = query(session, 'CALL db.indexes()', {}, skip_instrumentation: true) result.select { |row| row.type == 'node_unique_property' }.map do |row| - label, property = row.description.match(/INDEX ON :([^\(]+)\(([^\)]+)\)/)[1, 2] + match = row.description.match(/INDEX ON :([^\(]+)\(([^\)]+)\)/) + next unless match + + label, property = match[1, 2] {type: :uniqueness, label: label.to_sym, properties: [property.to_sym]} - end + end.compact end end end