@@ -126,7 +126,7 @@ class Database(Database):
126126 # no fractional seconds for MySQL
127127 hyperdb .Date : lambda x : x .formal (sep = ' ' ),
128128 hyperdb .Link : int ,
129- hyperdb .Interval : lambda x : x . serialise () ,
129+ hyperdb .Interval : str ,
130130 hyperdb .Password : str ,
131131 hyperdb .Boolean : int ,
132132 hyperdb .Number : lambda x : x ,
@@ -190,7 +190,7 @@ def create_version_2_tables(self):
190190 sql = 'insert into ids (name, num) values (%s,%s)' % (self .arg , self .arg )
191191 self .cursor .execute (sql , ('__textids' , 1 ))
192192
193- def add_actor_column (self ):
193+ def add_new_columns_v2 (self ):
194194 '''While we're adding the actor column, we need to update the
195195 tables to have the correct datatypes.'''
196196 for klass in self .classes .values ():
@@ -274,8 +274,15 @@ def add_actor_column(self):
274274 # convert to new MySQL data type
275275 prop = properties [name ]
276276 if v is not None :
277- v = self .hyperdb_to_sql_value [prop .__class__ ](v )
278- l .append (v )
277+ e = self .hyperdb_to_sql_value [prop .__class__ ](v )
278+ l .append (e )
279+
280+ # Intervals store the seconds value too
281+ if isinstance (prop , Interval ):
282+ if v is not None :
283+ l .append (v .as_seconds ())
284+ else :
285+ l .append (e )
279286
280287 self .drop_class_table_indexes (cn , old_spec [0 ])
281288
@@ -595,25 +602,24 @@ def filter(self, search_matches, filterspec, sort=(None,None),
595602 # If range creation fails - ignore that search parameter
596603 pass
597604 elif isinstance (propclass , Interval ):
605+ # filter using the __<prop>_int__ column
598606 if isinstance (v , type ([])):
599607 s = ',' .join ([a for x in v ])
600- where .append ('_%s in (%s)' % (k , s ))
601- args = args + [date .Interval (x ).serialise () for x in v ]
608+ where .append ('__%s_int__ in (%s)' % (k , s ))
609+ args = args + [date .Interval (x ).as_seconds () for x in v ]
602610 else :
603611 try :
604612 # Try to filter on range of intervals
605613 date_rng = Range (v , date .Interval )
606- if ( date_rng .from_value ) :
607- where .append ('_%s >= %s' % (k , a ))
608- args .append (date_rng .from_value .serialise ())
609- if ( date_rng .to_value ) :
610- where .append ('_%s <= %s' % (k , a ))
611- args .append (date_rng .to_value .serialise ())
614+ if date_rng .from_value :
615+ where .append ('__%s_int__ >= %s' % (k , a ))
616+ args .append (date_rng .from_value .as_seconds ())
617+ if date_rng .to_value :
618+ where .append ('__%s_int__ <= %s' % (k , a ))
619+ args .append (date_rng .to_value .as_seconds ())
612620 except ValueError :
613621 # If range creation fails - ignore that search parameter
614622 pass
615- #where.append('_%s=%s'%(k, a))
616- #args.append(date.Interval(v).serialise())
617623 else :
618624 if isinstance (v , type ([])):
619625 s = ',' .join ([a for x in v ])
@@ -634,49 +640,42 @@ def filter(self, search_matches, filterspec, sort=(None,None),
634640 args = args + v
635641
636642 # "grouping" is just the first-order sorting in the SQL fetch
637- # can modify it...)
638643 orderby = []
639644 ordercols = []
640- if group [0 ] is not None and group [1 ] is not None :
641- if group [0 ] != '-' :
642- orderby .append ('_' + group [1 ])
643- ordercols .append ('_' + group [1 ])
644- else :
645- orderby .append ('_' + group [1 ]+ ' desc' )
646- ordercols .append ('_' + group [1 ])
647-
648- # now add in the sorting
649- group = ''
650- if sort [0 ] is not None and sort [1 ] is not None :
651- direction , colname = sort
652- if direction != '-' :
653- if colname == 'id' :
654- orderby .append (colname )
655- else :
656- orderby .append ('_' + colname )
657- ordercols .append ('_' + colname )
658- else :
659- if colname == 'id' :
660- orderby .append (colname + ' desc' )
661- ordercols .append (colname )
645+ mlsort = []
646+ for sortby in group , sort :
647+ sdir , prop = sortby
648+ if sdir and prop :
649+ if isinstance (props [prop ], Multilink ):
650+ mlsort .append (sortby )
651+ continue
652+ elif isinstance (props [prop ], Interval ):
653+ # use the int column for sorting
654+ o = '__' + prop + '_int__'
655+ ordercols .append (o )
656+ elif prop == 'id' :
657+ o = 'id'
662658 else :
663- orderby .append ('_' + colname + ' desc' )
664- ordercols .append ('_' + colname )
659+ o = '_' + prop
660+ ordercols .append (o )
661+ if sdir == '-' :
662+ o += ' desc'
663+ orderby .append (o )
665664
666665 # construct the SQL
667666 frum = ',' .join (frum )
668667 if where :
669668 where = ' where ' + (' and ' .join (where ))
670669 else :
671670 where = ''
672- cols = ['id ' ]
671+ cols = ['distinct(id) ' ]
673672 if orderby :
674673 cols = cols + ordercols
675674 order = ' order by %s' % (',' .join (orderby ))
676675 else :
677676 order = ''
678677 cols = ',' .join (cols )
679- sql = 'select %s from %s %s%s%s ' % (cols , frum , where , group , order )
678+ sql = 'select %s from %s %s%s' % (cols , frum , where , order )
680679 args = tuple (args )
681680 if __debug__ :
682681 print >> hyperdb .DEBUG , 'filter' , (self , sql , args )
@@ -685,7 +684,28 @@ def filter(self, search_matches, filterspec, sort=(None,None),
685684
686685 # return the IDs (the first column)
687686 # XXX numeric ids
688- return [str (row [0 ]) for row in l ]
687+ l = [str (row [0 ]) for row in l ]
688+
689+ if not mlsort :
690+ return l
691+
692+ # ergh. someone wants to sort by a multilink.
693+ r = []
694+ for id in l :
695+ m = []
696+ for ml in mlsort :
697+ m .append (self .get (id , ml [1 ]))
698+ r .append ((id , m ))
699+ i = 0
700+ for sortby in mlsort :
701+ def sortfun (a , b , dir = sortby [i ]):
702+ if dir == '-' :
703+ return cmp (b [1 ][i ], a [1 ][i ])
704+ else :
705+ return cmp (a [1 ][i ], b [1 ][i ])
706+ r .sort (sortfun )
707+ i += 1
708+ return [i [0 ] for i in r ]
689709
690710class Class (MysqlClass , rdbms_common .Class ):
691711 pass
0 commit comments