пятница, 8 ноября 2013 г.

MySQL проблемы миграции

Надо было перенести сайт с сервера разработки на хостинг.
Всё вроде бы отлажено и работает. а на хостинге вдруг отказывается и сыпет сообщениями подобного содержания
Warning: mysql_connect() [function.mysql-connect]: Premature end of data (mysqlnd_wireprotocol.c:554) in ...
Warning: mysql_connect() [function.mysql-connect]: OK packet 1 bytes shorter than expected in ..
Немного побившись головой об клавиатуру, полез разбираться в чём же дело.
А дело оказалось в авторизации, точней в разнице в версия (и настройках) MySQL. Хэши паролей были разной длины. из-за разных механизмов хеширования (О_о).
В итоге всё решается простым запросом, который приведёт хэш к нужному виду
SET PASSWORD = PASSWORD('пароль')

понедельник, 14 октября 2013 г.

скриптуем математику в bash

юзается так:
$ seq 0 99 | ./test_seq.sh is_prime 

Сам скрипт выглядит так... Для проверки простых чисел используется калькулятор для командной строки o.0
#!/bin/bash

even_counter=$(( 2-$1%2  ))

function is_prime {
    number=
    if(( $1 < 0 )); then
        number=$(($1*-1))
    else
        number=$1
    fi
    if(( $number == 1 || $number == 0)); then
        echo $1
        return
    fi
    # а это строчка проверки числа, простое ли оно...
    result=`seq -s "*" 1 $(($number-1)) | 
sed -r "s/([0-9,\*]+)/(\1+1)%$number/" | bc`
    # перенос строчки чисто чтобы в блог нормально влезло

    #echo "[[$result]] for $number"
    if(( $result == 0 )); then
        echo $1
    fi
}

function is_even {
    if(( $even_counter == 2 )); then
        echo $1
        even_counter=1
    else
        even_counter=$(($even_counter + 1))
    fi
}

function is_not_even {
    if(( $even_counter == 1 )); then
        echo $1
        even_counter=$(($even_counter + 1))
    else
        even_counter=1
    fi
}

echo "filtering by: $1"
for item in $(cat)
do
    # echo "Item: $item"
    cmd="$1 $item"
    eval "$cmd"
    # eval $1
done

четверг, 29 августа 2013 г.

Абстракция от Sql в C#

Дано:
Имеется база данных с табличкой users(столбцы userID, и userName)

Условие:
Хочется инструмент который позволял бы быстро делать простейшие действия, но при этом был бы достаточно гибким для действий специфических.

Мое решение:
public static class SqlService
{
    private static string connectionString = "CONNECTION_STRING_HERE";

    // это позволит нам быстро создавать соединение
    public static SqlConnection Connection {
        get {
            return new SqlConnection(connectionString);
        }
    }

    // выполняем команду оставляя соединение в исходном состоянии
    private static void myExecute(this SqlCommand command) {
        bool connectionOpened =
            (command.Connection.State == ConnectionState.Open);

        if (!connectionOpened) {
            try {
                command.Connection.Open();
            }
            catch { throw; }
        }

        try {
            command.ExecuteNonQuery();
        }
        catch { throw; }
        finally {
            if (!connectionOpened) {
                command.Connection.Close();
            }
        }
    }

    public static void AddUser(Guid userID,
                               string userName,
                               SqlConnection connection = null) {
        //если соединение не передается в аргументе создаем новое
        SqlConnection con = connection ?? Connection;
        SqlCommand com =
            new SqlCommand("INSERT INTO users(userID, userName)"
                         + " VALUES(@userID, @userName)", con);
        com.Parameters.Add("@userID", SqlDbType.UniqueIdentifier);
        com.Parameters.Add("@userName", SqlDbType.NVarChar, 256);
        com.Parameters["@userID"].Value = userID;
        com.Parameters["@userName"].Value = userName;
        try {
            com.myExecute();
        }
        catch { throw; }
    }

    public static void DeleteUser(Guid userID,
                                  SqlConnection connection = null) {
        SqlConnection con = connection ?? Connection;
        SqlCommand com = new SqlCommand("DELETE FROM users"
                                       + " WHERE userID=@userID", con);
        com.Parameters.Add("@userID", SqlDbType.UniqueIdentifier);
        com.Parameters["@userID"].Value = userID;
        try {
            com.myExecute();
        }
        catch { throw; }
    }
}
Пример использования:
static void Example() {
    Guid newUserID = Guid.NewGuid();

    // простое действие
    // соединение создалось, открылось и закрылось
    SqlService.AddUser(newUserID, "MrSmith");

    // специфичное действие
    using (SqlConnection connection = SqlService.Connection) {
        connection.Open();

        //команда выполнилась, соединение осталось открытым
        SqlService.DeleteUser(newUserID, connection);

        //выполняем любые действия используя то же соединение
        SqlCommand specCom = new SqlCommand(specComText, connection);
        specCom.ExecuteNonQuery();
    }
}

пятница, 9 августа 2013 г.

MODx ERROR: Too many forward attempts.

При использовании ЧПУ в cms MODX может выскочить такая вот неочевидная ошибка "Too many forward attempts", природа её кроется как правило в том что пользователь/администратор/менеджер не указал в настройках станицу которая будет отображаться в случае ошибки.


понедельник, 5 августа 2013 г.

Геолокация IP адресов и злобные хостеры

Случилось однажды такое, что мне надо было прикрутить к сайту определение региона (области/субъекта РФ/тд.) по IP. Первое что пришло в голову - это воспользоваться уже имеющимся сервисом. После некоторых поисков я остановился на этом замечательном сайте http://ipgeobase.ru/

У них имеются 2 реализации.
http://blog.ipgeobase.ru/?p=37
http://blog.ipgeobase.ru/?p=76

Вроде всё просто, Курлом, отправляем адрес, получаем результат, все довольны. Но после часа-полутора возни выяснилось что на хостинге где живёт нужный сайт, провайтер по каким-то причинам запретил Curl'ом ходить по нестандартным портам (а сервисы ipgeobase у нас висят на 8090 и 7020).

Практически моментально отказавшись от использования всяких прокси, было решено сделать всё на стороне клиента, (а что серверу и так нелегко, ещё и ответ курловый ждать =) ).
А чтобы не дёргать по пустякам сервис, результат сохраняется в куках на неделю.

Код решения.
function get_region(){
 //get_cookie - не стандартная функция и не часть jquery =) при отсутствии нужной куки возвращает null
 var region = get_cookie('region');
 if (region !== null) {
  //делаем свои важные дела
  set_region(region);
 }
 //ip нам услужливо печатает сервер.
 var ip = $("#ip").val();
 $.ajax({
  type: "GET",
  url: "http://ipgeobase.ru:7020/geo?ip="+ip,
  dataType: "xml",
  success: function(xml) {
   $(xml).find('ip').each(function(){
    var reg = $(this).find('region').text();
    //делаем свои важные дела
    set_region(reg);
   });
  }
 });
}


четверг, 25 июля 2013 г.

google spreadshit

Мифы и надежды
* через апи можно получить _только_ формулу и данные ячейки
- комментари недоступны
- заметки не доступны
- форматирование ячеек недоступно
(http://code.google.com/a/google.com/p/apps-api-issues/issues/detail?id=1263)

в самой таблице возможно условное форматирование, но обработка данных согласно форматированию не возможна.
Хотя и есть несколько подходящих костылей: (В этом месте ваш браузер начинает биться в истерике)

function getBackgroundColor(rangeSpecification) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  return sheet.getRange(rangeSpecification).getBackgroundColor();
}

function ifColorSet(cellCol, cellRow, colorName, trueValue, falseValue) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var cellRowText = ("abcdefghijklmnopqrstuvwxyz").split("");
  var actualColor = sheet.getRange(cellRowText[cellCol-1]+''+cellRow)
      .getBackgroundColor();
  if(actualColor==colorName) {
    return trueValue;
  }
  return falseValue;
}

function getCellId(cellCol, cellRow) {
  var cellRowText = ("abcdefghijklmnopqrstuvwxyz")
      .toUpperCase().split("");
  return cellRowText[cellCol-1]+''+cellRow;
}

четверг, 11 июля 2013 г.

обновляем PHP до версии 5.4 в CentOS

Давно было пора это сделать, но всё какие-то другие дела отвлекали. как обычно вобщем.

Для начала удалим имеющееся старьё. php 5.2
yum uninstall php-common
Устанавливаем нужную версию
yum install php54
У нас nginx поэтому нужен FastCGI
yum install php54-fpm
Ну и то что постоянно используется
yum install php54-mysql 
yum install php54-gd
после установки не забыть в /etc/php.ini поставить short_open_tag = On
и перезапустить всё
/etc/init.d/php-fpm restart
/etc/init.d/nginx restart  

суббота, 6 июля 2013 г.

Samsung Galaxy Tab 8.9 P7310

Рассказывать всю предысторию и то как этот девайс попал ко мне в руки достойно отдельной книги.
Поэтому можно сразу начать с того что вот он планшет. Samsung GT-P7310 в простонародье GalaxyTab 8.9 WiFi :) Куплен был где-то на просторах Поднебесной. В фирменном магазине Samsung. А значит и андроид там обязан быть странновато-китайским.