From f2c3670c23129f669182fb3d258a1fa7c3bb9b38 Mon Sep 17 00:00:00 2001
From: Israel Barreto Sant'Anna <ibsa14@inf.ufpr.br>
Date: Fri, 18 Sep 2015 12:01:38 -0300
Subject: [PATCH] Subject relations creation working

Signed-off-by: Israel Barreto Sant'Anna <ibsa14@inf.ufpr.br>
---
 Gemfile                                       |  6 ++-
 Gemfile.lock                                  |  7 ++++
 app/models/learning_object.rb                 | 11 +++--
 app/repositories/orient_db/base.rb            |  3 +-
 .../orient_db/learning_object_repository.rb   | 42 +++++++++----------
 .../orient_db/subject_repository.rb           | 27 ++++++------
 config/initializers/repositories/dspace.rb    | 10 ++---
 config/orientdb.yml                           |  2 +-
 lib/orient_db/methods/edge_methods.rb         |  4 +-
 lib/orient_db/methods/generic_methods.rb      |  2 +-
 lib/tasks/orientdb.rake                       | 28 +++++++------
 11 files changed, 77 insertions(+), 65 deletions(-)

diff --git a/Gemfile b/Gemfile
index 70a42ed8..1039b92c 100644
--- a/Gemfile
+++ b/Gemfile
@@ -91,4 +91,8 @@ gem 'rack-mini-profiler'
 gem 'bullet'
 
 # docs
-gem 'rdoc'
\ No newline at end of file
+gem 'rdoc'
+
+#JavaScript runtime
+gem 'execjs'
+gem 'therubyracer'
\ No newline at end of file
diff --git a/Gemfile.lock b/Gemfile.lock
index d45fc6d9..3dbd0d29 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -127,6 +127,7 @@ GEM
       railties (>= 3.1.0)
       turbolinks
     json (1.8.3)
+    libv8 (3.16.14.7)
     locastyle (0.0.1)
     loofah (2.0.3)
       nokogiri (>= 1.5.9)
@@ -190,6 +191,7 @@ GEM
       parser (~> 2.2.0.pre.7)
       rainbow (>= 1.99, < 3.0)
       unparser (~> 0.2.2)
+    ref (1.0.5)
     responders (2.1.0)
       railties (>= 4.2.0, < 5)
     rest-client (1.8.0)
@@ -235,6 +237,9 @@ GEM
       activesupport (>= 3.0)
       sprockets (>= 2.8, < 4.0)
     sqlite3 (1.3.10)
+    therubyracer (0.12.2)
+      libv8 (~> 3.16.14.0)
+      ref
     thor (0.19.1)
     thread_safe (0.3.5)
     tilt (2.0.1)
@@ -285,6 +290,7 @@ DEPENDENCIES
   devise
   devise_token_auth
   dspace_rest_client (~> 1.1.0)
+  execjs
   gruff
   jbuilder (~> 2.0)
   jquery-rails
@@ -308,6 +314,7 @@ DEPENDENCIES
   shoulda-callback-matchers (~> 1.1.1)
   spring
   sqlite3
+  therubyracer
   turbolinks
   uglifier (>= 1.3.0)
   web-console (~> 2.0)
diff --git a/app/models/learning_object.rb b/app/models/learning_object.rb
index 7725479c..dc7102ae 100644
--- a/app/models/learning_object.rb
+++ b/app/models/learning_object.rb
@@ -11,10 +11,15 @@ class LearningObject
   end
 
   def get_metadata_value_of key
-    values = @metadata.select { |v|  v["key"] == key }
-    unless values.empty?
-      return values.first["value"]
+    get_metadata_values_of(key).first
+  end
+
+  def get_metadata_values_of key
+    values = []
+    @metadata.each do |m|
+      values << m["value"] if m["key"] == key
     end
+    values
   end
 
   private
diff --git a/app/repositories/orient_db/base.rb b/app/repositories/orient_db/base.rb
index b31c12f7..684778a9 100644
--- a/app/repositories/orient_db/base.rb
+++ b/app/repositories/orient_db/base.rb
@@ -25,7 +25,7 @@ class OrientDb::Base
   end
 
   def all_after(after_id,limit=-1)
-    objects_hash = connection.query "SELECT FROM #{odb_class} WHERE @rid > #{bigger_than}", :limit => limit
+    objects_hash = connection.query "SELECT FROM #{odb_class} WHERE @rid > #{after_id}", :limit => limit
     objects = build_objects(objects_hash) || []
   end
 
@@ -34,7 +34,6 @@ class OrientDb::Base
     hash.each do |h|
       objects << build_object(h)
     end
-
     objects
   end
 
diff --git a/app/repositories/orient_db/learning_object_repository.rb b/app/repositories/orient_db/learning_object_repository.rb
index e0507839..acfa39f7 100644
--- a/app/repositories/orient_db/learning_object_repository.rb
+++ b/app/repositories/orient_db/learning_object_repository.rb
@@ -2,10 +2,6 @@ module OrientDb
   class LearningObjectRepository < Base
     include OrientDb::Methods::EdgeMethods
 
-    def odb_class
-      "LearningObject"
-    end
-
     def increment_views(learning_object)
       #learning_object.views = learning_object.views + 1
       #save learning_object
@@ -29,20 +25,24 @@ module OrientDb
 
     def create(learning_object)
       hash = build_hash(learning_object)
-      learning_object.id = connection.create_document(hash)
+      result = connection.create_document(hash)
+      learning_object.id = result["@rid"]
       learning_object
     end
 
-    def get_subjects(id)
-      result = connection.query "SELECT expand(out('IsAbout')) FROM #{id}"
+    def get_subjects(learning_object)
+      result = connection.query "SELECT expand(out('IsAbout')) FROM #{learning_object.id}"
       Portalmec::Application.repository.for(:subject).build_objects(result)
     end
 
     def update_relations(learning_object)
+      edges = []
       learning_object.subjects.each do |s|
         unless edge_exists?("IsAbout", learning_object.id, s.id)
-          create_edge("IsAbout", learning_object.id, s.id)
+          edges << create_edge("IsAbout", learning_object.id, s.id)
+        end
       end
+      edges
     end
 
     # Usage:
@@ -86,26 +86,24 @@ module OrientDb
     end
 
     def build_object(args={})
-      lo = LearningObject.new(:id => args["@rid"],
-                              :id_dspace => args["id_dspace"],
-                              :title => args["title"],
-                              :metadata => args)
-      lo.likes = count_likes lo
-      lo.views = count_views lo
+      lo = nil
+      unless args.nil?
+        lo = LearningObject.new(:id => args["@rid"],
+                                :id_dspace => args["id_dspace"],
+                                :name => args["name"],
+                                :metadata => args["metadata"])
+        lo.likes = args.has_key?("in_Likes") ? args["in_Likes"].size : 0
+        lo.views = args.has_key?("in_Views") ? args["in_Views"].size : 0
+      end
       lo
     end
 
-    def build_objects(hash=[])
-      learning_objects = []
-      hash.each do |h|
-        learning_objects << build_object(h)
-      end
+    private
 
-      learning_objects
+    def odb_class
+      "LearningObject"
     end
 
-    private
-
     def count_likes(learning_object)
       get_in_edges_count "Likes", learning_object.id
     end
diff --git a/app/repositories/orient_db/subject_repository.rb b/app/repositories/orient_db/subject_repository.rb
index ff78b360..6e8e36af 100644
--- a/app/repositories/orient_db/subject_repository.rb
+++ b/app/repositories/orient_db/subject_repository.rb
@@ -3,30 +3,27 @@ module OrientDb
 
     def find_by_name(name)
       result = select_by_property(odb_class, "name", name)
-      result.first
+      build_object(result.first)
     end
 
     def create(subject)
-      subject.id = connection.create_document(build_hash(subject))
+      result = connection.create_document(build_hash(subject))
+      subject.id = result["@rid"]
       subject
     end
 
     def build_object(args={})
-      subject = Subject.new(:id => args["@rid"])
-      args.each do |var, val|
-        var_name = "@"+var
-        if subject.respond_to?(var)
-          subject.instance_variable_set(var_name, val)
+      subject = nil
+      unless args.nil?
+        subject = Subject.new(:id => args["@rid"])
+        args.each do |var, val|
+          var_name = "@"+var
+          if subject.respond_to?(var)
+            subject.instance_variable_set(var_name, val)
+          end
         end
       end
-    end
-
-    def build_objects(hash=[])
-      subjects = []
-      hash.each do |h|
-        subjects << build_subject(h)
-      end
-      subjects
+      subject
     end
 
     def build_hash(object)
diff --git a/config/initializers/repositories/dspace.rb b/config/initializers/repositories/dspace.rb
index 0324df56..48a75aab 100644
--- a/config/initializers/repositories/dspace.rb
+++ b/config/initializers/repositories/dspace.rb
@@ -1,10 +1,10 @@
 require 'yaml'
 
 def set_dspace_config(host, port, rest, solr)
-  Dspace::Config.host = config['host']
-  Dspace::Config.port = config['port']
-  Dspace::Config.rest_webapp_name = env_config['rest_webapp_name']
-  Dspace::Config.solr_webapp_name = env_config['solr_webapp_name']
+  Dspace::Config.host = host
+  Dspace::Config.port = port
+  Dspace::Config.rest_webapp_name = rest
+  Dspace::Config.solr_webapp_name = solr
 end
 
 
@@ -15,4 +15,4 @@ else
   config = dspace_configs.fetch(Rails.env)
 
   set_dspace_config config['host'], config['port'], config['rest_webapp_name'], config['solr_webapp_name']
-end
+end
\ No newline at end of file
diff --git a/config/orientdb.yml b/config/orientdb.yml
index 88e5d036..b87506bb 100644
--- a/config/orientdb.yml
+++ b/config/orientdb.yml
@@ -1,6 +1,6 @@
 development: &development
   host: localhost
-  database: portalmec
+  database: PortalMEC
   username: admin
   password: admin
   port: 2480
diff --git a/lib/orient_db/methods/edge_methods.rb b/lib/orient_db/methods/edge_methods.rb
index a2915afc..9a2ea5b2 100644
--- a/lib/orient_db/methods/edge_methods.rb
+++ b/lib/orient_db/methods/edge_methods.rb
@@ -11,8 +11,8 @@ module OrientDb
       end
 
       def edge_exists?(edge_class, from_id, to_id)
-        edge = connection.query sprintf("SELECT outE('%s') FROM %s WHERE out('%s') CONTAINS %s", edge_class, from_id, to_id)
-        edge.empty?
+        edge = connection.query sprintf("SELECT outE('%s') FROM %s WHERE out('%s') CONTAINS %s", edge_class, from_id, edge_class, to_id)
+        !edge.empty?
       end
 
     end
diff --git a/lib/orient_db/methods/generic_methods.rb b/lib/orient_db/methods/generic_methods.rb
index ecb170a4..fe39c0f5 100644
--- a/lib/orient_db/methods/generic_methods.rb
+++ b/lib/orient_db/methods/generic_methods.rb
@@ -7,7 +7,7 @@ module OrientDb
       end
 
       def select_by_property(from, prop_name, prop_value)
-        connection.query sprintf("SELECT FROM %s WHERE %s = %s", from, prop_name, prop_value)
+        connection.query sprintf("SELECT FROM %s WHERE %s = '%s'", from, prop_name, prop_value)
       end
 
     end
diff --git a/lib/tasks/orientdb.rake b/lib/tasks/orientdb.rake
index adffd53a..c7a61c5b 100644
--- a/lib/tasks/orientdb.rake
+++ b/lib/tasks/orientdb.rake
@@ -15,17 +15,17 @@ namespace :orientdb do
     subject_repo = Portalmec::Application.repository.for(:subject)
 
     # Quantity of LearningObjects fetched on each iteration
-    limit = 1000
+    limit = 100
     # Start point from where LearningObjects will be fetched
-    last_id = "#-1:-1"
+    last_id = "#20:74000" # "#-1:-1" # 
 
     loop do
-      puts " --> importing LearningObjects after #{@offset}"
+      puts " --> creating relations for LearningObjects after #{last_id}"
 
       begin
         # Get items from dspace (from offset to offset+limit)
         learning_objects = lo_repo.all_after(last_id,limit)
-        puts learning_objects
+        # puts "learning_objects = "+learning_objects.to_s
       rescue
         # Sleeps for a while to wait database's recovery
         sleep(30.seconds)
@@ -36,19 +36,21 @@ namespace :orientdb do
         break if learning_objects.empty?
 
         learning_objects.each do |lo|
-          subject_name = lo.get_metadata_value_of("dc_subject_category")
-          subject = subject_repo.find_by_name(subject_name)
-          puts subject
-          if subject.nil?
-            subject = Subject.new(:name => subject_name)
-            subject_repo.create(subject)
-          lo.subjects << subject
-          
-          lo_repo.update_relations(lo)
+          subjects = lo.get_metadata_values_of("dc.subject.category")
+          subjects.each do |subject_name|
+            subject = subject_repo.find_by_name(subject_name)
+            if subject.nil?
+              subject = Subject.new(:name => subject_name)
+              subject_repo.create(subject)
+            end
+            lo.subjects << subject
+          end
+          p lo_repo.update_relations(lo)
         end
 
         # Change last id, to get new LearningObjects on next iteration
         last_id = learning_objects.last.id
+      end
     end
   end
 end
\ No newline at end of file
-- 
GitLab