Changeset 16439

Show
Ignore:
Timestamp:
05/22/08 21:43:48 (3 months ago)
Author:
piotras
Message:

Multilang fallback ported from 1-9

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/midgard/core/midgard/src/midgard_core_query_builder.c

    r16242 r16439  
    3232#include "midgard_user.h" 
    3333#include "midgard_core_object.h" 
     34#include "midgard_object_class.h" 
    3435 
    3536MidgardQueryBuilderPrivate *midgard_query_builder_private_new(void) 
     
    125126} 
    126127 
     128gboolean _midgard_core_qb_is_multilingual(MidgardQueryBuilder *builder) 
     129{ 
     130        MidgardObjectClass *klass = (MidgardObjectClass*)g_type_class_peek(builder->priv->type); 
     131        MidgardConnection *mgd = builder->priv->mgd; 
     132         
     133        if(!midgard_object_class_is_multilang(klass)) 
     134                return FALSE; 
     135         
     136        if(builder->priv->unset_lang) 
     137                return FALSE; 
     138         
     139        if(MGD_GET_LANG_ID(mgd) == MGD_GET_DEFAULT_LANG_ID(mgd)) 
     140                return FALSE; 
     141         
     142        if(builder->priv->lang < 0) 
     143                return TRUE; 
     144         
     145        return FALSE; 
     146} 
     147 
     148static void __sql_add_constraints(GString *sql, MidgardQueryBuilder *builder) 
     149{ 
     150        GSList *clist = NULL; 
     151        GSList *jlist = NULL; 
     152        guint j = 0; 
     153         
     154        for(clist = builder->priv->constraints; 
     155                        clist != NULL; clist = clist->next) { 
     156                 
     157                if(j > 0) 
     158                        g_string_append(sql, " AND "); 
     159                 
     160                g_string_append(sql, 
     161                                MIDGARD_QUERY_CONSTRAINT(clist->data)->priv->condition); 
     162                 
     163                for(jlist = ((MidgardQueryConstraint*)clist->data)->priv->joins; 
     164                                jlist != NULL; jlist = jlist->next) { 
     165                         
     166                        g_string_append(sql, " AND "); 
     167                        g_string_append(sql, 
     168                                        ((MidgardQueryConstraintPrivate*)jlist->data)->condition); 
     169                } 
     170                 
     171                j++; 
     172        } 
     173         
     174        if(builder->priv->constraints == NULL) 
     175                g_string_append(sql, "1=1"); 
     176} 
     177 
    127178gchar *_midgard_core_qb_get_sql( 
    128179                MidgardQueryBuilder *builder, guint mode, gchar *select) 
     
    133184        /* FIXME, error reporting needed */ 
    134185        if(builder->priv->error != 0) { 
    135             g_warning("Can not create query"); 
    136             return NULL; 
     186               g_warning("Can not create query"); 
     187               return NULL; 
    137188        } 
     189 
     190        guint multilang_fallback = _midgard_core_qb_is_multilingual(builder); 
     191        MidgardConnection *mgd = builder->priv->mgd; 
    138192 
    139193        /* SELECT */ 
     
    147201        g_hash_table_foreach(builder->priv->tables, _add_table_foreach, &tlist); 
    148202 
     203        GString *tables = g_string_new(""); 
     204 
    149205        guint l = 0; 
    150206        GSList *nlist;  
     
    152208         
    153209                if(l < 1) 
    154                         g_string_append(sql, (gchar *) nlist->data); 
     210                        g_string_append(tables, (gchar *) nlist->data); 
    155211                else  
    156                         g_string_append_printf(sql,  
     212                        g_string_append_printf(tables,  
    157213                                        ", %s", (gchar *) nlist->data); 
    158214                l++; 
     
    161217                g_slist_free(tlist); 
    162218 
     219        g_string_append(sql, tables->str); 
     220 
    163221        /* WHERE */ 
    164222        g_string_append(sql, " WHERE "); 
    165223         
    166         GSList *clist = NULL; 
    167         GSList *jlist = NULL; 
    168         guint j = 0; 
    169  
    170         for(clist = builder->priv->constraints;  
    171                         clist != NULL; clist = clist->next) { 
    172          
    173                 if(j > 0) 
    174                         g_string_append(sql, " AND "); 
    175  
    176                 g_string_append(sql,  
    177                                 MIDGARD_QUERY_CONSTRAINT(clist->data)->priv->condition); 
    178  
    179                 for(jlist = ((MidgardQueryConstraint*)clist->data)->priv->joins;  
    180                                 jlist != NULL; jlist = jlist->next) { 
    181  
    182                         g_string_append(sql, " AND "); 
    183                         g_string_append(sql,  
    184                                         ((MidgardQueryConstraintPrivate*)jlist->data)->condition); 
    185                 } 
    186  
    187                 j++; 
    188         } 
    189  
    190         if(builder->priv->constraints == NULL) 
    191                 g_string_append(sql, "1=1"); 
     224        __sql_add_constraints(sql, builder); 
     225 
     226        /* MULTILANG FALLBACK */ 
     227        if(multilang_fallback) { 
     228         
     229                guint lang, dlang; 
     230                lang = midgard_connection_get_lang_id(builder->priv->mgd,  
     231                                midgard_connection_get_lang(builder->priv->mgd)); 
     232                dlang = midgard_connection_get_lang_id(builder->priv->mgd,  
     233                                midgard_connection_get_default_lang(builder->priv->mgd)); 
     234 
     235 
     236                g_string_append_printf(sql, " AND %s_i.id IN (", builder->priv->schema->table); 
     237                g_string_append_printf(sql, " SELECT ABS(MIN(i_id)) as i_id FROM (SELECT sid, " 
     238                                "CASE WHEN lang=%d THEN %s_i.id*-1 ELSE %s_i.id END AS i_id FROM " 
     239                                "%s  WHERE %s_i.sid = %s.id AND lang IN (%d,%d) ", 
     240                                lang, 
     241                                builder->priv->schema->table, builder->priv->schema->table, 
     242                                tables->str, builder->priv->schema->table, builder->priv->schema->table, 
     243                                lang, dlang); 
     244                 
     245                g_string_append(sql, " AND "); 
     246                __sql_add_constraints(sql, builder); 
     247                 
     248                g_string_append(sql, " ) AS midgard_multilang_fallback_table GROUP BY sid )"); 
     249        } 
     250 
     251        g_string_free(tables, TRUE); 
    192252 
    193253        if(builder->priv->groups != NULL) { 
     
    207267        /* Join tables from ORDER BY */ 
    208268        GSList *olist = NULL; 
    209         jlist = NULL; 
     269        GSList *jlist = NULL; 
    210270        guint i = 0; 
    211271        if(builder->priv->orders != NULL) { 
     
    226286 
    227287        if (builder->priv->schema->use_lang == 1) { 
     288 
    228289                g_string_append(sql, " AND "); 
    229290                g_string_append(sql, builder->priv->schema->table); 
     
    232293                g_string_append(sql, "_i.sid");   
    233294                
    234                 if(!builder->priv->unset_lang) { 
    235  
     295                if(!builder->priv->unset_lang 
     296                                && ( builder->priv->lang >= 0 
     297                                        || (MGD_GET_LANG_ID(mgd) == MGD_GET_DEFAULT_LANG_ID(mgd)))){ 
     298                         
    236299                        g_string_append(sql, " AND "); 
    237300                        g_string_append(sql, builder->priv->schema->table); 
    238                         /* Default behaviour , we get multilang records  
    239                          * with lang 0 and other lang set, thus we have  
    240                          * "full" list of objects , even some of them are  
    241                          * not translated yet.*/  
    242                         if(builder->priv->lang < 0) { 
    243                                 g_string_append_printf(sql, 
    244                                                 "_i.lang IN (%d, %d)", 
    245                                                 midgard_connection_get_lang_id(builder->priv->mgd, NULL),  
    246                                                 midgard_connection_get_lang_id( 
    247                                                         builder->priv->mgd,  
    248                                                         midgard_connection_get_default_lang( 
    249                                                                 builder->priv->mgd)));         
    250                         } else { 
    251                                 /* builder->priv->lang is set with set_lang method, so  
    252                                  * we get only those records with lang being set 
    253                                  * and we ignore all others , even woth lang 0  
    254                                  */ 
    255                                 g_string_append_printf(sql, 
    256                                                 "_i.lang = %d ", 
    257                                                 builder->priv->lang); 
    258                         } 
    259                 } 
    260                 
     301                        g_string_append_printf(sql, 
     302                                        "_i.lang = %d ", 
     303                                        builder->priv->lang > -1 ? builder->priv->lang : MGD_GET_LANG_ID(builder->priv->mgd));                   
     304                }        
    261305        }            
    262306 
     
    305349        } 
    306350 
    307         if (mode < MQB_SELECT_COUNT && builder->priv->limit != G_MAXUINT) { 
    308                 g_string_append_printf(sql, " LIMIT %u", builder->priv->limit); 
    309                 if (builder->priv->offset != 0) { 
    310                         g_string_append_printf( 
    311                                 sql, " OFFSET %u", builder->priv->offset); 
    312                 } 
    313         } 
     351        if (mode < MQB_SELECT_COUNT && builder->priv->limit != G_MAXUINT)  
     352                g_string_append_printf(sql, " LIMIT %u", builder->priv->limit); 
     353 
     354        if (builder->priv->offset != 0)  
     355                g_string_append_printf(sql, " OFFSET %u", builder->priv->offset); 
    314356 
    315357        return g_string_free(sql, FALSE); 
  • trunk/midgard/core/midgard/src/query_builder.c

    r16171 r16439  
    354354                return NULL;  
    355355        } 
    356  
    357         if (builder->priv->schema->use_lang == 1) { 
    358                  
    359                 gchar *guid = NULL; 
    360                 GList *nlist = NULL; 
    361                  
    362                 /* Reverse list only if we have user defined lang  
    363                  * and lang 0 as fallback */ 
    364                 if((midgard_connection_get_lang_id(builder->priv->mgd, NULL) != 0) 
    365                                 && builder->priv->lang == -1) 
    366                         list = g_list_reverse(list); 
    367  
    368                 for(; list ; list = list->next){      
    369                         
    370                         /* Bit of hack, records could be returned with lang DESC */ 
    371                          
    372                         if(select_type == MQB_SELECT_OBJECT) { 
    373                                 g_object_get(G_OBJECT(list->data), "guid", &guid, NULL); 
    374                         } else if (select_type == MQB_SELECT_GUID) { 
    375                                 guid = g_strdup((gchar *)list->data); 
    376                         } 
    377                         /* Changed to find_custom due to bug in GLib docs */ 
    378                         /* g_list_find never returns NULL */ 
    379                         /* We could use g_hash_table as well */ 
    380                         if((tmp_list = g_list_find_custom(tmp_list,  
    381                                                 guid, _compare_ml_guid))) { 
    382                                  
    383                                 g_free((gchar *)tmp_list->data);   
    384                                 tmp_list->data = g_strdup(""); /* FIXME */ 
    385                                  
    386                                 if(select_type == MQB_SELECT_OBJECT) { 
    387                                         g_object_unref(G_OBJECT(list->data)); 
    388                                 } else if (select_type == MQB_SELECT_GUID) { 
    389                                         /* TODO check leak, none for now */ 
    390                                         /* g_free(list->data); */ 
    391                                 } 
    392                                  
    393                         } else { 
    394                                 nlist = g_list_append(nlist, list->data);                           
    395                         }        
    396                         tmp_list = g_list_prepend(tmp_list, (gpointer)guid); 
    397                 }           
    398                  
    399                 /* Free unused guids */ 
    400                 for(; tmp_list ; tmp_list = tmp_list->next){ 
    401                         g_free((gchar *)tmp_list->data); 
    402                 } 
    403                 g_list_free(tmp_list); 
    404                 g_list_free(list); 
    405                 list = nlist; 
    406         }     
    407356         
    408357        if(holder) 
    409358                holder->elements = g_list_length(list); 
    410  
    411         /* Reverse list again so we get initial state */ 
    412         if((midgard_connection_get_lang_id(builder->priv->mgd, NULL) != 0) 
    413                         && builder->priv->lang == -1) 
    414                 list = g_list_reverse(list); 
    415359 
    416360        return list;      
     
    455399guint midgard_query_builder_count(MidgardQueryBuilder *builder) 
    456400{ 
    457         g_assert(builder != NULL); 
    458          
     401        g_assert(builder != NULL); 
    459402        MIDGARD_ERRNO_SET(builder->priv->mgd, MGD_ERR_OK); 
    460         MidgardTypeHolder *holder = g_new(MidgardTypeHolder, 1); 
     403         
    461404        GList *list = 
    462                 midgard_query_builder_execute_or_count(builder, holder, MQB_SELECT_GUID);        
    463  
     405                midgard_query_builder_execute_or_count(builder, NULL, MQB_SELECT_GUID); 
     406         
     407        gchar *rv = (gchar *)list->data; 
     408        guint elements; 
     409         
     410        if(rv == NULL) 
     411                elements = 0; 
     412        else 
     413                elements = atoi((gchar *)list->data); 
     414         
    464415        if(list != NULL){ 
    465416                 
    466                 for( ; list; list = list->next){                 
    467                         g_free((gchar *)list->data);                                      
    468                 }                
     417                for( ; list; list = list->next){ 
     418                        g_free((gchar *)list->data); 
     419                } 
     420                 
    469421                g_list_free(list); 
    470422        } 
    471         return holder->elements; 
     423         
     424        return elements; 
    472425} 
    473426 
     
    776729        /* We get guids only */ 
    777730        if(select_type == MQB_SELECT_GUID) { 
    778                 for (rows = 0; rows < ret_rows; rows++) { 
    779                         ret_fields =  gda_data_model_get_n_columns(model); 
    780                         for (columns = 0; columns < ret_fields; columns++) { 
    781                                  
    782                                 gvalue =  
    783                                         gda_data_model_get_value_at( 
    784                                                         model, columns, rows); 
    785                                 list = g_list_append(list,  
    786                                                 g_value_dup_string((GValue*)gvalue));    
    787                         } 
    788                         g_object_unref(model); 
    789                         return list;             
    790                 } 
     731                 
     732                gvalue = gda_data_model_get_value_at(model, 0, 0); 
     733                list = g_list_append(list, g_value_dup_string((GValue*)gvalue));         
     734                g_object_unref(model); 
     735                return list;             
    791736        } 
    792737