Changeset 625


Ignore:
Timestamp:
Nov 30, 2004, 9:26:44 PM (19 years ago)
Author:
plg
Message:
  • update_global_rank new function : far more intelligent update. Take into account the possiblity to have category tree not in category id ascending order
  • update global_rank when moving categories among the same parent
  • new function mass_updates : depending on MySQL version, create a temporary table, make one big insert and one big update by joining 2 tables (4.0.4 or above) or make 1 update per primary key
  • function update_category improved for representative_picture_id check : only one useful query (equivalent to NOT EXISTS) instead of N (N = number of categories) queries
Location:
trunk/admin
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/admin/cat_list.php

    r622 r625  
    209209    array_shift($categories);
    210210  }
     211  update_global_rank($_GET['parent_id']);
    211212}
    212213else if (isset($_GET['down']) and is_numeric($_GET['down']))
     
    268269    array_pop($categories);
    269270  }
     271  update_global_rank($_GET['parent_id']);
    270272}
    271273reset($categories);
  • trunk/admin/include/functions.php

    r614 r625  
    467467;';
    468468  $result = pwg_query( $query );
     469  $datas = array();
    469470  while ( $row = mysql_fetch_array( $result ) )
    470471  {
    471472    array_push($cat_ids, $row['category_id']);
     473    array_push($datas, array('id' => $row['category_id'],
     474                             'date_last' => $row['date_last'],
     475                             'count' => $row['count']));
     476  }
     477  $fields = array('primary' => array('id'),
     478                  'update'  => array('date_last', 'count'));
     479  mass_updates(CATEGORIES_TABLE, $fields, $datas);
     480
     481  if (count($cat_ids) > 0)
     482  {
     483    // find all categories where the setted representative is not possible
    472484    $query = '
    473 UPDATE '.CATEGORIES_TABLE.'
    474   SET date_last = \''.$row['date_last'].'\'
    475     , nb_images = '.$row['count'].'
    476   WHERE id = '.$row['category_id'].'
    477 ;';
    478     pwg_query($query);
    479   }
    480 
    481   if (count($cat_ids) > 0)
    482   {
    483     $query = '
    484 SELECT id, representative_picture_id
    485   FROM '.CATEGORIES_TABLE.'
     485SELECT id
     486  FROM '.CATEGORIES_TABLE.' LEFT JOIN '.IMAGE_CATEGORY_TABLE.'
     487    ON id = category_id AND representative_picture_id = image_id
    486488  WHERE representative_picture_id IS NOT NULL
    487489    AND id IN ('.implode(',', $cat_ids).')
     490    AND category_id IS NULL
    488491;';
    489492    $result = pwg_query($query);
    490493    while ($row = mysql_fetch_array($result))
    491494    {
     495      // set a new representative element for this category
    492496      $query = '
    493 SELECT image_id
    494   FROM '.IMAGE_CATEGORY_TABLE.'
    495   WHERE category_id = '.$row['id'].'
    496     AND image_id = '.$row['representative_picture_id'].'
    497 ;';
    498       $sub_result = pwg_query($query);
    499       if (mysql_num_rows($sub_result) == 0)
    500       {
    501         // set a new representative element for this category
    502         $query = '
    503497SELECT image_id
    504498  FROM '.IMAGE_CATEGORY_TABLE.'
     
    507501  LIMIT 0,1
    508502;';
    509         $sub_sub_result = pwg_query($query);
    510         if (mysql_num_rows($sub_sub_result) > 0)
    511         {
    512           list($representative) = mysql_fetch_array(pwg_query($query));
    513           $query = '
     503      $sub_result = pwg_query($query);
     504      if (mysql_num_rows($sub_result) > 0)
     505      {
     506        list($representative) = mysql_fetch_array($sub_result);
     507        $query = '
    514508UPDATE '.CATEGORIES_TABLE.'
    515509  SET representative_picture_id = '.$representative.'
    516510  WHERE id = '.$row['id'].'
    517511;';
    518           pwg_query($query);
    519         }
    520         else
    521         {
    522           $query = '
     512        pwg_query($query);
     513      }
     514      else
     515      {
     516        $query = '
    523517UPDATE '.CATEGORIES_TABLE.'
    524518  SET representative_picture_id = NULL
    525519  WHERE id = '.$row['id'].'
    526520;';
    527           pwg_query($query);
    528         }
     521        pwg_query($query);
    529522      }
    530523    }
     
    791784 *
    792785 * @param string table_name
    793  * @param array dbields
     786 * @param array dbfields
    794787 * @param array inserts
    795788 * @return void
    796789 */
    797 function mass_inserts($table_name, $dbfields, $inserts)
     790function mass_inserts($table_name, $dbfields, $datas)
    798791{
    799792  // inserts all found categories
     
    802795  ('.implode(',', $dbfields).')
    803796   VALUES';
    804   foreach ($inserts as $insert_id => $insert)
     797  foreach ($datas as $insert_id => $insert)
    805798  {
    806799    $query.= '
     
    833826  pwg_query($query);
    834827}
     828
     829/**
     830 * updates multiple lines in a table
     831 *
     832 * @param string table_name
     833 * @param array dbfields
     834 * @param array datas
     835 * @return void
     836 */
     837function mass_updates($tablename, $dbfields, $datas)
     838{
     839  // depending on the MySQL version, we use the multi table update or N
     840  // update queries
     841  $query = 'SELECT VERSION() AS version;';
     842  $row = mysql_fetch_array(pwg_query($query));
     843  if (version_compare($row['version'],'4.0.4') < 0)
     844  {
     845    // MySQL is prior to version 4.0.4, multi table update feature is not
     846    // available
     847    echo 'MySQL is prior to version 4.0.4, multi table update feature is not available<br />';
     848    foreach ($datas as $data)
     849    {
     850      $query = '
     851UPDATE '.$tablename.'
     852  SET ';
     853      foreach ($dbfields['update'] as $num => $key)
     854      {
     855        if ($num >= 1)
     856        {
     857          $query.= ",\n      ";
     858        }
     859        $query.= $key.' = ';
     860        if (isset($data[$key]))
     861        {
     862          $query.= '\''.$data[$key].'\'';
     863        }
     864        else
     865        {
     866          $query.= 'NULL';
     867        }
     868      }
     869      $query.= '
     870  WHERE ';
     871      foreach ($dbfields['primary'] as $num => $key)
     872      {
     873        if ($num > 1)
     874        {
     875          $query.= ' AND ';
     876        }
     877        $query.= $key.' = \''.$data[$key].'\'';
     878      }
     879      $query.= '
     880;';
     881      pwg_query($query);
     882    }
     883  }
     884  else
     885  {
     886    // creation of the temporary table
     887    $query = '
     888DESCRIBE '.$tablename.'
     889;';
     890    $result = pwg_query($query);
     891    $columns = array();
     892    $all_fields = array_merge($dbfields['primary'], $dbfields['update']);
     893    while ($row = mysql_fetch_array($result))
     894    {
     895      if (in_array($row['Field'], $all_fields))
     896      {
     897        $column = $row['Field'];
     898        $column.= ' '.$row['Type'];
     899        if (!isset($row['Null']) or $row['Null'] == '')
     900        {
     901          $column.= ' NOT NULL';
     902        }
     903        if (isset($row['Default']))
     904        {
     905          $column.= " default '".$row['Default']."'";
     906        }
     907        array_push($columns, $column);
     908      }
     909    }
     910    $query = '
     911CREATE TEMPORARY TABLE '.$tablename.'_temporary
     912(
     913'.implode(",\n", $columns).',
     914PRIMARY KEY (id)
     915)
     916;';
     917    pwg_query($query);
     918    mass_inserts($tablename, $all_fields, $datas);
     919    // update of images table by joining with temporary table
     920    $query = '
     921UPDATE '.$tablename.' AS t1, '.$tablename.'_temporary AS t2
     922  SET '.implode("\n    , ",
     923                array_map(
     924                  create_function('$s', 'return "t1.$s = t2.$s";')
     925                  , $dbfields['update'])).'
     926  WHERE '.implode("\n    AND ",
     927                array_map(
     928                  create_function('$s', 'return "t1.$s = t2.$s";')
     929                  , $dbfields['primary'])).'
     930;';
     931    pwg_query($query);
     932    $query = '
     933DROP TABLE '.$tablename.'_temporary
     934;';
     935    pwg_query($query);
     936  }
     937}
     938
     939/**
     940 * updates the global_rank of categories under the given id_uppercat
     941 *
     942 * @param int id_uppercat
     943 * @return void
     944 */
     945function update_global_rank($id_uppercat = 'all')
     946{
     947  $query = '
     948SELECT id,rank
     949  FROM '.CATEGORIES_TABLE.'
     950;';
     951  $result = pwg_query($query);
     952  $ranks_array = array();
     953  while ($row = mysql_fetch_array($result))
     954  {
     955    $ranks_array[$row['id']] = $row['rank'];
     956  }
     957
     958  // which categories to update ?
     959  $uppercats_array = array();
     960
     961  $query = '
     962SELECT id,uppercats
     963  FROM '.CATEGORIES_TABLE;
     964  if (is_numeric($id_uppercat))
     965  {
     966    $query.= '
     967  WHERE uppercats REGEXP \'(^|,)'.$id_uppercat.'(,|$)\'
     968    AND id != '.$id_uppercat.'
     969';
     970  }
     971  $query.= '
     972;';
     973  $result = pwg_query($query);
     974  while ($row = mysql_fetch_array($result))
     975  {
     976    $uppercats_array[$row['id']] =  $row['uppercats'];
     977  }
     978 
     979  $datas = array();
     980  foreach ($uppercats_array as $id => $uppercats)
     981  {
     982    $data = array();
     983    $data['id'] = $id;
     984    $global_rank = preg_replace('/(\d+)/e',
     985                                "\$ranks_array['$1']",
     986                                str_replace(',', '.', $uppercats));
     987    $data['global_rank'] = $global_rank;
     988    array_push($datas, $data);
     989  }
     990
     991  $fields = array('primary' => array('id'), 'update' => array('global_rank'));
     992  mass_updates(CATEGORIES_TABLE, $fields, $datas);
     993}
    835994?>
  • trunk/admin/include/functions_metadata.php

    r624 r625  
    6969  }
    7070
    71   $inserts = array();
     71  $datas = array();
    7272
    7373  foreach ($files as $id => $file)
    7474  {
    75     $insert = array();
    76     $insert['id'] = $id;
    77     $insert['filesize'] = floor(filesize($file)/1024);
     75    $data = array();
     76    $data['id'] = $id;
     77    $data['filesize'] = floor(filesize($file)/1024);
    7878 
    7979    if ($image_size = @getimagesize($file))
    8080    {
    81       $insert['width'] = $image_size[0];
    82       $insert['height'] = $image_size[1];
     81      $data['width'] = $image_size[0];
     82      $data['height'] = $image_size[1];
    8383    }
    8484 
     
    8989        if (isset($exif['DateTime']))
    9090        {
    91           preg_match('/^(\d{4}).(\d{2}).(\d{2})/'
    92                      ,$exif['DateTime']
    93                      ,$matches);
    94           $insert['date_creation'] =
    95             "'".$matches[1].'-'.$matches[2].'-'.$matches[3]."'";
     91          preg_match('/^(\d{4}).(\d{2}).(\d{2})/',$exif['DateTime'],$matches);
     92          $data['date_creation'] = $matches[1].'-'.$matches[2].'-'.$matches[3];
    9693        }
    9794      }
     
    105102        foreach (array_keys($iptc) as $key)
    106103        {
    107           $insert[$key] = "'".addslashes($iptc[$key])."'";
     104          $data[$key] = "'".addslashes($iptc[$key])."'";
    108105        }
    109106      }
    110107    }
    111108
    112     $insert['date_metadata_update'] = "'".CURRENT_DATE."'";
    113 
    114     array_push($inserts, $insert);
    115   }
    116  
    117   if (count($inserts) > 0)
    118   {
    119     $dbfields = array(
    120       'id','filesize','width','height','name','author','comment'
    121       ,'date_creation','keywords','date_metadata_update'
    122       );
    123 
    124     // depending on the MySQL version, we use the multi table update or N
    125     // update queries
    126     $query = 'SELECT VERSION() AS version;';
    127     $row = mysql_fetch_array(pwg_query($query));
    128     if (version_compare($row['version'],'4.0.4') < 0)
    129     {
    130       // MySQL is prior to version 4.0.4, multi table update feature is not
    131       // available
    132       echo 'MySQL is prior to version 4.0.4, multi table update feature is not available<br />';
    133       foreach ($inserts as $insert)
    134       {
    135         $query = '
    136 UPDATE '.IMAGES_TABLE.'
    137   SET ';
    138         foreach (array_diff(array_keys($insert),array('id')) as $num => $key)
    139         {
    140           if ($num > 1)
    141           {
    142             $query.= ', ';
    143           }
    144           $query.= $key.' = '.$insert[$key];
    145         }
    146         $query.= '
    147   WHERE id = '.$insert['id'].'
    148 ;';
    149         // echo '<pre>'.$query.'</pre>';
    150         pwg_query($query);
    151       }
    152     }
    153     else
    154     {
    155       // creation of the temporary table
    156       $query = '
    157 DESCRIBE '.IMAGES_TABLE.'
    158 ;';
    159       $result = pwg_query($query);
    160       $columns = array();
    161       while ($row = mysql_fetch_array($result))
    162       {
    163         if (in_array($row['Field'], $dbfields))
    164         {
    165           $column = $row['Field'];
    166           $column.= ' '.$row['Type'];
    167           if (!isset($row['Null']) or $row['Null'] == '')
    168           {
    169             $column.= ' NOT NULL';
    170           }
    171           if (isset($row['Default']))
    172           {
    173             $column.= " default '".$row['Default']."'";
    174           }
    175           array_push($columns, $column);
    176         }
    177       }
    178       $query = '
    179 CREATE TEMPORARY TABLE '.IMAGE_METADATA_TABLE.'
    180 (
    181 '.implode(",\n", $columns).',
    182 PRIMARY KEY (id)
    183 )
    184 ;';
    185       // echo '<pre>'.$query.'</pre>';
    186       pwg_query($query);
    187       // inserts all found pictures
    188       $query = '
    189 INSERT INTO '.IMAGE_METADATA_TABLE.'
    190   ('.implode(',', $dbfields).')
    191    VALUES
    192    ';
    193       foreach ($inserts as $insert_id => $insert)
    194       {
    195         $query.= '
    196 ';
    197         if ($insert_id > 0)
    198         {
    199           $query.= ',';
    200         }
    201         $query.= '(';
    202         foreach ($dbfields as $field_id => $dbfield)
    203         {
    204           if ($field_id > 0)
    205           {
    206             $query.= ',';
    207           }
    208          
    209           if (!isset($insert[$dbfield]) or $insert[$dbfield] == '')
    210           {
    211             $query.= 'NULL';
    212           }
    213           else
    214           {
    215             $query.= $insert[$dbfield];
    216           }
    217         }
    218         $query.=')';
    219       }
    220       $query.= '
    221 ;';
    222       // echo '<pre>'.$query.'</pre>';
    223       pwg_query($query);
    224       // update of images table by joining with temporary table
    225       $query = '
    226 UPDATE '.IMAGES_TABLE.' AS images, '.IMAGE_METADATA_TABLE.' as metadata
    227   SET '.implode("\n    , ",
    228                 array_map(
    229                   create_function('$s', 'return "images.$s = metadata.$s";')
    230                   , array_diff($dbfields, array('id')))).'
    231   WHERE images.id = metadata.id
    232 ;';
    233       echo '<pre>'.$query.'</pre>';
    234       pwg_query($query);
    235     }
     109    $data['date_metadata_update'] = CURRENT_DATE;
     110
     111    array_push($datas, $data);
     112  }
     113 
     114  if (count($datas) > 0)
     115  {
     116    $fields = array('primary' => array('id'),
     117                    'update'  => array('filesize','width','height','name',
     118                                       'author','comment','date_creation',
     119                                       'keywords','date_metadata_update'));
     120    mass_updates(IMAGES_TABLE, $fields, $datas);
    236121  }
    237122}
  • trunk/admin/update.php

    r614 r625  
    4343 * (insides its sub-category), even the newer that have none at te
    4444 * beginning. For this, ordering function selects all categories ordered by
    45  * rank ASC then name ASC for each uppercat. It also updates the global rank
    46  * which is able to order any two categorie in the whole tree
     45 * rank ASC then name ASC for each uppercat.
    4746 *
    4847 * @returns void
     
    5958;';
    6059  $result = pwg_query($query);
     60  $datas = array();
    6161  while ($row = mysql_fetch_array($result))
    6262  {
     
    6666      $current_uppercat = $row['id_uppercat'];
    6767    }
    68     $query = '
    69 UPDATE '.CATEGORIES_TABLE.'
    70   SET rank = '.++$current_rank.'
    71   WHERE id = '.$row['id'].'
    72 ;';
    73     pwg_query($query);
    74   }
    75   // global rank update
    76   $query = '
    77 UPDATE '.CATEGORIES_TABLE.'
    78   SET global_rank = rank
    79   WHERE id_uppercat IS NULL
    80 ;';
    81   pwg_query($query);
    82 
    83   $query = '
    84 SELECT DISTINCT(id_uppercat)
    85   FROM '.CATEGORIES_TABLE.'
    86   WHERE id_uppercat IS NOT NULL
    87 ;';
    88   $result = pwg_query($query);
    89   while ($row = mysql_fetch_array($result))
    90   {
    91     $query = '
    92 SELECT global_rank
    93   FROM '.CATEGORIES_TABLE.'
    94   WHERE id = '.$row['id_uppercat'].'
    95 ;';
    96     list($uppercat_global_rank) = mysql_fetch_array(pwg_query($query));
    97     $query = '
    98 UPDATE '.CATEGORIES_TABLE.'
    99   SET global_rank = CONCAT(\''.$uppercat_global_rank.'\', \'.\', rank)
    100   WHERE id_uppercat = '.$row['id_uppercat'].'
    101 ;';
    102     pwg_query($query);
    103   }
     68    $data = array('id' => $row['id'], 'rank' => ++$current_rank);
     69    array_push($datas, $data);
     70  }
     71
     72  $fields = array('primary' => array('id'), 'update' => array('rank'));
     73  mass_updates(CATEGORIES_TABLE, $fields, $datas);
    10474}
    10575
     
    651621  $start = get_moment();
    652622  ordering();
     623  update_global_rank();
    653624  echo get_elapsed_time($start, get_moment()).' for ordering categories<br />';
    654625}
Note: See TracChangeset for help on using the changeset viewer.