<?
// обращение к базе по умолчанию
// DB_MYSQL()->execSQL() ;
// или просто execSQL() ;

// обращение ко второму серверу
// DB_MYSQL('srv_back1')->execSQL()

// список серверов MYSQL
// $_SETTING=array() ;

//пример использования
// задание настроект в самом скрипте
//$GLOBALS['_SETTING']['srv_back1']['host']='localhost' ; // резервный сервер
//$GLOBALS['_SETTING']['srv_back1']['db_name']='esmo_aldan' ;
//$GLOBALS['_SETTING']['srv_back1']['username']='esmo' ;
//$GLOBALS['_SETTING']['srv_back1']['password']='esmo' ;
//$GLOBALS['_SETTING']['srv_back1']['debug']=1 ;

// или в файле конфига ini.yaml
/*
srv_back1:
    host: localhost
    db_name: esmo_aldan
    username: esmo
    password: esmo
    use_db_cluster_debug: 0
*/


//include(_DIR_TO_ENGINE.'/c_db_mysql.php') ;
//DB_MYSQL('srv_back1')->execSQL('select * from obj_site_account',2) ;

include_once('c_db.php') ;
if (!_sizeof($GLOBALS['_SETTING']['mysql'])) $GLOBALS['_SETTING']['mysql']=array('host'=>$GLOBALS['db_host'],'db_name'=>$GLOBALS['db_name'],'username'=>$GLOBALS['db_username'],'password'=>$GLOBALS['db_password']) ;

function DB_MYSQL($connect_code)
{ if (!isset($GLOBALS[$connect_code])) $GLOBALS[$connect_code]=new db_mysql($connect_code);
  return($GLOBALS[$connect_code]);
    }
class db_mysql extends c_db
{  public $class_name = 'mysql' ;

   function connect($reset_link=0)
   { $this->DB_LINK = mysqli_connect($this->host, $this->username, $this->password,$this->db_name);
     mysqli_query($this->DB_LINK,'SET CHARSET '._DB_CHARSET);
     mysqli_query($this->DB_LINK,'SET NAMES '._DB_CHARSET);
     $text_debug=($this->debug)? 'Параметры подключения:<br>host='.$this->host.'<br>db_name='.$this->db_name.'<br>user_name='.$this->username.'<br>':'' ;
     if (!$this->DB_LINK) die("<hr><center><strong>Невозможно подключиться к серверу MySQL<hr></strong></center>".$text_debug);
     /*if (!(mysqli_select_db($db_name,$this->DB_LINK))) die("<hr><div style='text-align:center;font-weight:bold;'>Не найдена БД '$db_name'</div><hr>");*/
       set_time_point('Подключили базу') ;
    }

    // возвращается массив кодов объектов сгруппированый по классам
    //  - debug: режим отладки, 1 - вывод текста запроса, количества записей и временных параметров
    //						  2 - еще вывод дампа
    //  - no_indx=0 : в качестве индексов массива использовать поле 'pkey', если данное определено
    //  - no_indx=1 : в качестве индексов массива использовать номера строк
    // ВНИМАНИЕ! начиная с версии 4.56 применять во всех вызовах опцию  'no_indx'=1, так как в будущем функция будет подставлять поле в индекс только по требованию
    function execSQL($sql,$options=array(),$no_indx=0,$use_fname_indx='') // запрос к БД
  { global $__debug_sql_cnt,$__debug_sql_time ;
    $arr=array() ; $debug=0 ; $tkey=0 ;
    // новая фишка - для передачи параметров через массив
    if (!is_array($options))   { $debug=$options ; $options=array() ; }
    if ($options['debug'])              $debug=$options['debug'] ;
    if ($options['no_indx'])            $no_indx=$options['no_indx'] ;
    if ($options['use_fname_indx'])     $use_fname_indx=$options['use_fname_indx'] ;
    if ($options['indx'])               $use_fname_indx=$options['indx'] ;

    $querytime_before=fixed_time() ;
    //$debug=2 ;

    if ($debug or $this->debug) print_SQL_debug_begin($sql) ;

     if (!$result = mysqli_query($this->DB_LINK,$sql)) SQL_error_message($sql) ;
      else
	  {	 if ($debug or $this->debug) { echo '<strong>Получено '.$result->num_rows.' записей : </strong>' ;fixed_time($querytime_before,'запрос к БД занял - ','') ;}
         $t_exec_sql=fixed_time($querytime_before) ; $querytime_after=fixed_time() ;
         //damp_array(_DOT($tkey)) ;
	     $fname_indx=($use_fname_indx)? $use_fname_indx:mysqli_fetch_field($result)->name ;
         try
         {
		   while (($new_res=mysqli_fetch_array($result,MYSQLI_ASSOC))!=NULL)
           { if (isset($new_res['pkey']) and !isset($new_res['tkey'])) $new_res['tkey']=get_main_table_id_in_SQL($sql) ;
             if ($new_res['tkey'] and $new_res['pkey']) {$new_res['_reffer']=$new_res['pkey'].'.'.$new_res['tkey'] ;}
             if ($new_res['tkey'] and isset($new_res['parent']) and isset($_SESSION['descr_obj_tables'][$new_res['tkey']]))
                 if (_DOT($new_res['tkey'])->mode=='main') $new_res['_parent_reffer']=$new_res['parent'].'.'.$new_res['tkey'] ;
                 else                                      $new_res['_parent_reffer']=$new_res['parent'].'.'._DOT($new_res['tkey'])->parent ; ;
             if ($_SESSION['__fast_edit_mode']=='enabled' and !$options['no_fs_info'] and $new_res['_reffer']) update_fast_edit_info($new_res) ;
             if ($options['no_manual']) unset($new_res['manual']) ;
             if ($options['no_intro']) unset($new_res['intro']) ;
             if ($options['hide_fields']) foreach($options['hide_fields'] as $hide_fname) unset($new_res[$hide_fname]) ;


             // если рабочий язык страницы не основной, заносим значение локального поля в основное
             if (_sizeof($new_res) and _CUR_LANG and !$options['no_cur_lag_correct']) foreach($new_res as $fname=>$fvalue) if ($new_res[$fname]) // только для заполненных полей
             { $suff1=strrchr($fname,_CUR_LANG_SUFF) ;
               if ($suff1==_CUR_LANG_SUFF) { $main_fname=str_replace(_CUR_LANG_SUFF,'',$fname) ; $new_res[$main_fname]=$new_res[$fname] ; /* echo 'fname='.$fname.' => |'.$suff1.'|<br>' ;*/}
             }

             if ($new_res[$fname_indx] and !$no_indx) $arr[$new_res[$fname_indx]]=$new_res ; else $arr[]=$new_res ;
            }
         }
         catch(Exception $ex)
            {
                //$ex - экземпляр класса Exception
                // или его наследника
            }
		 if ($debug==2 or $this->debug==2 or $this->debug==3) print_2x_arr($arr,$sql) ;
         if ($debug==3) damp_array($arr,$sql) ;
         if ($debug or $this->debug) {fixed_time($querytime_before,', суммарное время получения и обработки - ','') ;}

         $t_work_sql=fixed_time($querytime_after);
         $__debug_sql_time+=fixed_time($querytime_before);
         $__debug_sql_cnt++ ;

         debug_db_logging($sql,$t_exec_sql,$t_work_sql,_sizeof($arr),$options) ;
      }
	 if ($debug or $this->debug) print_SQL_debug_end() ;
     return($arr) ;
    }

    // для запросов, возвращающих только одну строку
    // результат - массив res["pkey"],res["value"],res["name"], т.е. обращение происходит
    // напрямую по имени поля
    // проверить с помощтю поиска по регулярному выражению execSQL_van.*\, есть ли использование других параметров, если нет - удалить
    function execSQL_van($sql,$options=array(),$no_indx=0,$ignore_error=0) // запрос к БД
    { global $__debug_sql_cnt,$__debug_sql_time ;
      $arr=array() ; $debug=0 ;
      if (!is_array($options)) { $debug=$options ; $options=array() ; }
      if ($options['debug'])              $debug=$options['debug'] ;
      if ($options['ignore_error'])       $ignore_error=$options['ignore_error'] ;
      //$debug=2 ;
       $querytime_before=fixed_time() ;

    	 if ($debug or $this->debug) print_SQL_debug_begin($sql) ;

       if ($ignore_error) $result = @mysqli_query($this->DB_LINK,$sql) ; else if (!$result = mysqli_query($this->DB_LINK,$sql)) { SQL_error_message($sql) ; return $arr; }

  	 if ($debug or $this->debug)  { echo '<strong>Получено '.$result->num_rows.' записей : </strong>' ; fixed_time($querytime_before,'запрос к БД занял - ','') ; }

  	 $arr=mysqli_fetch_assoc($result) ;
     $t_exec_sql=fixed_time($querytime_before) ; $querytime_after=fixed_time() ;
  	 if (!is_array($arr)) $arr=array() ;

       // простовляем в запросе код таблицы
       preg_match_all('/from (\w+_\w+_\w+)/is', $sql, $matches);
       $ii=_sizeof($matches[0])-1 ; // в запросе может быть несколько подзапросов , но главная таблица всегда будет идти последней
       $table_name=str_replace('from ','',$matches[0][$ii]) ;
       if (isset($_SESSION['pkey_by_table'][$table_name]) and $arr['pkey']) $arr['tkey']=$_SESSION['pkey_by_table'][$table_name] ;

       if ($arr['tkey'] and $arr['pkey']) $arr['_reffer']=$arr['pkey'].'.'.$arr['tkey'] ;
       //damp_array($arr) ;
       // удаляем большие текстовые поля из результатов запроса
       if ($options['no_text_fields'] and $arr['tkey'])
       { // принудительная загрузка описания таблицы, если оно еще не загружено
         //if (!_sizeof(_DOT($arr['tkey'])->field_info)) upload_descr_table($arr['tkey']) ;
         //if (_sizeof(_DOT($arr['tkey'])->field_info)) foreach(_DOT($arr['tkey'])->field_info as $fname=>$ftype)
         // if ($ftype=='text' and $fname!='obj_name') unset($arr[$fname]) ;
       }

       // если рабочий язык страницы не основной, заносим значение локального поля в основное
       if (_sizeof($arr) and _CUR_LANG and !$options['no_cur_lag_correct']) foreach($arr as $fname=>$fvalue) if ($arr[$fname]) // только для заполненных полей
       { $suff1=strrchr($fname,_CUR_LANG_SUFF) ;
         if ($suff1==_CUR_LANG_SUFF) { $main_fname=str_replace(_CUR_LANG_SUFF,'',$fname) ; $arr[$main_fname]=$arr[$fname] ; /*echo 'fname='.$fname.' => |'.$suff1.'|<br>' ;*/}
       }

       if ($debug==2  or $this->debug==2 or $this->debug==3) { $temp_arr[]=$arr ; print_2x_arr($temp_arr,$sql) ; }
       if ($debug or $this->debug) fixed_time($querytime_before,', суммарное время получения и обработки - ','') ;

  	 if ($debug or $this->debug) print_SQL_debug_end() ;

      $t_work_sql=fixed_time($querytime_after);
      $__debug_sql_time+=fixed_time($querytime_before);
      $__debug_sql_cnt++ ;
      debug_db_logging($sql,$t_exec_sql,$t_work_sql,1,$options) ;

      if ($arr['tkey'] and $arr['pkey']) {$arr['_reffer']=$arr['pkey'].'.'.$arr['tkey'] ;}
      //if ($arr['tkey'] and $arr['parent']) if (_DOT($arr['tkey'])->mode=='main') $arr['_parent_reffer']=$arr['parent'].'.'.$arr['tkey'] ;
  	//	                                 else                                  $arr['_parent_reffer']=$arr['parent'].'.'._DOT($arr['tkey'])->parent ; ;

  	if ($_SESSION['__fast_edit_mode']=='enabled' and !$options['no_fs_info'] and $arr['_reffer']) update_fast_edit_info($arr) ;

      return $arr;
    }


    // аналогично execSQL, но выключена отладка - для увеличесния скорости
    function execSQL_fast($sql,$options=array()) // запрос к БД
    {  global $__debug_sql_cnt,$__debug_sql_time ;
       $arr=array() ;
       $querytime_before=fixed_time() ;

       if (!$result = mysqli_query($this->DB_LINK,$sql,$options)) SQL_error_message($sql) ;
       $t_exec_sql=fixed_time($querytime_before) ; $querytime_after=fixed_time() ;

       $fname=mysqli_fetch_field($result)->name ;
       while (($new_res=mysqli_fetch_assoc($result))!==false) if ($new_res[$fname]) $arr[$new_res[$fname]]=$new_res ; else $arr[]=$new_res ;

       $t_work_sql=fixed_time($querytime_after);
       $__debug_sql_time+=fixed_time($querytime_before);
       $__debug_sql_cnt++ ;
       debug_db_logging($sql,$t_exec_sql,$t_work_sql,_sizeof($arr),$options) ;
       return $arr;
    }

   // функция для выполнения запросов update,delete и т.д.
   function execSQL_update($sql,$options=array())
    { global $__debug_sql_cnt,$__debug_sql_time ;
      $debug=0 ; $count=0 ;
      if (!is_array($options)) { $debug=$options ; $options=array() ; }
      if ($options['debug'])     $debug=$options['debug'] ;

  	$querytime_before=fixed_time() ;

  	if ($debug or $this->debug) print_SQL_debug_begin($sql) ;

       if (!mysqli_query($this->DB_LINK,$sql)) SQL_error_message($sql) ;
       else
  	  {	 $count=mysqli_affected_rows($this->DB_LINK) ;
         $t_exec_sql=fixed_time($querytime_before) ; $querytime_after=fixed_time() ;
         if ($debug or $this->debug or $options['log_result'])
  		  { //echo '<span class=blau>'.mysqli_info($this->DB_LINK).'</span><br>' ; - не работает
              echo '<br><strong>Затронуто '.$count.' записей : </strong>' ; ;
  		    fixed_time($querytime_before,'запрос к БД занял - ','') ;
              fixed_time($querytime_before,', суммарное время получения и обработки - ','') ;
  		 }
  		 $t_work_sql=fixed_time($querytime_after);
         $__debug_sql_time+=fixed_time($querytime_before);
         $__debug_sql_cnt++ ;
         debug_db_logging($sql,$t_exec_sql,$t_work_sql,$count,$options) ;
  	  }
  	 if ($debug or $this->debug) print_SQL_debug_end() ;
       return($count) ;
    }

   function execSQL_Line($sql,$options=array())
    { global $__debug_sql_cnt,$__debug_sql_time ;
      $arr=array() ;
      $debug=0 ;
      if (!is_array($options)) { $debug=$options ; $options=array() ; }
      if ($options['debug'])              $debug=$options['debug'] ;

      $querytime_before=fixed_time() ;
      if ($debug or $this->debug) print_SQL_debug_begin($sql) ;

  	if (!$result = mysqli_query($this->DB_LINK,$sql)) SQL_error_message($sql) ;
    $t_exec_sql=fixed_time($querytime_before) ; $querytime_after=fixed_time() ;

      if ($debug or $this->debug){echo '<strong>Получено '.$result->num_rows.' записей : </strong>' ;fixed_time($querytime_before,'запрос к БД занял - ','') ;}

      if ($result>"") for ($i=0;$i<$result->num_rows;$i++) $arr[]=mysqli_result($result,$i,0);

  	if ($debug==2  or $this->debug==2  or $this->debug==3) print_array($arr,$sql) ;
  	if ($debug or $this->debug) fixed_time($querytime_before,', суммарное время получения и обработки - ','') ;

    $t_work_sql=fixed_time($querytime_after);
    $__debug_sql_time+=fixed_time($querytime_before);
    $__debug_sql_cnt++ ;
    debug_db_logging($sql,$t_exec_sql,$t_work_sql,_sizeof($arr),$options) ;
  	if ($debug or $this->debug) print_SQL_debug_end() ;
      return $arr;
    }

   // возвращает один столбец
   function execSQL_row($sql,$options=array())
    { global $__debug_sql_cnt,$__debug_sql_time;
      $arr=array() ;
      $debug=0 ;
      if (!is_array($options)) { $debug=$options ; $options=array() ; }
      if ($options['debug'])              $debug=$options['debug'] ;

      $querytime_before=fixed_time() ;

  	if ($debug or $this->debug) print_SQL_debug_begin($sql) ;

  	if (!$result = mysqli_query($this->DB_LINK,$sql)) SQL_error_message($sql) ;
    $t_exec_sql=fixed_time($querytime_before) ; $querytime_after=fixed_time() ;

      if ($debug or $this->debug){echo '<strong>Получено '.$result->num_rows.' записей : </strong>' ;fixed_time($querytime_before,'запрос к БД занял - ','') ;}

      if ($result>"") for ($i=0;$i<$result->num_rows;$i++) $arr[mysqli_result($result,$i,0)]=mysqli_result($result,$i,1);

      if ($debug==2 or $this->debug==2 or $this->debug==3) print_array($arr,$sql) ;
      if ($debug or $this->debug) fixed_time($querytime_before,', суммарное время получения и обработки - ','') ;

  	if ($debug or $this->debug) print_SQL_debug_end() ;

  	  $t_work_sql=fixed_time($querytime_after);
      $__debug_sql_time+=fixed_time($querytime_before);
      $__debug_sql_cnt++ ;
      debug_db_logging($sql,$t_exec_sql,$t_work_sql,_sizeof($arr),$options) ;
      return $arr;
    }

    function mysqli_result($res, $row, $field=0) {
      $res->data_seek($row);
      $datarow = $res->fetch_array();
      return $datarow[$field];
    }

    // для запросов, возвращающих только одно значение
    function execSQL_value($sql,$options=array(),$no_indx=0,$ignore_error=0) // запрос к БД
    { $res=$this->execSQL_van($sql,$options,$no_indx,$ignore_error) ;
      if (_sizeof($res))
      {   reset($res) ;
          list($indx,$value)=each($res) ;
          return($value) ;
      }
    }






}
?>
