<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>lib/sync/client_mapper.rb</filename>
    </added>
    <added>
      <filename>spec/models/libs/sync/client_mapper_spec.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,8 +1,4 @@
-require 'digest/md5'
-require 'yaml'
-require 'open-uri'
-require 'net/http'
-require 'net/https'
+require 'sync'
 require 'source_adapter'
 
 class SourcesController &lt; ApplicationController
@@ -15,9 +11,7 @@ class SourcesController &lt; ApplicationController
   SUPPORTED_VERSIONS = [2]
 
   include SourcesHelper
-  # shows all object values in XML structure given a supplied source
-  # if a :last_update parameter is supplied then only show data that has been
-  # refreshed (retrieved from the backend) since then
+  include Sync
   protect_from_forgery :only =&gt; [:create, :delete, :update]
 
   def callback
@@ -516,6 +510,7 @@ protected
   end
   
   def get_wrapped_list(ovlist)
-    @wrapped_list = wrap_object_values(ovlist,@token) if @version
+    @cmapper = ClientMapper.new(@client,@token,@app)
+    @wrapped_list = @cmapper.wrap_object_values(ovlist) if @version
   end
 end</diff>
      <filename>app/controllers/sources_controller.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,2 +1,15 @@
 module ClientsHelper
+  def setup_client(client_id)
+    # setup client &amp; user association if it doesn't exist
+    if client_id and client_id != 'client_id'
+      @client = Client.find_by_client_id(client_id)
+      if @client.nil?
+        @client = Client.new
+        @client.client_id = client_id
+      end
+      @client.user ||= current_user
+      @client.save
+    end
+    @client
+  end
 end</diff>
      <filename>app/helpers/clients_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,9 @@
+require 'sync'
+
 module SourcesHelper
+  
+  include ClientsHelper
+  include Sync
 
   def slog(e,msg,source_id=self.id,operation=nil,timing=nil)
     begin
@@ -309,7 +314,7 @@ module SourcesHelper
       if @source.queuesync and @source.needs_refresh
         @object_values=[]
       else
-        @object_values=process_objects_for_client(@source,@client,@token,@ack_token,@resend_token,p_size,@first_request,by_source)
+        @object_values=ClientMapper.process_objects_for_client(current_user,@source,@client,@token,@ack_token,@resend_token,p_size,@first_request,by_source)
       end
       # set token depending on records returned
       # if we sent zero records, we need to keep track so the client
@@ -326,136 +331,4 @@ module SourcesHelper
     end
     @object_values.delete_if {|o| o.value.nil? || o.value.size&lt;1 } # don't send back blank or nil OAV triples
   end
-
-  def setup_client(client_id)
-    # setup client &amp; user association if it doesn't exist
-    if client_id and client_id != 'client_id'
-      @client = Client.find_by_client_id(client_id)
-      if @client.nil?
-        @client = Client.new
-        @client.client_id = client_id
-      end
-      @client.user ||= current_user
-      @client.save
-    end
-    @client
-  end
-  
-  # wrap object-values by object and source
-  def wrap_object_values(ovlist,token)
-    @count = 0
-    list = {}
-    temp_count = @client.client_temp_objects.count
-    
-    # process the ovlist (this will also include successful create objects)
-    sources = @app.sources
-    srchash = {}
-    sources.each do |src|
-      srchash[src.id] = src.name
-    end
-    
-    ovlist.each do |ov|
-      src_name = srchash[ov.source_id]
-      src_name ||= 'RhoDeleteSource'
-      obj_sym = ov.object.nil? ? nil : ov.object.to_sym
-      obj_sym ||= :rho_del_obj
-      old_obj = nil
-      av_hash = { :i =&gt; ov.id, :d =&gt; ov.db_operation, :a =&gt; ov.attrib, :v =&gt; ov.value }
-                  
-      if temp_count &gt; 0
-        # find the temp_obj that corresponds to the successful create
-        tmp_obj = @client.client_temp_objects.find(:first, :conditions =&gt; {:objectid =&gt; ov.object, :error =&gt; nil})
-      end
-      old_objid = tmp_obj.temp_objectid if tmp_obj
-      if list[src_name]
-        if list[src_name][obj_sym]
-          list[src_name][obj_sym][:av] &lt;&lt; av_hash
-          @count +=1
-        else
-          list[src_name][obj_sym] = { :oo =&gt; old_objid, :av =&gt; [av_hash] }
-          @count +=1
-        end
-      else
-        list[src_name] = { obj_sym =&gt; { :oo =&gt; old_objid, :av =&gt; [av_hash] } }
-        @count +=1
-      end
-    end
-    error_objs = ClientTempObject.find(:all, :conditions =&gt; &quot;client_id = '#{@client.client_id}' and error is not NULL&quot;)
-    
-    error_objs.each do |err_obj|
-      src_name = err_obj.source.nil? ? nil : err_obj.source.name
-      if list[src_name]
-        list[src_name][err_obj.temp_objectid.to_sym] = { :oo =&gt; err_obj.temp_objectid, :e =&gt; err_obj.error }
-        @count +=1
-      else
-        list[src_name] = { err_obj.temp_objectid.to_sym =&gt; { :oo =&gt; err_obj.temp_objectid, :e =&gt; err_obj.error } }
-        @count +=1
-      end
-      
-      # make sure to set token, this may be the only object in the list
-      @token = err_obj.token unless @token
-    end
-    list
-  end
-
-  # creates an object_value list for a given client
-  # based on that client's client_map records
-  # and the current state of the object_values table
-  # since we do a delete_all in rhosync refresh,
-  # only delete and insert are required
-  def process_objects_for_client(source,client,token,ack_token,resend_token,p_size=nil,first_request=false,by_source=nil)
-
-    # default page size of 10000
-    page_size = p_size.nil? ? 10000 : p_size.to_i
-    last_sync_time = Time.now
-    objs_to_return = []
-    by_source_condition = &quot;and ov.source_id=#{source.id}&quot; if by_source
-    user_condition = &quot;= #{current_user.id}&quot; if current_user and current_user.id
-    user_condition ||= &quot;is NULL&quot;
-
-    # Setup the query conditions
-    object_value_insert_query = &quot;from object_values ov where ov.update_type='query' #{by_source_condition} and ov.user_id #{user_condition}
-        and not exists (select object_value_id from client_maps where ov.id=object_value_id and client_id='#{client.id}') order by ov.object,ov.id limit #{page_size}&quot;
-
-    object_value_query = &quot;select * from object_values ov inner join client_maps on ov.id = client_maps.object_value_id where token = '#{token}' order by ov.object,ov.id&quot;
-
-    # setup fields to insert in client_maps table
-    object_insert_query = &quot;select '#{client.id}',id,'insert','#{token}' #{object_value_insert_query}&quot;
-
-    # if we're resending the token, quickly return the results (inserts + deletes)
-    if resend_token
-      logger.debug &quot;Resending token, resend_token: #{resend_token.inspect}&quot;
-      objs_to_return = ClientMap.get_delete_objs_by_token_status(client.id,resend_token)
-      client.update_attributes({:updated_at =&gt; last_sync_time, :last_sync_token =&gt; resend_token})
-      objs_to_return.concat( ClientMap.get_insert_objs_by_token_status(client.id,resend_token) )
-    else
-      logger.debug &quot;ack_token: #{ack_token.inspect}, using new token: #{token.inspect}&quot;
-
-      # mark acknowledged token so we don't send it again
-      ClientMap.mark_objs_by_ack_token(ack_token) if ack_token and ack_token.length &gt; 0
-
-      # find delete records
-      objs_to_return.concat( ClientMap.get_delete_objs_for_client(token,page_size,client.id) )
-      
-      # process temp objects for this client
-      ClientMap.process_create_objs_for_client(client.id,source.id,token)
-
-      # find + save insert records
-      ClientMap.insert_new_client_maps(object_insert_query)
-      objs_to_insert = ObjectValue.find_by_sql object_value_query
-      objs_to_insert.collect! {|x| x.db_operation = 'insert'; x}
-
-      # Update the last updated time for this client
-      # to track the last sync time
-      client.update_attribute(:updated_at, last_sync_time)
-      objs_to_return.concat(objs_to_insert)
-
-      if token and objs_to_return.length &gt; 0
-        client.update_attribute(:last_sync_token, token)
-      else
-        client.update_attribute(:last_sync_token, nil)
-      end
-    end
-    objs_to_return
-  end
 end</diff>
      <filename>app/helpers/sources_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1 +1 @@
-[{count:&lt;%=@count%&gt;},{version:&lt;%=@version%&gt;}&lt;%if @total_count and @total_count &gt; 0 and @count &gt; 0%&gt;,{total_count:&lt;%=@total_count%&gt;}&lt;%end%&gt;&lt;%if @token%&gt;,{token:&quot;&lt;%=@token%&gt;&quot;},&lt;%end%&gt;&lt;%wlist_size = 0%&gt;&lt;%@wrapped_list.each do |source_name,oblist|%&gt;{s:&quot;&lt;%=source_name%&gt;&quot;,ol:[&lt;%ob_size = 0%&gt;&lt;%oblist.each do |objkey,obj|%&gt;{&lt;%if obj[:oo]%&gt;oo:&quot;&lt;%=obj[:oo]%&gt;&quot;,&lt;%end%&gt;&lt;%if obj[:e]%&gt;e:&quot;&lt;%=obj[:e]%&gt;&quot;}&lt;%else%&gt;o:&quot;&lt;%=objkey%&gt;&quot;,av:[&lt;%obj[:av].each_with_index do |o,i|%&gt;&lt;%if o[:d] == &quot;delete&quot;%&gt;{i:&lt;%=o[:i]%&gt;}&lt;%else%&gt;{a:&quot;&lt;%=o[:a]%&gt;&quot;,i:&lt;%=o[:i]%&gt;,v:&lt;%=o[:v].to_json -%&gt;}&lt;%end%&gt;&lt;%=i &lt; obj[:av].length-1 ? &quot;,&quot; : &quot;]}&quot;%&gt;&lt;%end%&gt;&lt;%=ob_size &lt; oblist.length-1 ? &quot;,&quot; : nil%&gt;&lt;%ob_size += 1%&gt;&lt;%end%&gt;&lt;%end%&gt;]}&lt;%=wlist_size &lt; @wrapped_list.length-1 ? &quot;,&quot; : nil%&gt;&lt;%wlist_size += 1%&gt;&lt;%end%&gt;]
\ No newline at end of file
+[{count:&lt;%=@cmapper.count%&gt;},{version:&lt;%=@version%&gt;}&lt;%if @total_count and @total_count &gt; 0 and @cmapper.count &gt; 0%&gt;,{total_count:&lt;%=@total_count%&gt;}&lt;%end%&gt;&lt;%if @cmapper.token%&gt;,{token:&quot;&lt;%=@cmapper.token%&gt;&quot;},&lt;%end%&gt;&lt;%wlist_size = 0%&gt;&lt;%@wrapped_list.each do |source_name,oblist|%&gt;{s:&quot;&lt;%=source_name%&gt;&quot;,ol:[&lt;%ob_size = 0%&gt;&lt;%oblist.each do |objkey,obj|%&gt;{&lt;%if obj[:oo]%&gt;oo:&quot;&lt;%=obj[:oo]%&gt;&quot;,&lt;%end%&gt;&lt;%if obj[:e]%&gt;e:&quot;&lt;%=obj[:e]%&gt;&quot;}&lt;%else%&gt;o:&quot;&lt;%=objkey%&gt;&quot;,av:[&lt;%obj[:av].each_with_index do |o,i|%&gt;&lt;%if o[:d] == &quot;delete&quot;%&gt;{i:&lt;%=o[:i]%&gt;}&lt;%else%&gt;{a:&quot;&lt;%=o[:a]%&gt;&quot;,i:&lt;%=o[:i]%&gt;,v:&lt;%=o[:v].to_json -%&gt;}&lt;%end%&gt;&lt;%=i &lt; obj[:av].length-1 ? &quot;,&quot; : &quot;]}&quot;%&gt;&lt;%end%&gt;&lt;%=ob_size &lt; oblist.length-1 ? &quot;,&quot; : nil%&gt;&lt;%ob_size += 1%&gt;&lt;%end%&gt;&lt;%end%&gt;]}&lt;%=wlist_size &lt; @wrapped_list.length-1 ? &quot;,&quot; : nil%&gt;&lt;%wlist_size += 1%&gt;&lt;%end%&gt;]
\ No newline at end of file</diff>
      <filename>app/views/sources/show.json_v2.erb</filename>
    </modified>
    <modified>
      <diff>@@ -1,14 +1,12 @@
 require 'sync'
 
-class SourceAdapterException &lt; RuntimeError
-end
+class SourceAdapterException &lt; RuntimeError; end
 
 # raise this to cause client to be logged out during a sync
 class SourceAdapterLoginException &lt; SourceAdapterException; end
 
 # raise these to trigger rhosync sending an error to the client
 class SourceAdapterServerTimeoutException &lt; SourceAdapterException; end
-
 class SourceAdapterServerErrorException &lt; SourceAdapterException; end
 
 class SourceAdapter
@@ -37,21 +35,18 @@ class SourceAdapter
     default_sync.sync
   end
   
-  def create(name_value_list)
-  end
+  def create(name_value_list); end
 
   def update(name_value_list); end
 
   def delete(name_value_list); end
 
-  def logoff
-  end
+  def logoff; end
   
   # only implement this if you want RhoSync to install a callback into your backend
   # def set_callback(notify_url)
   # end
   
-  
   MSG_NO_OBJECTS = &quot;No objects returned from query&quot;
   MSG_NIL_RESULT_ATTRIB = &quot;You might have expected a synchronization but the @result attribute was 'nil'&quot;
   </diff>
      <filename>lib/source_adapter.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,2 +1,3 @@
 require 'sync/synchronizer'
+require 'sync/client_mapper'
 require 'sync/errors'</diff>
      <filename>lib/sync.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>1369d47a18c66f5772a512fae6342dc6c310818e</id>
    </parent>
  </parents>
  <author>
    <name>lars</name>
    <email>larsburgess@gmail.com</email>
  </author>
  <url>http://github.com/rhomobile/rhosync/commit/1534d893b42332120e1e005e35b588ae2ffb4e77</url>
  <id>1534d893b42332120e1e005e35b588ae2ffb4e77</id>
  <committed-date>2009-10-22T13:54:29-07:00</committed-date>
  <authored-date>2009-10-22T13:54:29-07:00</authored-date>
  <message>refactoring client-mapping methods to Sync module, working on removing deletes from delete/inserts [#264]</message>
  <tree>70298afcd07058c6b88c5d098c75beb97b116387</tree>
  <committer>
    <name>lars</name>
    <email>larsburgess@gmail.com</email>
  </committer>
</commit>
