<s> import itertools <EOL> from django . conf import settings <EOL> from django . db import models <EOL> from django . utils import translation as translation_utils <EOL> from olympia . addons . query import IndexCompiler , IndexQuery <EOL> def order_by_translation ( qs , fieldname ) : <EOL> """<STR_LIT>""" <EOL> if fieldname . startswith ( '<STR_LIT:->' ) : <EOL> desc = True <EOL> fieldname = fieldname [ <NUM_LIT:1> : ] <EOL> else : <EOL> desc = False <EOL> qs = qs . all ( ) <EOL> model = qs . model <EOL> field = model . _meta . get_field ( fieldname ) <EOL> connection = ( model . _meta . db_table , field . rel . to . _meta . db_table , <EOL> field . rel . field_name ) <EOL> if not qs . query . tables : <EOL> qs . query . get_initial_alias ( ) <EOL> qs . query = qs . query . clone ( TranslationQuery ) <EOL> t1 = qs . query . join ( connection , join_field = field , reuse = set ( ) , <EOL> nullable = True ) <EOL> t2 = qs . query . join ( connection , join_field = field , reuse = set ( ) , <EOL> nullable = True ) <EOL> qs . query . translation_aliases = { field : ( t1 , t2 ) } <EOL> f1 , f2 = '<STR_LIT>' % t1 , '<STR_LIT>' % t2 <EOL> name = '<STR_LIT>' % field . column <EOL> ifnull = '<STR_LIT>' % ( f1 , f2 ) <EOL> prefix = '<STR_LIT:->' if desc else '<STR_LIT>' <EOL> return qs . extra ( select = { name : ifnull } , <EOL> where = [ '<STR_LIT>' % ( f1 , f2 ) ] , <EOL> order_by = [ prefix + name ] ) <EOL> class TranslationQuery ( IndexQuery ) : <EOL> """<STR_LIT>""" <EOL> def clone ( self , klass = None , ** kwargs ) : <EOL> c = super ( TranslationQuery , self ) . clone ( klass , ** kwargs ) <EOL> c . translation_aliases = self . translation_aliases <EOL> return c <EOL> def get_compiler ( self , using = None , connection = None ) : <EOL> c = super ( TranslationQuery , self ) . get_compiler ( using , connection ) <EOL> return SQLCompiler ( self , c . connection , c . using ) <EOL> class SQLCompiler ( IndexCompiler ) : <EOL> """<STR_LIT>""" <EOL> def get_from_clause ( self ) : <EOL> old_tables = list ( self . query . tables ) <EOL> for table in itertools . chain ( * self . query . translation_aliases . values ( ) ) : <EOL> self . query . tables . remove ( table ) <EOL> joins , params = super ( SQLCompiler , self ) . get_from_clause ( ) <EOL> params . append ( translation_utils . get_language ( ) ) <EOL> if hasattr ( self . query . model , '<STR_LIT>' ) : <EOL> fallback = self . query . model . get_fallback ( ) <EOL> else : <EOL> fallback = settings . LANGUAGE_CODE <EOL> if not isinstance ( fallback , models . Field ) : <EOL> params . append ( fallback ) <EOL> for field , aliases in self . query . translation_aliases . items ( ) : <EOL> t1 , t2 = aliases <EOL> joins . append ( self . join_with_locale ( t1 ) ) <EOL> joins . append ( self . join_with_locale ( t2 , fallback ) ) <EOL> self . query . tables = old_tables <EOL> return joins , params <EOL> def join_with_locale ( self , alias , fallback = None ) : <EOL> qn = self . quote_name_unless_alias <EOL> qn2 = self . connection . ops . quote_name <EOL> mapping = self . query . alias_map [ alias ] <EOL> name , alias , join_type , lhs , join_cols , _ , join_field = mapping <EOL> lhs_col = join_field . column <EOL> rhs_col = join_cols <EOL> alias_str = '<STR_LIT>' if alias == name else ( '<STR_LIT>' % alias ) <EOL> if isinstance ( fallback , models . Field ) : <EOL> fallback_str = '<STR_LIT>' % ( qn ( self . query . model . _meta . db_table ) , <EOL> qn ( fallback . column ) ) <EOL> else : <EOL> fallback_str = '<STR_LIT:%s>' <EOL> return ( '<STR_LIT>' % <EOL> ( join_type , qn ( name ) , alias_str , <EOL> qn ( lhs ) , qn2 ( lhs_col ) , qn ( alias ) , qn2 ( rhs_col ) , <EOL> qn ( alias ) , qn ( '<STR_LIT>' ) , fallback_str ) ) </s>
