Skip to content

Commit

Permalink
Merge branch '8.0.x'
Browse files Browse the repository at this point in the history
* 8.0.x:
  CHANGELOG entry for #1254
  Improvements based on #1264
  Destroy should return object like in ActiveRecord
  Use ActiveSupport::Logger instead of base Logger
  Release .15 patch with #1270 change
  Trying to fix ruby 2.0 build.
  Fix gemspec.
  Fix Gemfile for jruby.
  Accepting `nil` as enum value
  Add information about which exceptions are replacing old exceptions
  Update ActiveRel.rst
  Up to 7.1.2 to include fix from model_label_map_fix
  Put this back, because of course it broke things
  Fix issue with label / model mappings getting stuck before all models have a chance to load.  Also don't clear WRAPPED_CLASSES (I think this will fix the CypherNode issue we've been seeing in development
  • Loading branch information
ProGM committed Aug 21, 2016
2 parents dc2b9e2 + 64c917a commit 998984a
Show file tree
Hide file tree
Showing 13 changed files with 142 additions and 21 deletions.
25 changes: 24 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file.
This file should follow the standards specified on [http://keepachangelog.com/]
This project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Changed

- `ActiveNode#destroy` and `ActiveRel#destroy` now return the object in question rather than `true` to be compatible with `ActiveRecord` (see #1254)

## [8.0.0.alpha.2] 2016-08-05

### Changed
Expand Down Expand Up @@ -52,6 +58,18 @@ This project adheres to [Semantic Versioning](http://semver.org/).

- Made some memory optimizations (thanks ProGM / see #1221)

## [7.1.3] - 08-18-2016

### Changed

- Default value for `enum` is `nil` instead of the first value. This is a **BREAKING** change but is being released as a patch because the original behavior was considered a bug. See [this pull request](https://github.com/neo4jrb/neo4j/pull/1270) (thanks to ProGM and andyweiss1982)

## [7.1.2] - 08-01-2016

### Fixed

- Fixed issue where the label wrapping cache would get stuck

## [7.1.1] - 07-22-2016

### Fixed
Expand All @@ -65,6 +83,12 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Gemspec dependency requirements were modified where ActiveModel, ActiveSupport, and Railties are concerned. The gem now requires >= 4.0, < 5.1.
- `ActiveModel::Serializers::Xml` is only included if supported if available.

## [7.0.15] - 08-18-2016

### Changed

- Default value for `enum` is `nil` instead of the first value. This is a **BREAKING** change but is being released as a patch because the original behavior was considered a bug. See [this pull request](https://github.com/neo4jrb/neo4j/pull/1270) (thanks to ProGM and andyweiss1982)

## [7.0.14] - 07-10-2016

### Fixed
Expand All @@ -82,7 +106,6 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Fixed

- Fix dipendence from JSON when using outside of rails (thanks ProGM)
>>>>>>> 7.1.x

## [7.0.10] - 06-07-2016

Expand Down
2 changes: 1 addition & 1 deletion docs/ActiveRel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ Any of these methods can return relationship objects.
Student.first.lessons.each_rel { |r| }
Student.first.lessons.each_with_rel { |node, rel| }
Student.first.query_as(:s).match('s-[rel1:\`enrolled_in\`]->n2').pluck(:rel1)
Student.first.query_as(:s).match('(s)-[rel1:\`enrolled_in\`]->(n2)').pluck(:rel1)
These are available as both class or instance methods. Because both each_rel and each_with_rel return enumerables when a block is skipped, you can take advantage of the full suite of enumerable methods:

Expand Down
70 changes: 69 additions & 1 deletion docs/UpgradeGuide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,61 @@ If you are using version ``8.0`` of the ``neo4j`` gem, that will be accessible,
server_db
^^^^^^^^^

In previous version of the ``neo4j`` gem to connect to Neo4j via HTTP you would define the value ``server_db`` in the ``neo4j.yml`` file, the ``NEO4J_TYPE`` environment variable, or a Rails configuration (``config.neo4j.session_type``). This should now be replaced and either ``bolt`` or ``http`` should be used.
In previous version of the ``neo4j`` gem to connect to Neo4j via HTTP you would define the value ``server_db`` in the ``neo4j.yml`` file, the ``NEO4J_TYPE`` environment variable, or a Rails configuration (``config.neo4j.session_type``). This should now be replaced and either ``bolt`` or ``http`` should be used depending on which connection type you need.

Some examples:

.. code-block:: yaml
# config/neo4j.yml
# Before
development:
type: server_db
url: http://localhost:7474
# After
development:
type: http # or bolt
url: http://localhost:7474
.. code-block:: ruby
# Rails config/application.rb, config/environments/development.rb, etc...
# Before
config.neo4j.session_type = :server_db
config.neo4j.session_url = 'http://localhost:7474'
# AFter
config.neo4j.session_type = :http # or :bolt
config.neo4j.session_url = 'http://localhost:7474'
Outside of Rails
^^^^^^^^^^^^^^^^

The ``neo4j`` gem will automatically set up a number of things with it's ``railtie``. If you aren't using Rails you may need to set some things up yourself and some of the details have changed with version 8.0 of the ``neo4j`` gem.

Previously a connection with be established with ``Neo4j::Session.open`` and the default session from ``neo4j-core`` would be used. In version 7.0 of the ``neo4j-core`` gem, no such default session exists for the new API so you will need to establish a session to use the ``ActiveNode`` and ``ActiveRel`` modules like so:

.. code-block:: ruby
adaptor = Neo4j::Core::CypherSession::Adaptors::HTTP.new('http://username:password@localhost:7474')
session = Neo4j::Core::CypherSession.new(adaptor)
Neo4j::ActiveBase.current_session = session
# Or skip setting up the session yourself:
Neo4j::ActiveBase.current_adaptor = adaptor
Migrations:

If you would like to use the migrations provided by the ``neo4j`` outside of Rails you can include this in your ``Rakefile``:

.. code-block:: ruby
load 'neo4j/tasks/migration.rake'
Indexes and Constraints
^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -131,3 +185,17 @@ In version 8.0 of the ``neo4j`` gem support was added to allow for definining th
.. warning::

Use of ``neo_id`` as a perminent identifier should be done with caution. Neo4j can recycle IDs from deleted nodes meaning that URLs or other external references using that ID will reference the wrong item. Neo4j may be updated in the future to support internal IDs which aren't recycled, but for now use at your own risk

Exceptions
^^^^^^^^^^

With the new API comes some new exceptions which are raised. With the new adaptor API errors are more dependable across different ways of connecting to Neo4j.

======================================================= =========================================================================
Old Exception New Exception
------------------------------------------------------- -------------------------------------------------------------------------
Neo4j::Server::Resource::ServerException Neo4j::Core::CypherSession::ConnectionFailedError
Neo4j::Server::CypherResponse::ConstraintViolationError Neo4j::Core::CypherSession::SchemaErrors::ConstraintValidationFailedError
Neo4j::Session::CypherError Neo4j::Core::CypherSession::CypherError
======================================================= =========================================================================

2 changes: 1 addition & 1 deletion lib/neo4j/active_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def label_object(label_name)
end

def logger
@logger ||= (Neo4j::Config[:logger] || Logger.new(STDOUT))
@logger ||= (Neo4j::Config[:logger] || ActiveSupport::Logger.new(STDOUT))
end
end
end
Expand Down
2 changes: 2 additions & 0 deletions lib/neo4j/active_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ def self.inherited?
end

def self.inherited(other)
Neo4j::ActiveNode::Labels.clear_wrapped_models

LOADED_CLASSES << other
other.instance_variable_set('@inherited', true)
inherit_id_property(other)
Expand Down
6 changes: 1 addition & 5 deletions lib/neo4j/active_node/labels.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@ module Labels
MODELS_FOR_LABELS_CACHE.clear

included do |model|
def self.inherited(model)
add_wrapped_class(model)

super
end
Neo4j::ActiveNode::Labels.clear_wrapped_models

Neo4j::ActiveNode::Labels.add_wrapped_class(model) unless Neo4j::ActiveNode::Labels._wrapped_classes.include?(model)
end
Expand Down
16 changes: 11 additions & 5 deletions lib/neo4j/shared/enum.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@ def normalize_key_list(enum_keys)
end
end

VALID_OPTIONS_FOR_ENUMS = [:_prefix, :_suffix]
DEFAULT_OPTIONS_FOR_ENUMS = {}
VALID_OPTIONS_FOR_ENUMS = [:_index, :_prefix, :_suffix, :_default]

def split_options_and_parameters(parameters)
options = {}
Expand All @@ -80,9 +79,16 @@ def split_options_and_parameters(parameters)
[options, new_parameters]
end

def define_property(property_name, enum_keys, _options)
property property_name, default: enum_keys.keys.first # .merge(options)
serialize property_name, Neo4j::Shared::TypeConverters::EnumConverter.new(enum_keys)
def define_property(property_name, enum_keys, options)
property_options = build_property_options(enum_keys, options)
property property_name, property_options
serialize property_name, Neo4j::Shared::TypeConverters::EnumConverter.new(enum_keys, property_options)
end

def build_property_options(_enum_keys, options = {})
{
default: options[:_default]
}
end

def define_enum_methods(property_name, enum_keys, options)
Expand Down
2 changes: 2 additions & 0 deletions lib/neo4j/shared/persistence.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ def destroy
destroy_query.exec if _persisted_obj

@_deleted = true

self
end

def exist?
Expand Down
3 changes: 2 additions & 1 deletion lib/neo4j/shared/type_converters.rb
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,9 @@ def to_ruby(value)
end

class EnumConverter
def initialize(enum_keys)
def initialize(enum_keys, options)
@enum_keys = enum_keys
@options = options
end

def converted?(value)
Expand Down
2 changes: 1 addition & 1 deletion lib/neo4j/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Neo4j
VERSION = '8.0.0.alpha.2'
VERSION = '8.0.0.alpha.3'
end
23 changes: 21 additions & 2 deletions spec/e2e/enum_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
create_index :StoredFile, :size, type: :exact
create_index :StoredFile, :flag, type: :exact
stub_active_node_class('StoredFile') do
enum type: [:unknown, :image, :video]
enum type: [:unknown, :image, :video], _default: :unknown
enum size: {big: 100, medium: 7, small: 2}, _prefix: :dimension
enum flag: [:clean, :dangerous], _suffix: true

Expand Down Expand Up @@ -37,7 +37,12 @@
end

describe 'getters and setters' do
it 'returns a type as symbol' do
it 'returns nil by default' do
file = StoredFile.new
expect(file.flag).to be_nil
end

it 'returns the default value' do
file = StoredFile.new
expect(file.type).to eq(:unknown)
end
Expand All @@ -55,6 +60,14 @@
expect(StoredFile.as(:f).pluck('f.type')).to eq([2])
expect(file.reload.type).to eq(:video)
end

it 'accepts nil as value' do
file = StoredFile.new
file.flag = nil
file.save!
expect(StoredFile.as(:f).where(id: file.id).pluck('f.flag')).to eq([nil])
expect(file.reload.flag).to eq(nil)
end
end

describe 'scopes' do
Expand Down Expand Up @@ -99,6 +112,12 @@
end

describe '? methods' do
it 'returns false when accessing to a nil value' do
file = StoredFile.new
expect(file).not_to be_clean_flag
expect(file).not_to be_dangerous_flag
end

it 'returns true when the enum is in the current state' do
file = StoredFile.new
file.type = :video
Expand Down
6 changes: 5 additions & 1 deletion spec/shared_examples/destroyable_model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@
subject.save!
@other = subject.class.find_by_id(subject.id)
@old_id = subject.id
subject.destroy
@result = subject.destroy
end
it { is_expected.to be_frozen }

it 'should remove the model from the database' do
expect(subject.class.find_by_id(@old_id)).to be_nil
end

it 'returns the model object' do
expect(@result).to eq(subject)
end
end
end
4 changes: 2 additions & 2 deletions spec/shared_examples/model_schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
it("does not log a warning that the #{index_or_constraint} definition for #{model} is no longer needed") do
model.to_s.constantize.first

expect(@active_base_logger).not_to have_received(:warn)
.with(/WARNING: The #{index_or_constraint} option is no longer supported \(Defined on #{model}#{" for #{property_name}" if property_name}/)
expect(@active_base_logger).not_to have_received(:warn).with(
/WARNING: The #{index_or_constraint} option is no longer supported \(Defined on #{model}#{" for #{property_name}" if property_name}/)
end
end

Expand Down

0 comments on commit 998984a

Please sign in to comment.