Changeset 16439
- Timestamp:
- 05/22/08 21:43:48 (3 months ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/midgard/core/midgard/src/midgard_core_query_builder.c
r16242 r16439 32 32 #include "midgard_user.h" 33 33 #include "midgard_core_object.h" 34 #include "midgard_object_class.h" 34 35 35 36 MidgardQueryBuilderPrivate *midgard_query_builder_private_new(void) … … 125 126 } 126 127 128 gboolean _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 148 static 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 127 178 gchar *_midgard_core_qb_get_sql( 128 179 MidgardQueryBuilder *builder, guint mode, gchar *select) … … 133 184 /* FIXME, error reporting needed */ 134 185 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; 137 188 } 189 190 guint multilang_fallback = _midgard_core_qb_is_multilingual(builder); 191 MidgardConnection *mgd = builder->priv->mgd; 138 192 139 193 /* SELECT */ … … 147 201 g_hash_table_foreach(builder->priv->tables, _add_table_foreach, &tlist); 148 202 203 GString *tables = g_string_new(""); 204 149 205 guint l = 0; 150 206 GSList *nlist; … … 152 208 153 209 if(l < 1) 154 g_string_append( sql, (gchar *) nlist->data);210 g_string_append(tables, (gchar *) nlist->data); 155 211 else 156 g_string_append_printf( sql,212 g_string_append_printf(tables, 157 213 ", %s", (gchar *) nlist->data); 158 214 l++; … … 161 217 g_slist_free(tlist); 162 218 219 g_string_append(sql, tables->str); 220 163 221 /* WHERE */ 164 222 g_string_append(sql, " WHERE "); 165 223 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); 192 252 193 253 if(builder->priv->groups != NULL) { … … 207 267 /* Join tables from ORDER BY */ 208 268 GSList *olist = NULL; 209 jlist = NULL;269 GSList *jlist = NULL; 210 270 guint i = 0; 211 271 if(builder->priv->orders != NULL) { … … 226 286 227 287 if (builder->priv->schema->use_lang == 1) { 288 228 289 g_string_append(sql, " AND "); 229 290 g_string_append(sql, builder->priv->schema->table); … … 232 293 g_string_append(sql, "_i.sid"); 233 294 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 236 299 g_string_append(sql, " AND "); 237 300 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 } 261 305 } 262 306 … … 305 349 } 306 350 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); 314 356 315 357 return g_string_free(sql, FALSE); trunk/midgard/core/midgard/src/query_builder.c
r16171 r16439 354 354 return NULL; 355 355 } 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 lang363 * 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 }407 356 408 357 if(holder) 409 358 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);415 359 416 360 return list; … … 455 399 guint midgard_query_builder_count(MidgardQueryBuilder *builder) 456 400 { 457 g_assert(builder != NULL); 458 401 g_assert(builder != NULL); 459 402 MIDGARD_ERRNO_SET(builder->priv->mgd, MGD_ERR_OK); 460 MidgardTypeHolder *holder = g_new(MidgardTypeHolder, 1);403 461 404 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 464 415 if(list != NULL){ 465 416 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 469 421 g_list_free(list); 470 422 } 471 return holder->elements; 423 424 return elements; 472 425 } 473 426 … … 776 729 /* We get guids only */ 777 730 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; 791 736 } 792 737
