Module: ActiveCypher::ConnectionAdapters::PersistenceMethods
- Included in:
- MemgraphAdapter::Persistence, Neo4jAdapter::Persistence
- Defined in:
- lib/active_cypher/connection_adapters/persistence_methods.rb
Overview
Common persistence helpers shared by adapters
Instance Method Summary collapse
-
#create_record(model) ⇒ Boolean
Create a record in the database and update model state.
-
#destroy_record(model) ⇒ Boolean
Destroy a record in the database.
-
#update_record(model) ⇒ Boolean
Update a record in the database based on model changes.
Instance Method Details
#create_record(model) ⇒ Boolean
Create a record in the database and update model state.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/active_cypher/connection_adapters/persistence_methods.rb', line 10 def create_record(model) props = model.send(:attributes_for_persistence) labels = if model.class.respond_to?(:labels) model.class.labels else [model.class.label_name.to_s] end adapter = model.connection.id_handler # OPTIMIZED: Use string template instead of Cyrel for known-safe CREATE pattern # Labels come from model class (safe), props are parameterized (safe) label_string = labels.map { |l| ":#{l}" }.join cypher = if adapter.id_function == 'elementId' "CREATE (n#{label_string} $props) RETURN elementId(n) AS internal_id" else "CREATE (n#{label_string} $props) RETURN id(n) AS internal_id" end data = model.connection.execute_cypher(cypher, { props: props }, 'Create') return false if data.blank? || !data.first.key?(:internal_id) model.internal_id = data.first[:internal_id] model.instance_variable_set(:@new_record, false) model.send(:changes_applied) true end |
#destroy_record(model) ⇒ Boolean
Destroy a record in the database.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/active_cypher/connection_adapters/persistence_methods.rb', line 78 def destroy_record(model) labels = if model.class.respond_to?(:labels) model.class.labels else [model.class.label_name] end adapter = model.connection.id_handler # Convert internal_id to whatever format makes the database feel validated # It's like therapy, but for graph databases node_id_param = adapter.id_function == 'elementId' ? model.internal_id.to_s : model.internal_id.to_i # OPTIMIZED: Use string template for known-safe DELETE pattern # Labels come from model class (safe) label_string = labels.map { |l| ":#{l}" }.join cypher = if adapter.id_function == 'elementId' "MATCH (n#{label_string}) WHERE elementId(n) = $node_id DETACH DELETE n RETURN count(*) AS deleted" else "MATCH (n#{label_string}) WHERE id(n) = $node_id DETACH DELETE n RETURN count(*) AS deleted" end result = model.connection.execute_cypher(cypher, { node_id: node_id_param }, 'Destroy') result.present? && result.first[:deleted].to_i.positive? end |
#update_record(model) ⇒ Boolean
Update a record in the database based on model changes.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/active_cypher/connection_adapters/persistence_methods.rb', line 42 def update_record(model) changes = model.send(:changes_to_save) return true if changes.empty? labels = if model.class.respond_to?(:labels) model.class.labels else [model.class.label_name.to_s] end adapter = model.connection.id_handler # Convert internal_id to its preferred existential format # Neo4j wants strings because it's complicated, Memgraph wants integers because it's not node_id_param = adapter.id_function == 'elementId' ? model.internal_id.to_s : model.internal_id.to_i # OPTIMIZED: Use string template for known-safe UPDATE pattern # Labels come from model class (safe), property names from model attributes (safe) label_string = labels.map { |l| ":#{l}" }.join set_clauses = changes.keys.map { |property| "n.#{property} = $#{property}" }.join(', ') cypher = if adapter.id_function == 'elementId' "MATCH (n#{label_string}) WHERE elementId(n) = $node_id SET #{set_clauses} RETURN n" else "MATCH (n#{label_string}) WHERE id(n) = $node_id SET #{set_clauses} RETURN n" end params = changes.merge(node_id: node_id_param) model.connection.execute_cypher(cypher, params, 'Update') model.send(:changes_applied) true end |