src/midgard_quota.c

00001 /* 
00002  * Copyright (C) 2005 Piotr Pokora <piotr.pokora@infoglob.pl>
00003  *
00004  * This program is free software; you can redistribute it and/or modify it
00005  * under the terms of the GNU Lesser General Public License as published
00006  * by the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  * 
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  * 
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  */
00018 
00019 #include <stdlib.h>
00020 #include <midgard/midgard_quota.h>
00021 #include <midgard/query.h>
00022 #include <midgard/midgard_error.h>
00023 #include <sys/errno.h>
00024 #include <sys/types.h>
00025 #include <sys/stat.h>
00026 #include "schema.h"
00027 
00028 #define get_varchar_size(str) \
00029         if(str == NULL) \
00030                 size++; \
00031         else \
00032                 size = strlen(str) + 1 + size; \
00033         g_free(str);
00034         
00035 #define get_datetime_size(str) \
00036         size = 8 + size; \
00037         g_free(str);
00038 
00039 gboolean midgard_quota_size_is_reached(MgdObject *object, gint size)
00040 {
00041         GString *query;
00042         gint limit_tmp_size, tmp_size;
00043         GList *list;
00044         midgard *mgd = object->mgd;
00045         char *spacefields = NULL;
00046 
00047         /* First we check old quota */
00048         if (mgd->quota && mgd_sitegroup(mgd) > 0) {
00049                 if ((spacefields = mgd_check_quota(mgd, object->data->query->table)) == 0) {
00050                         MIDGARD_ERRNO_SET(object->mgd, MGD_ERR_QUOTA);
00051                         return TRUE;
00052                 }
00053         }               
00054 
00055         /* Check global quota */
00056         guint sgid;
00057         g_object_get(G_OBJECT(object), "sitegroup", &sgid, NULL);
00058         query = g_string_new("SELECT limit_sg_size, sg_size FROM quota ");
00059         g_string_append_printf(query,
00060                         "WHERE typename='' and sitegroup=%d",
00061                         sgid);
00062 
00063         list = midgard_query_get_single_row(g_string_free(query, FALSE), object);
00064         
00065         /* This means that quota is enabled but quota limits are not set
00066          * return FALSE then*/
00067         if(!list)
00068                 return FALSE;
00069         
00070         limit_tmp_size = atoi(list->data);
00071         g_free(list->data);
00072         list = list->next;
00073         tmp_size = atoi(list->data);
00074         g_free(list->data);
00075         g_list_free(list);
00076 
00077         if(((tmp_size + size) > limit_tmp_size) && limit_tmp_size > 0){
00078                 MIDGARD_ERRNO_SET(object->mgd, MGD_ERR_QUOTA);
00079                 return TRUE;
00080         }
00081         
00082         /* Check quota for type size */
00083         query = g_string_new("SELECT limit_type_size, type_size FROM quota ");
00084         g_string_append_printf(query,
00085                         "WHERE typename='%s' and sitegroup=%d",
00086                         G_OBJECT_TYPE_NAME(object), 
00087                         midgard_sitegroup_get_id(object->mgd));
00088 
00089         list = midgard_query_get_single_row(g_string_free(query, FALSE), object);
00090 
00091         /* This means that quota is enabled and quota limits are not set
00092          * return FALSE then*/
00093         if(!list)
00094                 return FALSE;
00095         
00096         limit_tmp_size = atoi(list->data);
00097         g_free(list->data);
00098         list = list->next;
00099         tmp_size = atoi(list->data);
00100         g_free(list->data);
00101         
00102         g_list_free(list);
00103         
00104         if(((tmp_size + size) > limit_tmp_size) && limit_tmp_size > 0){
00105                 MIDGARD_ERRNO_SET(object->mgd, MGD_ERR_QUOTA);
00106                 return TRUE;
00107         }
00108 
00109         return FALSE;
00110 }
00111 
00112 
00113 /*
00114  * Returns object's disk usage size 
00115  */ 
00116 guint midgard_quota_get_object_size(MgdObject *object){
00117 
00118         g_assert(object != NULL);
00119 
00120         MidgardObjectClass *klass = MIDGARD_OBJECT_GET_CLASS(object);
00121         GString *select = g_string_new("SELECT metadata_size");
00122         g_string_append_printf(select, 
00123                         " FROM %s WHERE %s=",
00124                         midgard_object_class_get_table(klass),                          
00125                         midgard_object_class_get_primary_field(klass));
00126                         
00127         GParamSpec *prop = 
00128                 g_object_class_find_property(
00129                                 G_OBJECT_GET_CLASS(G_OBJECT(object)),
00130                                 midgard_object_class_get_primary_property(klass));
00131 
00132         if(prop == NULL)
00133                 g_error("Primary property not found for %s", G_OBJECT_TYPE_NAME(object));
00134 
00135         GValue pval = {0, };
00136         g_value_init(&pval, prop->value_type);
00137         g_object_get_property(G_OBJECT(object),
00138                         midgard_object_class_get_primary_property(klass),
00139                         &pval);
00140 
00141         if(prop->value_type == G_TYPE_UINT) {
00142                 g_string_append_printf(select, 
00143                                 "%d",
00144                                 g_value_get_uint(&pval));                               
00145         } else {
00146                 g_string_append_printf(select,
00147                                 "'%s'",
00148                                 g_value_get_string(&pval));
00149         }
00150         g_value_unset(&pval);
00151         
00152         /* there is no need to get SG0 size */
00153         guint sgid;
00154         g_object_get(G_OBJECT(object), "sitegroup", &sgid, NULL);
00155         g_string_append_printf(select, 
00156                         " AND sitegroup=%d",
00157                         sgid);
00158         
00159         gchar *query = g_string_free(select, FALSE);
00160         GList *list = midgard_query_get_single_row(query, object);
00161         
00162         if(list == NULL)
00163                 return 0;
00164 
00165         guint size = atoi(list->data);
00166 
00167         g_free(list->data);
00168         g_list_free(list);
00169 
00170         return size;
00171 }
00172 
00173 /*
00174  * Updates object's storage setting object's size
00175  * WARNING, this is MySQL optimized!    
00176  */
00177 gboolean midgard_quota_update(MgdObject *object)
00178 {
00179         g_assert(object != NULL);
00180         g_assert(object->mgd != NULL);
00181 
00182 
00183         guint size = 0;
00184         guint32 qsize = 0;
00185         const gchar *typename = G_OBJECT_TYPE_NAME(object);
00186         GValue pval = {0, };
00187 
00188         g_object_get(G_OBJECT(object->metadata), "size", &size, NULL);
00189                 
00190         /* nothing to update, this should never happen */
00191         if(size == 0) return TRUE;
00192 
00193         /* Get difference */
00194         /* difference is important to allow multiple updates without wrong size 
00195          * diff_size may be less then , equal or greater than 0 */
00196         qsize = midgard_quota_get_object_size(object);
00197         gint diff_size = size - qsize;  
00198 
00199         if(midgard_quota_size_is_reached(object, diff_size)){
00200                 MIDGARD_ERRNO_SET(object->mgd, MGD_ERR_QUOTA);
00201                 return FALSE;
00202         }
00203 
00204         guint32 opsize;
00205         opsize = diff_size + qsize;
00206         
00207         /* diff size is 0 , so no need update record without changing its value */
00208         if(diff_size == 0) 
00209                 return TRUE;
00210 
00211         g_object_set(G_OBJECT(object->metadata), "size", opsize, NULL);
00212         MidgardObjectClass *klass = MIDGARD_OBJECT_GET_CLASS(object);   
00213         
00214         GString *query = g_string_new("UPDATE ");
00215         g_string_append_printf(query, 
00216                         "%s SET metadata_size=metadata_size+%d "
00217                         "WHERE %s=",
00218                         midgard_object_class_get_table(klass),
00219                         diff_size,
00220                         midgard_object_class_get_primary_field(klass));
00221         
00222         GParamSpec *prop = g_object_class_find_property(
00223                         G_OBJECT_GET_CLASS(G_OBJECT(object)),
00224                         midgard_object_class_get_primary_property(klass));
00225         
00226         g_value_init(&pval, prop->value_type);
00227         g_object_get_property(G_OBJECT(object),
00228                         midgard_object_class_get_primary_property(klass),
00229                         &pval);
00230         
00231         if(prop->value_type == G_TYPE_UINT) {
00232                 g_string_append_printf(query,
00233                                 "%d",
00234                                 g_value_get_uint(&pval));
00235         } else {
00236                 g_string_append_printf(query,
00237                                 "'%s'",
00238                                 g_value_get_string(&pval));
00239         }
00240         g_value_unset(&pval);   
00241         midgard_query_execute(object->mgd, g_string_free(query, FALSE), NULL);
00242 
00243         /* Update type size */
00244         GString *quota_query;
00245         guint sgid;
00246         g_object_get(G_OBJECT(object), "sitegroup", &sgid, NULL);
00247         quota_query = g_string_new("UPDATE quota ");
00248         g_string_append_printf(quota_query, 
00249                         "SET type_size=type_size+%d "
00250                         "WHERE typename='%s' AND sitegroup=%d",
00251                         diff_size,
00252                         typename,
00253                         sgid);
00254         midgard_query_execute(object->mgd, g_string_free(quota_query, FALSE), NULL);
00255 
00256         /* Update global sitegroup size */
00257         quota_query = g_string_new("UPDATE quota ");
00258         g_string_append_printf(quota_query,
00259                         "SET sg_size=sg_size+%d "
00260                         "WHERE typename='' AND sitegroup=%d",
00261                         diff_size,
00262                         sgid);
00263         midgard_query_execute(object->mgd, g_string_free(quota_query, FALSE), NULL);
00264 
00265 
00266         return TRUE;
00267 }
00268 
00269 gboolean midgard_quota_create(MgdObject *object)
00270 {
00271         g_assert(object != NULL);
00272 
00273         GString *query;
00274         gint tmp_type_limit, tmp_limit;
00275         GList *list;
00276         guint object_sitegroup;
00277 
00278         g_object_get(G_OBJECT(object), "sitegroup", &object_sitegroup, NULL);
00279         
00280         /* Check quota for global records limit*/
00281         query = g_string_new("SELECT limit_sg_records, sg_records FROM quota ");
00282         g_string_append_printf(query,
00283                         "WHERE typename='' and sitegroup=%d",
00284                         object_sitegroup);
00285 
00286         list = midgard_query_get_single_row(g_string_free(query, FALSE), object);
00287         
00288         /* This means that quota is enable but quota limits are not set 
00289          * return TRUE then */
00290         if(!list)
00291                 return TRUE;
00292         
00293         
00294         tmp_type_limit = atoi(list->data);
00295         g_free(list->data);
00296         list = list->next;
00297         tmp_limit = atoi(list->data);
00298         g_free(list->data);
00299         
00300         g_list_free(list);
00301         
00302         if(((tmp_limit + 1) > tmp_type_limit) && tmp_type_limit > 0){
00303                 MIDGARD_ERRNO_SET(object->mgd, MGD_ERR_QUOTA);
00304                 return FALSE;
00305         }
00306 
00307         /* Check quota for type's records limit*/
00308         query = g_string_new("SELECT limit_type_records, type_records FROM quota ");
00309         g_string_append_printf(query,
00310                         "WHERE typename='%s' and sitegroup=%d",
00311                         G_OBJECT_TYPE_NAME(object), 
00312                         object_sitegroup);
00313 
00314         list = midgard_query_get_single_row(g_string_free(query, FALSE) , object);
00315         
00316         /* This means that quota is enabled but quota limits are not set 
00317          * return TRUE then */
00318         if(!list)
00319                 return TRUE;
00320         
00321         tmp_type_limit = atoi(list->data);
00322         g_free(list->data);
00323         list = list->next;
00324         tmp_limit = atoi(list->data);
00325         g_free(list->data);
00326         
00327         g_list_free(list);
00328         
00329         if(((tmp_limit + 1) > tmp_type_limit) && tmp_type_limit > 0){
00330                 MIDGARD_ERRNO_SET(object->mgd, MGD_ERR_QUOTA);
00331                 return FALSE;
00332         }
00333 
00334         guint32 size;
00335         g_object_get(G_OBJECT(object->metadata), "size", &size, NULL);
00336         if(midgard_quota_size_is_reached(object, size)){
00337                 MIDGARD_ERRNO_SET(object->mgd, MGD_ERR_QUOTA);
00338                 return FALSE;
00339         }
00340 
00341         /* Update type's records */
00342         query = g_string_new("UPDATE quota ");
00343         g_string_append_printf(query,
00344                         "SET type_records=type_records+1"
00345                         " WHERE typename='%s' AND sitegroup=%d",
00346                         G_OBJECT_TYPE_NAME(object), 
00347                         object_sitegroup);
00348 
00349         midgard_query_execute(object->mgd, g_string_free(query, FALSE), NULL);
00350 
00351         /* Update global sitegroup records */
00352         query = g_string_new("UPDATE quota ");
00353         g_string_append_printf(query,
00354                         "SET sg_records=sg_records+1"
00355                         " WHERE typename='' AND sitegroup=%d",
00356                         object_sitegroup);
00357 
00358         midgard_query_execute(object->mgd, g_string_free(query, FALSE), NULL);
00359 
00360         return TRUE;
00361 }
00362 
00363 guint midgard_object_get_size(MgdObject *object)
00364 {
00365         g_assert(object != NULL);
00366         g_assert(object->mgd != NULL);
00367 
00368         /* This is overloaded function 
00369          * Should be absolutely changed when midgard type system is done 
00370          */
00371         guint propn, size = 0;
00372         const gchar *schematype, *blobdir, *strprop;
00373         const gchar *typename = G_OBJECT_TYPE_NAME(object);
00374         gchar *meta_strprop = NULL, *blobpath, *location;
00375         guint meta_intprop, i;
00376         GValue pval = {0, };
00377         struct stat statbuf; /* GLib 2.6 is not available everywhere, g_stat not used */
00378 
00379         MidgardObjectClass *klass = MIDGARD_OBJECT_GET_CLASS(object);
00380         
00381         if(g_ascii_strcasecmp(typename, "midgard_attachment") == 0){
00382                 
00383                 blobdir = mgd_get_blobdir(object->mgd);
00384 
00385                 if (!blobdir || (*blobdir != '/')
00386                                 || (stat(blobdir, &statbuf) != 0)
00387                                 || !S_ISDIR(statbuf.st_mode)) {
00388                 g_error("Invalid blobdir or blobdir is not set");
00389                 }
00390                                 
00391                 g_object_get(G_OBJECT(object), "location", &location, NULL);
00392         
00393                 /* I "think" it's update method now. It poor solution 
00394                  * till there's no real attachment support in core */
00395                 if(strlen(location) > 1) {
00396 
00397                         blobpath = g_strconcat(
00398                                         blobdir,
00399                                         "/",
00400                                         location,
00401                                         NULL);
00402                         
00403                         if((stat(blobpath, &statbuf) == 0) || (!S_ISDIR(statbuf.st_mode)))
00404                                 size = statbuf.st_size;
00405                         
00406                         g_free(blobpath);
00407                 }
00408         }
00409                 
00410         GParamSpec **props = g_object_class_list_properties(
00411                         G_OBJECT_GET_CLASS(G_OBJECT(object)), &propn);
00412         
00413         if(props == NULL){
00414                 g_warning("Object size: Object %s has no properties",
00415                                 G_OBJECT_TYPE_NAME(object));
00416                 MIDGARD_ERRNO_SET(object->mgd, MGD_ERR_INVALID_OBJECT);
00417                 return FALSE;
00418         }
00419         
00420         for(i = 0; i < propn; i++){
00421 
00422                 /* midgard_metadata object */
00423                 if(g_ascii_strcasecmp(props[i]->name, "metadata") == 0){
00424 
00425                         /* creator */
00426                         g_object_get(G_OBJECT(object->metadata), "creator", &meta_strprop, NULL);
00427                         get_varchar_size(meta_strprop);
00428                         /* created */
00429                         g_object_get(G_OBJECT(object->metadata), "created", &meta_strprop, NULL);
00430                         get_datetime_size(meta_strprop);
00431                         /* revisor */
00432                         g_object_get(G_OBJECT(object->metadata), "revisor", &meta_strprop, NULL);
00433                         get_varchar_size(meta_strprop);
00434                         /* revised */
00435                         g_object_get(G_OBJECT(object->metadata), "revised", &meta_strprop, NULL);
00436                         get_datetime_size(meta_strprop);
00437                         /* revision */
00438                         g_object_get(G_OBJECT(object->metadata), "revision", &meta_intprop, NULL);
00439                         size = 4 + size;
00440                         /* locker */
00441                         g_object_get(G_OBJECT(object->metadata), "locker", &meta_strprop, NULL);
00442                         get_varchar_size(meta_strprop);
00443                         /* locked */
00444                         g_object_get(G_OBJECT(object->metadata), "locked", &meta_strprop, NULL);
00445                         get_datetime_size(meta_strprop);
00446                         /* approver */
00447                         g_object_get(G_OBJECT(object->metadata), "approved", &meta_strprop, NULL);
00448                         get_varchar_size(meta_strprop);
00449                         /* approved */
00450                         g_object_get(G_OBJECT(object->metadata), "approved", &meta_strprop, NULL);
00451                         get_datetime_size(meta_strprop);
00452                         /* authors */
00453                         g_object_get(G_OBJECT(object->metadata), "authors", &meta_strprop, NULL);
00454                         if(meta_strprop == NULL)
00455                                 meta_strprop = g_strdup("");
00456                         size = strlen(meta_strprop) + 4 + size;
00457                         g_free(meta_strprop);
00458                         /* owner */
00459                         g_object_get(G_OBJECT(object->metadata), "owner", &meta_strprop, NULL);
00460                         get_varchar_size(meta_strprop);
00461                         /* schedule-start */
00462                         g_object_get(G_OBJECT(object->metadata), "schedulestart", &meta_strprop, NULL);
00463                         get_datetime_size(meta_strprop);
00464                         /* schedule-end */
00465                         g_object_get(G_OBJECT(object->metadata), "scheduleend", &meta_strprop, NULL);
00466                         get_datetime_size(meta_strprop);
00467                         /* hidden */
00468                         g_object_get(G_OBJECT(object->metadata), "hidden", &meta_intprop, NULL);
00469                         size = size;
00470                         /* nav-noentry */
00471                         g_object_get(G_OBJECT(object->metadata), "navnoentry", &meta_intprop, NULL);
00472                         size =  size;   
00473 
00474                 } else {        
00475 
00476                         /* Follow all custom properties */
00477                         g_value_init(&pval, props[i]->value_type);
00478                         
00479                         switch (props[i]->value_type){
00480 
00481                                 case G_TYPE_FLOAT:
00482                                 case G_TYPE_UINT:
00483                                         size =  4 + size;
00484                                         break;
00485 
00486                                 case G_TYPE_BOOLEAN:
00487                                         size = size; /* Piotras: I didn't find bool size */
00488                                         break;
00489                                         
00490                                 case G_TYPE_STRING:
00491 
00492                                         g_object_get_property(G_OBJECT(object), props[i]->name, &pval);
00493                                         
00494                                         /* FIXME , move to data->gtype if midgard fundamental 
00495                                          * types can not do this work */
00496                                         MgdSchemaPropertyAttr *prop_attr = 
00497                                                 g_hash_table_lookup(klass->data->prophash,
00498                                                                 props[i]->name);
00499                                         schematype = NULL;
00500                                         if(prop_attr != NULL)
00501                                                 schematype = prop_attr->type; 
00502                                                                                         
00503                                         /* default one is string (varchar) */
00504                                         if((schematype == NULL)){
00505 
00506                                                 strprop = g_value_get_string(&pval);
00507                                                 if(strprop == NULL)
00508                                                         size++;
00509                                                 else
00510                                                         size = (strlen(strprop)) + 1 + size;
00511 
00512                                                 schematype = "";                                        
00513                                         }
00514                                                 
00515                                         if(g_ascii_strcasecmp(schematype, "longtext") == 0){
00516                                                 strprop = g_value_get_string(&pval);
00517                                                 if(strprop == NULL)
00518                                                         strprop = "";
00519                                                 size = (strlen(strprop)) + 4 + size;
00520                                         }
00521 
00522                                         if(g_ascii_strcasecmp(schematype, "text") == 0){
00523                                                 strprop = g_value_get_string(&pval);
00524                                                 if(strprop == NULL)
00525                                                         strprop = "";
00526                                                 size = (strlen(strprop)) + 1 + size;
00527                                         }
00528                                         
00529                                         if(g_ascii_strcasecmp(schematype, "string") == 0){
00530                                                 strprop = g_value_get_string(&pval);                                                                       if(strprop == NULL)
00531                                                         strprop = "";
00532                                                 size = (strlen(strprop)) + 1 + size;
00533                                         }
00534                                                                                 
00535                                         
00536 
00537                                         if(g_ascii_strcasecmp(schematype, "date") == 0)
00538                                                 size =  3 + size;
00539                                         
00540                                         if(g_ascii_strcasecmp(schematype, "datetime") == 0)
00541                                                 size =  8 + size;
00542                                         
00543                                         break;
00544 
00545 
00546                         }
00547                         g_value_unset(&pval);
00548                 }       
00549         }
00550 
00551         g_free(props);
00552 
00553         return size;
00554 }
00555 
00556 void midgard_quota_remove(MgdObject *object, guint size){
00557 
00558         g_assert(object != NULL);
00559 
00560         GString *query;
00561         const gchar *typename = G_OBJECT_TYPE_NAME(object);
00562         
00563         /* Update type's records */
00564         query = g_string_new("UPDATE quota ");
00565         g_string_append_printf(query,
00566                         "SET type_records=type_records-1"
00567                         " WHERE typename='%s' AND sitegroup=%d AND type_records>0",
00568                         typename,
00569                         midgard_sitegroup_get_id(object->mgd));
00570         midgard_query_execute(object->mgd, g_string_free(query, FALSE), NULL);
00571 
00572         /* Update global sitegroup records */
00573         query = g_string_new("UPDATE quota ");
00574         g_string_append_printf(query,
00575                         "SET sg_records=sg_records-1"
00576                         " WHERE typename='' AND sitegroup=%d AND sg_records>0",
00577                         midgard_sitegroup_get_id(object->mgd));
00578         
00579         midgard_query_execute(object->mgd, g_string_free(query, FALSE), NULL);
00580 
00581         query = g_string_new("UPDATE quota ");
00582         g_string_append_printf(query,
00583                         "SET type_size=type_size-%d "
00584                         "WHERE typename='%s' AND sitegroup=%d AND type_size>0",
00585                         size,
00586                         typename,
00587                         midgard_sitegroup_get_id(object->mgd));
00588         midgard_query_execute(object->mgd, g_string_free(query, FALSE), NULL);
00589 
00590         /* Update global sitegroup size */
00591         query = g_string_new("UPDATE quota ");
00592         g_string_append_printf(query,
00593                         "SET sg_size=sg_size-%d "
00594                         "WHERE typename='' AND sitegroup=%d AND sg_size>0",
00595                         size,
00596                         midgard_sitegroup_get_id(object->mgd));
00597         midgard_query_execute(object->mgd, g_string_free(query, FALSE), NULL);
00598 
00599 }
00600 
00601 typedef struct{
00602         guint sg;
00603         guint32 size;
00604         midgard *mgd;
00605 }_qts;
00606 
00607 
00608 static void _get_type_global_size(gpointer k, gpointer v, gpointer ud)
00609 {
00610         const gchar *typename = (gchar *)k;
00611         _qts *qts = (_qts *)ud;
00612 
00613         MgdObject *object = midgard_object_new(qts->mgd, typename, NULL);
00614         MidgardObjectClass *klass = MIDGARD_OBJECT_GET_CLASS(object);
00615 
00616         guint propn, i;
00617         GParamSpec **props = g_object_class_list_properties(
00618                         G_OBJECT_GET_CLASS(G_OBJECT(object)), &propn);
00619 
00620         if(props == NULL) return;
00621         
00622         GString *tmp = g_string_new("");
00623         const gchar *nick;
00624         
00625         for(i = 0; i < propn; i++){
00626                 
00627                 nick = g_param_spec_get_nick(props[i]);
00628                 if(nick && strlen(nick) > 0){
00629 
00630                         g_string_append_printf(tmp,
00631                                         "%s,",
00632                                         nick);
00633                 }
00634         }
00635 
00636         g_free(props);
00637         
00638         gchar *concat = g_string_free(tmp, FALSE);
00639         guint conlen = strlen(concat);
00640 
00641         if(conlen < 1){
00642                 g_free(concat);
00643                 return;
00644         }
00645         
00646         concat[conlen-1] = '\0';
00647         
00648         tmp = g_string_new("SELECT SUM(LENGTH(CONCAT(");
00649         g_string_append_printf(tmp,
00650                         "%s))) FROM %s ",
00651                         concat,
00652                         midgard_object_class_get_tables(klass));
00653         g_string_append(tmp, " WHERE ");
00654         g_string_append_printf(tmp,
00655                         "%s.sitegroup=%d",
00656                         midgard_object_class_get_table(klass),
00657                         qts->sg);
00658 
00659         if(midgard_object_class_is_multilang(klass)){
00660 
00661                 g_string_append_printf(tmp,
00662                                 " AND %s.id=%s_i.sid ",
00663                                 midgard_object_class_get_table(klass),
00664                                 midgard_object_class_get_table(klass));
00665         }
00666         
00667         g_free(concat);
00668         midgard_res *res;
00669         gchar *query = g_string_free(tmp, FALSE);
00670         res = mgd_query(qts->mgd, query);
00671         if(res && mgd_fetch(res)){
00672                 qts->size = qts->size + (guint)mgd_sql2id(res,0);
00673                 if(res) mgd_release(res);
00674         }       
00675         g_free(query);
00676 
00677         if(g_ascii_strcasecmp(typename, "midgard_attachment") == 0){
00678 
00679                 struct stat buf;
00680                 gchar *path;
00681                 const gchar *location;
00682                 
00683                 res = mgd_query(qts->mgd, 
00684                                 "SELECT location FROM blobs WHERE sitegroup = $d",
00685                                 qts->sg);
00686                 if (res) {
00687                         while (mgd_fetch(res)) {
00688                                 location = mgd_colvalue(res,0);
00689                                 if(location){
00690                                         path = g_strconcat(
00691                                                         mgd_get_blobdir(qts->mgd),
00692                                                         "/",
00693                                                         location, NULL);
00694                                         stat(path, &buf);
00695                                         qts->size = qts->size + buf.st_size;
00696                                         g_free(path);
00697                                 }
00698                         }
00699                         mgd_release(res);
00700                 }
00701         }
00702         g_object_unref(object);
00703 }
00704 
00705 
00706 guint32 midgard_quota_get_sitegroup_size(midgard *mgd, guint sg)
00707 {
00708 
00709         g_assert(mgd != NULL);
00710         if(sg == 0) return 0;
00711 
00712         if(!mgd_isroot(mgd)) 
00713                 return 0;
00714         
00715         guint32 size = 0;
00716         
00717         _qts *qts = g_new(_qts,1);
00718         qts->size = 0;
00719         qts->sg = sg;
00720         qts->mgd = mgd;
00721 
00722         g_hash_table_foreach(mgd->schema->types, _get_type_global_size, qts);
00723 
00724         size = qts->size;
00725         g_free(qts);
00726         return size;
00727 }
00728 
00729 

Generated on Thu Feb 22 06:15:18 2007 for midgard-core by  doxygen 1.4.6