sort by plus cards+solution

sort should be able to take a hash.

 

Here's the ruby long form for a plus card sort to sort Call cards by the content of a +call number card:

{ type: 'Call',
  sort:{
    :right=>'call_number',
    :left=>'_item', # this means the result item is the left part of the sort card. # this is the hard part, because it requires special handling based on the value # this probably has to be the value of a root-level key, and may only work for a limited set.
    :return=>'content' # this should probably be the default for anything with a cardspec
    :cast  =>'integer' # this means sort the content as numbers (1,2,3), not strings (1,10,100). Strings is default for 'content'
  }
}

rough version of the sql that translates to:

  select c.name, 
    cast(s.content as integer) as sort_field                   
  from cards c
  left join (
    select z.trunk_id, r.content from cards z 
    join revisions r on r.card_id = z.id 
    where z.tag_id in 
      ( select id from cards tx  where tx.key = 'call_number' ) 
  ) s 
  on c.id = s.trunk_id
  where c.type='Call' and c.trash is false                    
  order by sort_field limit 10;

 

Ruby long form for sorting territories based on the number of users in them (as represented by [user]+territory)

 

{ type: 'Territory',
  sort:{
  :left =>{:type=>'User'},
  :right =>'Territory',
  :return =>'count', #not sure "return" is right word here, but it parallels normal wql usage
  :refer_to =>'_item'
  },
  :dir => 'desc'
}

 

and the sql:

  select c.name, coalesce(count,0) as sort_field 
  from cards c
  left join (
    select z.id, count(*) as count
    from cards z
    join wiki_references r on r.referenced_card_id = z.id
    where r.card_id in (
      select id from cards tx                                            
      where tx.tag_id in
        (select id from cards txx where txx.key = 'territory') 
      and tx.trunk_id in 
        (select id from cards txx  where txx.extension_type = 'User')
    )
    group by z.id
  ) s                                                          
  on c.id = s.id
  where c.type='Zone' 
  and c.trash is false                    
  order by sort_field desc
  limit 10;

 

You can also do variations on the current sort results.  For example, to sort a list of cards by their content numerically, you can do this:

sort: { :return=> 'content', :cast=>'integer' }

As for having multiple sort variables, I think at this point that becomes comparatively simple -- you just give the sort argument an array.  Eg

sort:
[ { :right=>'last name', :left=>'_item' },
  { :right=>'first name', :left=>'_item' }, 'update' ]

We may also want to add shortcuts for plus card sorts, like { :sort => '+last name' }, but the full syntax is important and will have to be deduced anyway, and the shortcut conversation would probably have other higher priorities.