ru_dmitriid


О королях и капусте


Стыжусь
happy
dmitriid
Как мне не стыдно. В прошлом посте я допустил ошибку. Спасибо xaprb за замечание.

Я неправильно расставил кавычки во втором запросе.

Как должно было быть:

date BETWEEN '2008-01-01 12:00:00.000' AND '2008-01-14 12:00:00.000' AND accomodation=1


Как стало:

date BETWEEN '2008-01-01 12:00:00.000' AND '2008-01-14 12:00:00.000 AND accomodation=1'


Обратите внимание на кавычку после accomodation=1

:)
Tags: ,

Запрос, как много в этом звуке...
happy
dmitriid
Разбираюсь на работе с базами данных. Краем глаза читаю «High performance MySQL». Решаю опробовать полученные навыки на практике. Хм...

Есть у нас таблица, разбитая на пратиции по неделям:


CREATE TABLE `price_detail` (
`accomodation` int(11) NOT NULL,
`date` datetime NOT NULL,
`price` int(11) NOT NULL,
`room_id` int(11) NOT NULL,
KEY `idx_price_date` (`date`) USING BTREE,
KEY `idx_price` (`price`) USING BTREE,
KEY `idx_price_accomodation` (`accomodation`) USING BTREE
)
PARTITION BY RANGE (TO_DAYS(`date`)) (
PARTITION p20080101 VALUES LESS THAN (733407),
PARTITION p20080108 VALUES LESS THAN (733414),
/* и так далее — на целый год */


Нда... И индексы тож...

На каждую неделю у нас ни много ни мало — 26 миллионов записей в худшем случае. Для тестирования выбран именно худший случай.

Смотрим, как у нас будет работать выборка из этой базы:

Запрос первый:

explain partitions 
  select 
    accomodation 
  from 
    price_detail 
  where 
    accomodation=1 and date BETWEEN '2008-01-01 12:00:00.000' AND '2008-01-14 12:00:00.000'\G;

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: price_detail
   partitions: p20080108,p20080115
         type: ref
possible_keys: idx_price_date,idx_price_accomodation
          key: idx_price_accomodation
      key_len: 4
          ref: const
         rows: 40292
        Extra: Using where


Запрос второй:


explain partitions 
  select 
    accomodation 
  from 
    price_detail 
  where 
    date BETWEEN '2008-01-01 12:00:00.000' AND '2008-01-14 12:00:00.000 AND accomodation=1'\G;

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: price_detail
   partitions: p20080108,p20080115,p20080122,p20080129,p20080205,p20080212,p20080219,
                     p20080226,p20080304,p20080311,p20080318,p20080325,p20080401,p20080408,
                     p20080415,p20080422,p20080429,p20080506,p20080513,p20080520,p20080527,
                     p20080603,p20080610,p20080617,p20080624,p20080701,p20080708,p20080715,
                     p20080722,p20080729,p20080805,p20080812,p20080819,p20080826,p20080902,
                     p20080909,p20080916,p20080923,p20080930,p20081007,p20081014,p20081021,
                     p20081028,p20081104,p20081111,p20081118,p20081125,p20081202,p20081209,
                     p20081216,p20081223,p20081230,p20090106,p20090113,p20090120,p20090127
         type: ALL
possible_keys: idx_price_date
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 274845000
        Extra: Using where


Звезда в шоке.

Ушел читать covering index...




ЗАПОЗДАЛЫЙ АПДЕЙТ. Во тором случае забыл просто кавычку после второй даты закрыть :) Что оно в итоге искало — хз :)
Tags: ,

Что в вакансии тебе моей...
happy
dmitriid
Набираем людей на работу.

Во первых строках вакансии пишем: «требуется хорошее или отличное знание РНР»

Приходит письмо: «РНР я только начинаю изучать...»

Может, я чего-то не понимаю в этой жизни? :)

Сотня мудрецов...
happy
dmitriid
via http://andrzejn.livejournal.com/1152676.html

- Сотня мудрецов знают, что нечто невозможно. Потом находится один дурак, который этого не знает...

- И он-то и делает открытие?

- Нет, но мудрецы ещё долго потом вспоминают его с умилением.

Размышлизмы
happy
dmitriid
Как и обещал, размышления

1. Во-первых, сопоставление с образцом позволяет быстро и достаточно безболезненно описывать требуемое. Например, возьмем правила:

{field}
{field, Func}
{field, {'=', field2}}


Честно говоря, я слабо себе представляю, как это обработать if'ами. Думаю, все это пришлось бы оборачивать в какой-нибудь класс Rule и наследовать от него классы RuleField, RuleFunc, RuleOperator и так далее. Используя сопоставление с образцом, такие правила разребаются очень просто:

%%{field}
validate_rule({FieldName}) ->
    ok.

%%{field, Func}
validate_rule({FieldName, Func}) when is_function(Func) ->
    ok.

%%{field, {'=', field2}}
validate_rule({FieldName, {Operator, FieldName2}}) ->
    ok.


Правда, такая легкость приводит (меня, во всяком случае) к пункту 2:

2. Индусокод. Эта легкость в обработке сложных конструкций моет привести к тому, что начинаешь просто писать функции, их обрабатывающие, вместо того, чтобы остановиться и подумать - а оно мне надо?

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

В итоге, в самом начале функция возвращала дикую конструкцию такого вида:


[[Field, [Error1, Error2]], [Field2, [Error3, Error4]]]


то есть глубокий список списков. Это сейчас она возвращает более-менее proplist. С третьей попытки :)

Этот же подход в стиле "вау, посмотри, что я могу обработать, а что вернем - неважно" привел к тому, что перед возвращением значения происходит следующая обработка:

lists:filter(
    fun(Elem) -> 
        case 
            Elem of {} -> false; 
            {_, []} -> false;
            _ -> true 
        end 
    end, 
    lists:flatten(validate1(A, ValidationRules, [])))


Дадада. Вычищаем список от нежелательных элементов. Вам страшно? Мне - да. Мне еще и грустно :(


На этом мысль закончилась...
Tags:

Валидация для erlyweb
happy
dmitriid
Накалякал тут функцию валидации для Erlyweb. Сначала описание работы, а потом, может быть, о самой функции :) Работает примерно так:

Создаем форму с четырьмя полями:
- login
- password
- pasword_repeat
- email

Стандартная форма регистрации то бишь. Естественно, нам нужно провести валидацию полей следующим образом:
- login должен быть 4-16 символов
- password должен быть 4-16 символов
- password должен быть равен password_repeat
- email должен быть правильным адресом

Стандартные функции валидации для этого не подходят. Но подойдет моя :)

Предположим, у нас есть функция process_signup, которая принимает на вход стандартную структуру yaws_arg. Тогда валидация будет выглядеть следующим образом:

process_signup(A) ->
	F = fun(A, Field) ->
		{ok, Val} = yaws_api:postvar(A, Field),
		L = string:len(Val),
		if
			L < 4 orelse L > 16 ->
				{Field, length};
			true ->
				{}
			end
	end,
	EmailCheck = fun(Args, Field2) ->
		{ok, Email} = yaws_api:postvar(Args, Field2),
		Match = regexp:match(Email, "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]+"),
		Match /= nomatch
	end,

	%% магия тут:
	buktu_form:validate(A, [
		{login, F},
		{email, EmailCheck},
		{password, [{'=', password_repeat}, F]}
	]).


Таким образом, если вообще ни одно поле введено не будет, то мы получим:
[{login,invalid_field},
 {email,invalid_field},
 {password,[{invalid_fields,[password,password_repeat]},
            invalid_field]}]


Если введем поля, не соответствующие критериям, то:
[{login,length},
 {email,invalid_value},
 {password,[{not_equal,password_repeat},
            length]}]


  • Callback-функция, которую можно передавать для валидации, может возвращать:

    • кортеж типа {FieldName, Error}

    • true, если поле прошло валидацию или false в противном случае (тогда функция валидации вернет кортеж {FieldName, invalid_value})

    • любое значение Value, которое будет трансформировано в {FieldName, Value}


  • если любое из полей в правиле не существует или не содержит значение, то для каждого такого правила функция валидации вернет:

    • invalid_field если поле сравнивается со значением

    • {invalid_fields, [field1, field2]} если поле сравнивается с другим полем


  • Если необходимо передать несколько правил, достаточно передать их в списке. Если достаточно проверить наличие поля, можно передать кортеж, содержащий только название поля:

    • Проверить, существует ли такое поле
      {field_name}

    • Сравнить поле field_name с полем field2_name (также можно использовать '=', '/=', '<', '=<', '>', '>=' )
      {field_name, {'=', field2_name}}

    • Сравнить значение поля с любым другим значением:
      {field_name, {'=', Value}}

    • Использовать callback-функцию (function/2, первый параметр - yaws_arg, второй - название поля). Функция может быть лямбдой или любой функцией из любого модуля в виде module:function/2 или {module, function}
      {field_name, F}

    • Использовать callback-функцию с дополнительным значением (function/3, первый параметр - yaws_arg, второй - название поля, третий - значение). Функция может быть лямбдой или любой функцией из любого модуля в виде module:function/3 или {module, function}
      {field_name, {F, Value}}


  • Функция валидации возвращает proplist в виде:
    [{FieldName(), Errors()}]

    где
    FieldName() = atom()
    Errors() = Error() | [Error()]
    Error() = любое_пользовательское_значение | absent | invalid_value | 
              invalid_field | {invalid_fields, [FieldName(), FieldName()]} |
              ComparisonError()
    ComparisonError() = {not_equal, value_or_field} | {equal, value_or_field} |
                        {not_greater, value_or_field} | {not_less, value_or_field} |
                        {not_greater_or_equal, value_or_field} | {not_less_or_equal, value_or_field} |
    

Apple...
happy
dmitriid



v obshem, vot ono. nemnogo neprivychno, no budem osvaivat'...
Tags:

Опрос о журнале по декларативному программированию
happy
dmitriid
darkus проводит опрос о целесообразности создания журнала (электронного или печатного) по декларативному программированию:

http://users.livejournal.com/_darkus_/422028.html

Пристрелите
happy
dmitriid
Кто-нибудь, пристрелите меня :)

Я ухитрился собственноручно сдвинуть с места один из самых старых багов в Firefox'е: https://bugzilla.mozilla.org/show_bug.cgi?id=69230 (см. комментарий 86). Что с этим "счастьем" делать - ума не приложу :) А ведь мне еще собирать мозиллу из сырцов придется...

Ля-ля-ля, я сошла с ума (с) :))

Erlang Bit Syntax
happy
dmitriid
Решил я посмотреть, насколько все легко и просто в Эрланге с двоичными данными, как рассказывается.

Вернее, так. Один мой товарищ возился с форматом OMA, использующемся в аудиоплеерах Sony. Единственно отличие этого формата от других, человеческих, вроде MP3 в том, что он не документирован, а та информация, что об этом формате есть противоречит самому же формату :)Read more...Collapse )
Tags:

?

Log in