Перейти к основному содержимому

Порядок выполнения событий в DOM

· 2 мин. чтения

Столкнулся с проблемой в своём календарике - есть два элемента, один из которых позиционируется абсолютно на весь экран, полупрозрачная затемняющая занавеска а второй - форма. Вы наверняка видели такие решения при показе картинок в lightbox или аутидентификации на habrahabr'е..

<div id='form_bg' onclick="$('form_bg').hide();$('form').hide();"> <div id='form'></div> </div>

Проблема в том, что при любом нажатии на внутренний элемент, событие автоматом вызывается на родительском элементе. Это заставило меня задуматься как над решением, так и над теорией как браузеры работают.


Две с половиной модели

Как оказывается, существует две модели передачи событий в объектно-ориентированной иерархии

  • Пузырьковый метод (bubbling), когда событие возникает внутри и затем передаётся родительским элементам наружу. MS Internet Explorer, Opera, Firefox
  • Захват события (capturing), событие обрабатывается сначала у родителей, а потом проникает глубже. Opera, Firefox

Консорциум W3C благоразумно решили что разработчикам может быть удобно в любую сторону направлять события (event propagation), поэтому по стандарту две модели объединены - событие сначала захватывается, а потом возвращается как пузырёк.

Таким образом разработчик может привязать вызываемый метод к фазе события:

$('form_bg').addEventListener('click',hideBackground,true); // true - говорит о фазе capturing $('form').addEventListener('click',function(){},false); // false - говорит о фазе bubbling
Получается что при клике на form_bg происходит сразу hideBackground, и form на фазе capturing не вызывается, затем возвращаясь, в фазе bubbling вызывается анонимная функция. 

Традиции по умолчанию

Модель W3C приятна, но по умолчанию по всей видимости из-за IE, обычная регистрация события подразумевает bubbling фазу, т.е. изнутри наружу. А это в свою очередь значит, что если я явно укажу на родительский элемент:

$('form_bg').onclick = hideBackground; // или как выше - в <div id='form_bg' onclick=..

То любое событие без остановки вызывает у всех родительских элементов обработку onclick-события. Есть у них оно или нет, вплоть до корня - document.

Заплыв без пузырьков

В кросс-браузерном варианте для остановки распространения обработки события к родительским элементам, надо поменять параметр cancelBubble на true (для IE) и вызывать функцию stopPropagation (W3C модель):

function hideBackground(e){ if (!e) var e = window.event; e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation(); }

Теперь мне интересно как устроена модель обработки событий в других языках и платформах - Java, NET, Flash..

Написано по мотивам статьи "Event order".

Random order в Postgres

· 3 мин. чтения

Случайность — маска неузнанной закономерности
Александр Волков

Как-то я писал о том как быстро можно сделать выборку в MySQL по большой таблице в случайном порядке не используя ORDER BY RAND(), теперь этот же вопрос всплыл на Postgre. Если вы не знаете, то ORDER BY RAND достаточно медленная операция из-за того, что сортируется фактически вся таблица. Некоторые советовали всё-таки обычную сортировку или чуть-изменённую с использованием Primary Key, но я на своём опыте убедился что конструкция IN всегда медленней чем EXISTS.

Электроны и дырки

Вообще задача подразумевает выборку и нескольких случайных рядов, но она сводится к выборке одного ряда, а точней ID. Самый простой способ - взять минимум (MIN или 1), максимум (MAX или значение Sequence) и случайным образом тыкнуть в промежутке. Задача чем-то напоминает процесс хэширования. И всё хорошо покуда всё идёт по порядку и ряды не удаляются. Как только в базе возникают пустоты (а они возникают вероятностью пропорционально размеру проекта), то получается что ряд не находится.

Использовать наиболее близкий к этой дырке ID'шник мы не можем из-за неравномерного распределения вероятностей и не гарантированного присутсвия вообще каких-то данных если мы в конце. Хотя можно плюнуть..

SELECT * FROM mytable WHERE id >= CEIL(RANDOM()*(SELECT MAX() FROM mytable)) ORDER BY id LIMIT 1;

Лотерея

Делать цикл с простукиванием каждой дыры тоже рискованно - вставит кто-нибудь гипер прыжок ID с 435 на 43600 и сложность алгоритма прыгнет основательно. 

Можно оторваться от ID'шек и внести случайны float-параметр. Такой лотерее дыры в ID уже неважны. Но  неравномерность вероятности всё-таки существует и в таком случае. Правда чем больше рядов, тем она незначительней, но тем больше места занимают эти лишние данные.

ALTER TABLE mytable ADD myrand DOUBLE PRECISION; --добавляем колонку UPDATE mytable SET myrand = RANDOM(); --очень медленная процедура ALTER TABLE mytable ALTER myrand SET NOT NULL DEFAULT RANDOM(); --ставим случайное значение для новых рядов по умолчанию SELECT * FROM mytable WHERE myrand >= (SELECT RANDOM() OFFSET 0) ORDER BY myrand ASC LIMIT 1;

Горст и грабен

Ещё простое решение - использовать случайный OFFSET. Сразу минус - LIMIT конструкция не позволяет динамически задавать значения, но образно идея такая:

SELECT CEIL(RANDOM()*(SELECT COUNT(*) AS cnt FROM mytable)); --получим из базы offset SELECT * FROM quotes LIMIT 1 OFFSET 43600; --и передадим в явном виде в запрос

LIMIT сразу перейдёт к нужному ряду - нет нужды в ID, а значит больше свободы. Единственный вопрос в скорости. Ведь используемая внутри COUNT функция - аггрегирующая, а в Postgre она отличается от обычного счётчика в MySQL. Ко всему прочему, как говорит документация - OFFSET может быть неэффективным в больших базах из-за того, что обработка предыдущих рядов всё-равно происходит.

Теги:

Экспорт данных используя Create View и Aggregate-функции

· 2 мин. чтения

Встала задача экспортирования данных из таблицы Firma в качестве строки. Если бы дело было в одноразовом копировании то проблемы особой и не-было бы - всегда есть клиентские программы, которые экспортируют хоть в Excel, хоть в текстовый файл какие угодно колонки. Но мне необходимо было это сделать при помощи SQL, потому что прямого доступа к live-базе данных у меня нет, а размер таблицы мне неизвестен.

Вход - таблица Firma

IDname
1Google
2Microsoft
Выход - строка
1=>Google;2=>Microsoft

Агрегирующие функции занимаются именно такой задачей - на входе у них массив данных, а на выходе - одно значение. Типичным примером являются функции COUNT, MAX, SUM. Postgre пошла по пути универсальности и позволяет пользователю самому создавать такие функции. Создаём CONCAT функцию:

CREATE AGGREGATE concat (  
BASETYPE = text,
SFUNC = textcat,
STYPE = text,
INITCOND = ''
);

Теперь можно сразу получить строку с данными, но мне нужна сортировка по названию фирмы, но никакие вложенные запросы и ORDER BY этому не помогают:

SELECT CONCAT(name||';') FROM Firma;

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

CREATE VIEW FirmaSorted AS SELECT * FROM Firma ORDER BY name;

Остаётся сделать выборку, в которую я добавлю ещё одно поле, уберу последний символ-разделитель и сделаю UPDATE полученного значения в другую таблицу:

UPDATE tblLists SET strValue=(  
SELECT TRIM(';' FROM (SELECT CONCAT(id||'=>'||name||';') FROM FirmaSorted))
) WHERE strName='companies';

Планирование проекта в MS Project

· 4 мин. чтения

Управление проектом - задача трудная, совмещающая сразу несколько областей - финансовые возможности и потребности нескольких лиц, психологические и знания каждого работника и наконец бизнес-план и технические требования самого проекта. Всю информацию можно писать на коленках, составлять отдельно списки или всё по памяти делать, но в данной статье я знакомлюсь с Microsoft Project - отдельного продукта, не входящего в MS Office.

Сразу оговорюсь, что план, составленный в MS Project очень абстрактный и нужен больше для управляющего проектом и его общения с клиентом/заказчиком чем для программистов. В качестве конкретных задач и ошибок, как правило используется открытые и достаточно простые альтернативы -TracBugzilla

Возраст и день рождения через SELECT

· 1 мин. чтения

Иногда хочется быстро вычислить сколько дней до дня рождения пользователя. Вы все видели это в Одноклассниках и ЖЖ. Это можно делать в запросе например таким образом для mysql 5

SELECT
TIMESTAMPDIFF(YEAR,users.birth_date,NOW()) years_old,
TIMESTAMPDIFF(DAY, NOW(), DATE_ADD(users.birth_date, INTERVAL 1+TIMESTAMPDIFF(YEAR,users.birth_date,NOW()) YEAR)) next_birth_days
FROM users

Нашёл в своём стареньком коде, может кому полезно будет..

Коллега Юра скинул версию для старенькой mysql 4, может это даже лучше:

SELECT
IF(
DATE_ADD(birth_date, INTERVAL (DATE_FORMAT(NOW(),'%Y') - DATE_FORMAT(birth_date,'%Y')) YEAR) > NOW(),
(DATE_FORMAT(NOW(),'%Y') - DATE_FORMAT(birth_date,'%Y')) -1,
(DATE_FORMAT(NOW(),'%Y') - DATE_FORMAT(birth_date,'%Y'))
) as years_old,
DATEDIFF(
DATE_ADD (birth_date, INTERVAL IF(
DATE_ADD(birth_date, INTERVAL (DATE_FORMAT(NOW(),'%Y') - DATE_FORMAT(birth_date,'%Y')) YEAR) > NOW(),
(DATE_FORMAT(NOW(),'%Y') - DATE_FORMAT(birth_date,'%Y')) ,
(DATE_FORMAT(NOW(),'%Y') - DATE_FORMAT(birth_date,'%Y')) + 1
) YEAR ),NOW()) as next_birth_days
FROM users

Стратегический анализ инфосистемы

· 2 мин. чтения

Инфосистема в целом это своего рода кровеносная система организации. Будь то политическая кампания, маленькая фирма или рекламное бюро - везде есть общие составляющие, в которых инфосистема занимает важную роль.

Предмет Infos?steemide Strateegiline Anal??s (IDU0021) в ТТУ преподаётся лектором Mart Roost'ом и практующим Ants Torim'мом. В практической части предполагается что студенты смогут описать инфосистему организации согласно предлагаемым в лекциях условиям.

Описывать инфосистему значит моделировать её, тоесть абстрагироваться от конкретных задач и пописывать в целом, с разных сторон.


В данном предмете предлагается такой костяк для проекта:

  • Деловые процессы (как ИС смотрит глава компании)
    • Области ответсвенности лиц, роли (программисты, аналитики, бухгалтера) (p?devusalad)

      • цели
      • ответсвенности
      • необходимости
      • процессы
      • термины (бизнес-объекты, например "договор")
    • Функциональные подсистемы, департаменты (маркетинг, research&development, финансы) (alls?steemid). Описываются точно так-же все цели, процессы и тп.

    • Регистры, аналоги таблиц баз данных, только без посредтсвенных таблиц связей и ID'шников. Работают по элементарным CRUD -функциям.

      • Практическая реализация. SQL-схема.
      • Связи с подсистемами
      • Концептуальная классовая диаграмма
  • Архитектура технологий (как на ИС смотрит инженер)
  • Развитие организации (как финансисты общаются с технарями)
    • Стратегия и временной план

    • Проекты и оценка рисков

    • Оценки ресурсов

Мы с коллегой решили что проще описать систему небольшой фирмы, занимающейся хостингом. Ролей в такой фирме мало - администратор, бухгалтер и глава компании. Единственные данные которыми можно разнообразить UML-диаграммы это регистры договоров с клиентами и счетов. В качестве функциональных диаграмм инетересна разве что процедура оплаты.

На экзамене мы получили двойку, потому что было мало регистров (минимум надо 5), на концептуальной диаграмме стрелки вместо ассоциации были обобщения. На диаграмме процессов было мало действующих ролей и отсутсвовали бизнес-объекты, заносимые в регистры.

Читайте также:

Системные таблицы в базах данных

· 1 мин. чтения

Редко когда приходится делать перечисление всех таблиц, колонок, прав - при разработке это всё делает клиентская программа. Но когда разработка ведётся удалённо и вы не видите разниц в продублированных базах данных в принципе безопасности, то что-бы сдвинуться с мёртвой точки гадания в чём же дело, почему не поступают данные, надо делать элементарные запросы о структуре таблиц и владений привилегиями.

Ключём являются тн. системные таблицы, которые описывают остальные и самих себя. Из-за отсутсвия таких процедур, разные движки реализовали по разному доступ к таким таблицам.

Mysql - отдельный тип запроса. SHOW так-же может показывать состояние БД, нагруженность процессами и тп.

SHOW TABLE status SHOW COLUMNS FROM my_custom_table

Postgre - Иерархия разделена по принципу database.schema.table, поэтому часто администраторы не любят создавать новые базы данных - для них каждый раз дублируются системные схемы pg_catalog и information_schema.

select table_name, table_schema from information_schema.tables //все таблицы select column_name from information_schema.columns WHERE table_name='columns' // замкнутый круг

Oracle - обычные таблицы, которые правда мало кто может просто так взять и поменять

select * from ALL_TABLES ``select * from USER_TABLES

Mysql rownum

· 1 мин. чтения

вторник, 1 января 2008 г. в 22:40:38

Есть таблица меню в БД с полем порядка order_id, но порядок неправильный и надо порядок обновить по алфавиту другого поля title. Сортировка по полю title исключается, потому что таблица представляет из себя иерархическое меню, где порядок может менять пользователь устанавливая order_id. Использовать отдельно серверную обработку (php) тоже невыгодно - лишнее разделение бизнес логики если это можно сделать в БД, да и на случай больших объемов данных это займёт больше ресурсов.

Решение

В MySQL к сожалению отсутсвует такая возможность ROWNUM, RANK(), ROW_NUMBER() как в ORACLE или MSSQL. Присутсвие _rowid никак не влияет на ситуацию. В нашем случае можно использовать переменные, введённые с пятой версии (или раньше):

SET @rank=0; SELECT @rank:=@rank+1 AS rank, id FROM menu;

Для обновления такой таблицы через саму себя у меня не получилось, поэтому я просто скопировал таблицу под другим именем и выполнил такой запрос:

SET @rank=0;  
UPDATE `menu` SET order_id=(
SELECT @rank:=@rank+1 FROM `menu2` WHERE `menu`.id=`menu2`.id LIMIT 1
) WHERE parentID=0 ORDER BY `title` ASC;

EDC

· 7 мин. чтения

Интерес к апокалипсису (ок, апокалипсис буквально это "откровение", так что правильней - армегеддон) концу света всё больше и больше проявляется в американской культуре и мировоззрении. Теперь всё научно обосновывается как риски и неизбежность. Увеличивающиеся энергетические, экологические, террористические и духовные проблемы человечества. Я уже написал про причины, теперь попробую систематизировать решения

Если надо добраться быстро - иди сам,
если надо идти далеко - идём вместе
Африканская поговорка

Видео и mp3 в своём блоге

· 3 мин. чтения

Чем профессиональней становится web-ресурс тем больше необходимость использовать собственных технологий, или по крайней мере своего стиля. Применимо к видео и аудио это значит что внешний вид, функциональность и хостинг - не от youtube/rutube/vimeo а свой. Особенно это заметно когда у вас 500 статей и у большинства - ролики с ютуба, и можно с высокой долей вероятности утверждать что несколько из них уже не работают потому что автор или ютуб их удалил.

Поэтому преимущества держать файл у себя и показывать в своём плеере:

  • правовую независимость и надёжность неудаляемости роликов
  • инновативность, например показ только собственных связанных видео или HD-канал
  • удержание аудитории от публичного сервиса
  • свой дизайн и стиль плеера

В качестве примера таких решений в рунете можно привести ТНТ и Absolute Games.


Аудио-плеер

Для mp3 есть JW MP3 Player и Macloo player, оба на flash естественно. Второй мне особенно показался симпатичным, отчасти из-за его схожести с используемом в сервисе boomp3. Код достаточно простой - в качестве параметра передаётся URL источника. В своём блоге я уже прикрутил - смотрите ниже, как и поиск по эстонско-русскому словарику, но это не в тему. Так что подумайте о ведении подкастинга или видео-кастинга. Уникальность содержимого очень ценится. Есть ещё dewplayer.

Для того что-бы встроить такой элемент в rss 2.0 надо вставить внутрь item-блока примерно такой код

<enclosure url="http://kurapov.name/pathkrasivosleva.mp3" length="7332316" type="audio/mpeg" />

Видео-плеер

Появление flv-видео значительно укрепило перспективы flash. И хотя для этого надо конвертировать стандартные форматы (avi, mov, mpg) с помощью ffmpeg в качестве консоли на стороне сервера и могут возникнуть проблемы с кодеками, размер и удобство стало очевидным.

Некоторые из плееров
Spring playerHD, поточность, есть поддержка MOV и MP4
flv-mp3.comНикита для wordpress советует
Flowplayerнемножко игрушечный
JW FLV Playerдостаточно заезженный
FLV-playerслишком примитивный
uppodочень схож с flv-mp3
xmoovс лишними иконками
Sonneticc HD, немного игрушечный
Agriyaплатный
AS-Flash Media playerплатный, отличный скин
Proxus FLV component

Сложность возникает с перемоткой, буфферизацией и тп. Здесь нельзя обойтись без возможности сервера в поточной раздаче (streaming), т.е. с подстраиванием под возможности клиента. Для этого нужны специальные серверные программы типа xmoovStream и mammoth server. По этой теме советую послушать Андрея Смирнова на РИТ 2007, где он советует модуль для nginx lighttpd. Теоретически конвертация из командной строки должна выглядеть так..

ffmpeg -i movie.[avi] -s 320x240 -ar 44100 -r 12 movie.flv cat movie.flv | flvtool2 -U stdin movie.flv

Подробней о конверторах смотрите:

Будущее

Если основная функциональность имеется, то во многих видео-сайтах уже прослеживаются инновации типа

  • HD-разрешение
  • субтитров
  • слоёв, зависящих от времени
  • комментариев, зависящих от времени
  • geo-tagging
  • поиск лиц
  • полный 360° обзор со специальной камерой

По теме читайте также:

Межтабличный UPDATE

· 1 мин. чтения

Редко когда, но всё же приходится делать в базе данных одиночные запросы по перемещению существующих данных из одной таблицы в другую. И если с добавлением рядов используя INSERT проблем возникает мало, то с обновлением существующих таблиц у меня возникла трудность. А именно - была старая таблица Invision Powerboard форума, и имелась новая таблица пользователей, с одинаковыми пользователями.

Хотелось перенести поля из одной таблицы в другую. В самом худшем случае можно было написать цикл в php, где ряд за рядом делался бы одиночный UPDATE. Но поскольку лень - лучшая мотивация человечества к прогрессу, то по принципу наименьшего сопротивления пришлось обойтись таким запросом..

UPDATE sys_users  
SET avatar = ( SELECT ibf_members.avatar
                            FROM ibf_members
                            WHERE sys_users.login = ibf_members.name LIMIT 0,1)
WHERE EXISTS ( SELECT 1
                                FROM ibf_members
                                WHERE sys_users.login = ibf_members.name )

Если интересно, то EXISTS выражение нужно только для возможности использования подзапроса, связывающего обе таблицы, раз уж в обычном UPDATE нельзя использовать несколько таблиц, единица это первое поле, а LIMIT нужен на случай дубликатов.

Call of Duty 4

· 2 мин. чтения

Игра позиционируется как стрелялка для взрослых. И дело вовсе не в количестве насилия и крови выливающейся из врагов, а в диалогах и сценарии. Сценарий предсказуемый но далеко не фантастический. Альтернативная история - Россия погрязла в гражданской войне, арабский революционер Аль-асад получает ядерную боеголовку в свои руки. В игре нет конкретного героя, игра идёт за конкретного человека в зависимости от истории. Вот десант захватывает судно в поиске следов, вот спасает шпиона, вот высаживается в Узбекистане, переносимся в прошлое и смотрим на Припять, обстреливаем с вертолёта террористов. Прям как в фильме, подумал я до того как меня, президента арабской страны, престрелил перед камерой Аль-асад.

Alter sequence

· 1 мин. чтения

Обычно в Postgre последовательности (sequence) обновляются естественно, но как и в случае с дупликатами, порой иногда хочется одним запросом восстановить правильный максимум .. Сначала я подумал что сработает обычный под-запрос типа

ALTER SEQUENCE sysusers_id_seq RESTART SELECT MAX(id)+1 FROM sysusers ; 

Но как оказалось, последовательности обновлять можно либо статичным рестартом, либо такой функцией.. 

SELECT setval('sysusers_id_seq', (select max(id)+1 from sysusers))+1;

Теперь можно просто продублировать этот запрос для разных таблиц и последовательностей и беззаботно продолжать работу..

AddHandler в Visual Basic 2005

· 2 мин. чтения

С Visual Basic мне пришлось столкнуться по учёбе, и именно по невизуальной его части - создание элементов форм динамически (в цикле) с частично ограниченным числом оных элементов. Задание в общем звучит невинно - создать программу (автомобильного) теста.

Для упрощённого решения, все данные лежат в открытом виде в текстовом файле. Пользователю надо показать форму с вопросами. По умолчанию пользователь вводит сам ответ в TextBox компоненты, что даёт ему 3 очка за правильное решение. Если нажать на вопрос, то TextBox прячется и пользователь выбирает из предлагаемых вариантов.

Честно говоря самое сложное это вовсе не чтение из файла, а привязка создаваемых объектов с событиями (Events)

Dim resFile As IO.StreamReader Dim Row As String Dim line As Integer resFile = New IO.StreamReader("Valuutad.txt") Do line = line + 1 If resFile.EndOfStream Then Exit Do Row = resFile.ReadLine Me.AddQ(line, Row) Loop resFile.Close()

Сначала я нашёл такой кусок кода как AddHandler objLabel.Click, AddressOf Labelx_Click и решил что неплохо бы передать вместе с этим параметры EventArgs. Не тут то было, оказалось что VB делали такие перцы, логика которых с моей не совпадала вовсе, и которые наделали в VB тучу возможностей которыми я даже и не задумывался пользоваться..

Как оказалось, третьи примеры кода следовали всё тому же AddHandler, но уникальность того, что за кнопка из сотни кнопок была нажата брали из ActiveControl.Text! Это всё равно что баловаться фокусом в среде где фокус легко может отбираться или вообще не присваиваться, как это у меня с Label и происходило. Просто взять и добавить в объект новый параметр ID и по нему найти объект обратно, подобно getElementById в Javascript, тоже задача не из лёгких - надо тогда делать новый класс и наследовать контрол.. дебри.

Программу спас параметр Tag и занесение объектов в массив.

Две lan карты одновременно

· 2 мин. чтения

Вчера мне провели кабельный интернет и оказалось что теперь у меня старое wifi соединение с хорошим upload каналом но низким ping-ом, и кабель с хорошим ping-ом, но низким upload. Ясное дело - два канала, работает только один, так почему же второму пропадать?

В более общем случае люди конечно хотели бы по максимому использовать оба шлюза (gateway) для получения суммарных скоростей, если бы не различие в IP. Обычно такую задачу перекладывают на рутер, который сам думает какой пакет кинуть по какому шлюзу что-бы ничего не потерялось, но в Windows есть и встроенный инструмент маршрутизации - комманда route.

Проблема лишь в том что она прописывает шлюзы для IP конкретных получателей, что очень полезно при статичных VPN, но в моём случае она бесполезна, поскольку по wifi я хотел бы иметь доступ ко всему спектру IP. Но сузив рамки, я решил что по wifi имеет смысл пустить только mail сервак и задача сводится к маршрутизации пакетов в зависимости от используемых портов (110,25,995).

Для такой перенастройки маршрутизации я попробовал:

  • wipfw, портирование из freeBSD
  • kerio winroute, вместе с уймой настроек, firewall, traffic quotas и тп. Даже основная фича по транслирование сетевых адрессов (NAT) не помогла ником образом
  • Netcom Routix по идее очень навороченная прога, позволяющая даже изменять модули маршрутизации по своему усмотрению, если есть знания в Visual Basic.

Предложения заблокировать порты на одном шлюзе с мыслью что они сами побегут на другой - не получилось. Копания в течение суток я понял что data layer и network layer в windows очень слаб, даже несмотря на присутсвие третьих программ. Надеюсь кто-нибудь найдёт решение кроме как установки второго компа.

Удаление дубликатов в Mysql

· 1 мин. чтения

Очень часто всплывает тема поиска дубликатов в таблицах, особенно когда надо установить UNIQUE constraint. Всегда можно обойтись таким запросом..

SELECT login, COUNT(login) AS cnt
FROM sys_users GROUP BY login
HAVING ( COUNT(login) > 1 )

И теперь..

DELETE t1 FROM sys_users t1, sys_users t2 
WHERE t1.login=t2.login AND t1.ID > t2.ID

Ещё один красивый и лаконичный способ..

ALTER IGNORE TABLE sys_users ADD UNIQUE INDEX(login);

Читайте также:

Crysis

· 1 мин. чтения

Crysis, ожидаемый ещё с весны выпустил демку, в которую я с удовольствием порубился. Новый движок cryengine творит чудеса, не нагружая сильно процессор, а cюжет не срывается до уровня ужасов Bioshock, покрайней мере в начале

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

Пингуем technorati и feedburner по XML-RPC

· 2 мин. чтения

Я уже писал про XML-RPC и использование его с livejournal.

Месяца 4 назад я зарегистрировался для продвижения блога наtechnorati - англоязычном аналоге яндекс.блогов, но обнаружил отсутсвие обновления. Как оказалось, всё дело в том что technorati пошло как раз по тому пути о котором я говорил чуть ранее про Google.

XFN и FOAF

· 3 мин. чтения

Не основываясь ни на чём я могу сказать что 40% читаемых мною блогов обращают какое-либо внимание на шумиху Web 2.0, 4% из них задумываются о будующем web 3.0, о семантике и только единицы реально изучают микроформаты и пытаются об этом писать.

FOAF это практическое применение формата семантики RDF, а цель раскрывает значение этого сокращения - друг моего друга, т.е. формат связей некоего блога или ресурса с другими. Документация и весь формат разрабатывался с 2000 года и с того времени завоевал популярность в основном среди прогрессивных web-разработчиков.

XFN это микроформат проще реализующий смысл FOAF, технически в виде отношения многое к многим как и тэги. Отвечает стандартам XHTML,и всё что от вас требуется так это добавить параметр rel='friend' в каждую ссылку из списка. Параметр может быть не только friend, но и другим отвечать значениям - см. XFN 1.1. creator. А что-бы показать всем пример и выпендиться, можно использовать иконки.

Цель и перспективы

  1. Децентрализованная сетка друзей. Заходите на любую социальную сеть, регистрируетесь, находите друзей, и объединяете всех в один список. Для этого надо, что-бы популярные сервисы поддерживали формат FOAF. И некоторые уже это делают - LivejournalLiveinternet.

  2. Поиск по сетке. Вообще поиск по людям в интернете отсутсвует, чего бы не писала seobaby. Всему причина как я уже писал, политика конфиденциальности. Конечно вы можете попробовать умерший поисковик Rubhub. Mindsack.com предлагает создать список в виде JSON, и прыгаеть с одного списка на другой.

  3. Визуализация. Построить граф всея интернета хочет разве что параноик-детектив, но видеть нечто отличное от текстовых списков всегда приятно, особенно когда в качестве узлов выступают фотки знакомых людей. Однако достаточно взглянуть на граф от six apart что-бы понять что графы неудобны. Можно использовать xfngraph.

Работы

  • Для работы с XFN Дима Джус например уже нахимичил паука с такими аббревиатурами как XSLT, Python, tidy.
  • Oliver Brown наваял неудачно какой-то географический проект с отображением друзей.
  • Дикий попробовал mindsack и даже Бишопа с Флинтом подключил до момента перезапуска блога последним.
  • Optimus конвертит XFN в нужный xml или json.

Якобы вывод

FOAF и XFN это всего лишь "фича" блогеров, которая предоставляет данные тем кто их понимает (поисковикам и программам) и если он наберёт популярность, то его будут учитывать большие игроки... например livejournal уже учитывает. Но для коммерческих систем естественно такой формат для услуг не нужен. Тем временем можно занять нишу rubhub, хитро скомбинировать это с блогами и сделать подобие blogowar , Дима ты меня слышишь?

В заключение можно заметить, что на протяжение всей истории интернет-поиска, крупные поисковики никак не пытались повлиять и навязать форматы данных которые сайт должен показывать. Sitemap, favicon, robots.txt, meta и headers не в счёт. Когда же появятся "Google рекомендует"?

Система прав в инфосистемах

· 4 мин. чтения

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

Управление СУБД

· 1 мин. чтения

С СУБД сталкивается практически каждый разработчик, начиная как правило с PhpMyAdmin, PhpPgAdmin, простейших серверных скриптов, постепенно переходя на более тяжёлое но удобное ПО, которое я тут постараюсь описать.

Maestro group

SQL Maestro это компания, производящая административные программы баз данных. Практическая реализация очень схожа с SQLyog, т.е. так же позволяет легко управлять таблицами, данными, базами, схемами, функциями, тригеррами и тп. В плюс - возможность составление диаграммы структур. В комплекте есть поддержка MySQL, Postgre, Oracle, MS SQL server, Firebird, Max DB. В последних версиях есть HTTP-туннелирование. В минусы - порой выпадают ошибки нехватки памяти.

SQL yog

SQLyog 6 Enterprise стоит 67$, что для фирмы, которая хочет экономить время своих работников, цена приемлимая. Интерфейс построен как и в pgadmin - слева список таблиц с подразделами (поля, индексы, триггеры), справа - данные таблицы и sql запрос. Сверху - меню с удобными диалогами создания FOREIGN KEY, управлением привилегиями, структурой таблиц, возможностями импорта/экспорта и т.п.

См. также

VPN

· 1 мин. чтения

Virtual Private Network это искусственный защищённый канал связи между двумя LAN-сетями использующий протоколы аутидентификации IPSec, PPTP или L2TP и алгоритмы криптографии DES, triple DES, AES.

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

Для обычного пользователя VPN-туннель просто создаёт второй сетевой интерфейс и как результат - второй IP, который доступен из второй сети. Благодаря этому все остальные программы и протоколы (SVN, FTP, SMTP) могут использовать ресурсы корпоративной сети. Это в корне увеличивает возможности пользователя по сравнению с использованием SSH-туннелирования, которое часто исопльзуется для защищённой передачи данных (через WinSCP и Putty)

VPN-соединение устанавливается программами:

Как побочный эффект от соединения, вы можете заметить что пропал доступ к интернету - ваш gateway оказался перенаправленным на VPN'овский интерфейс. И наоборот, внутри внутренней сети нельзя пользоваться глобальным DNS.

Если возникает ошибка ROUTE, то можно создать .bat файлик и прописать туда нужные пути таким образом..

route ADD 10.138.12.4 MASK 255.255.255.255 10.138.11.109

Синхронизация Google Calendar c MS Outlook

· 1 мин. чтения

Синхронизируем Outlook и Google calendar. Самый недавно вышедший и простой способ - Google Calendar Sync.

Iframe

Для начала самый простой и не настоящий способ. Идём в Outlook под Calendar слайд, и под "My Calendars" жмём правой кнопкой по нужному календарю, ставим на нём Properties->Home Page->Address равным http://www.google.com/calendar/render. Браво, теперь у вас iframe вместо настоящего календарика.

Plug-in RemoteCalendars

  1. Закрываем Outlook
  2. Устанавливаем NET 2.0
  3. Устанавливаем RemoteCalendars (включая файлы O2003PIA.EXE, O2003PIA.MSI, vstor.exe, RemoteCalendarsVSTOSetup.msi)
  4. Открываем Outlook, ставим во вдруг появившемся окошке настроек временную зону и Auto Update.
  5. Видим такую панельку
  6. Добавляем новый календарь. Для этого берём из Google Calendar настроек ссылку . После этого - вводим логин пароль, и вуаля - двусторонняя синхронизация есть.

Читайте также:

RSS generator

· 1 мин. чтения

Все знают про RSS и то как это читать и даже парсить , но как переделать из html-кода статью в валидный RSS для веб-разработчика может быть проблематично.

К типичным проблемам можно отнести присутсвие символов <, >, &. Кроме того сложности с присутсвием тэгов object внутри description приводят к тому что сделать видео объект в rss нельзя.

Пробуем FeedCreator. Громадина, поддерживает всевозможные ATOM, RSS 0.9-RSS 2.0, OPML, MBOX. Надо вручную менять на UTF8 кодировку, объект хочет сразу создать xml файл. Хорошо, это в принципе разумно, кэширование в один час для блога не критично, для новостных сайтов надо уменьшать до пары минут.

$rss = new UniversalFeedCreator();  
$rss->useCached();
$rss->title = "Artjom Kurapov";
$rss->description = "Personal Blog";
$rss->link = "http://kurapov.name/";

Валидатор всё равно ругается на flash (следовательно object не поддерживается) . Кроме того не нравятся относительные пути. Конешно можно изменить WYSIWYG что-бы он сразу генерировал абсолютные пути, но в случае если надо будет менять домен прийдётся много с базой работать. Поэтому мы их генерируем вместе с RSS.

$recEntry->description=preg_replace("//i",'',$recEntry->description);  
$recEntry->description=str_replace("href='/","href='http://kurapov.name/",$recEntry->description);
$recEntry->description=str_replace('href="/','href="http://kurapov.name/',$recEntry->description);
$recEntry->date = date('r',$item->unix_added);
$rss->addItem($recEntry);
echo $rss->saveFeed("RSS2.0", "feed.xml");

И в результате
[Valid RSS]

Шифр Брайля

· 1 мин. чтения

Нет, это не шифр инопланетян, хотя достаточно любопытный, не правда ли? Способы кодирования информации, и криптографии создавались с древнейших времён, но для данный код носит имя француза Брайля и изначально разрабатывался для военных целей для общения ночью в полной тишине, но для обычных солдат это оказалось слишком сложным

Сейчас транскрипцию шифра Брайля используют не только для печати книг для слепых но и для чтения с экранов компьютера. Из-за ограничения размера "буквы" всего существует 26=64 символа. Интересно такой интерфейс как прототип предлагается использовать и на специальных мобильных телефонах, часах

Выбираем полу-профессиональный фотоаппарат

· 3 мин. чтения

Фотоаппарат, впрочем как и практически любой товар оценивается по многим параметрам, поэтому что-бы детально не расписывать эту сложнейшую аппаратуру приведу самые важные характеристики:

  1. Светосила или отношение чувствительности темноты к выдержке.
    Чем больше светосила, тем больше свободы съемки в ночное время (по шкале ISO) и больше свободы при съемке движущихся предметов (в секундах). Всё это вытекает из зависимости между выдержкой, экспозицией как результат - яркостью картины.
    • 2.0-2.8 профессиональные объективы, тоесть при минимальной и максимальной выдержке яркости будут 2@1/2000 с и 2.8 @ 1/300с
    • 2.8-5 оптика на любителя
  2. Фокусное расстояние объектива.
    • 10-28мм - макросъемка
    • 28-35мм - широкоугольные
    • 50мм - нормальные (человеческий глаз)
    • 80-100мм - портретные
    • 100-300мм - длинно фокусныеОбъективы с меняющимся фокусным расстоянием, т.е. с zoom-возможностью имеют свои пределы. Скажем 50 мм - человеческий глаз, то около 10 мм это уже макро-съемка, а 200мм это уже природа и ландшафт.
  3. Размер матрицы и уровень шума. Из маркетинговых соображений зачастую уровень шума при высоких экспозициях приносится в жертву ради большей матрицы. Если кто-то интересуется что такое шум - сделайте Filter Noise в фотошопе и поймёте.
  4. Класс. В зависимости от требуемых функций фотоаппараты делятся на профессиональные зеркалки, компактные мыльницы и что-то по середине.

Поскольку у меня уже был опыт с мыльницами от Mustek и Olympus C-310, хотелось не столько компактности, сколько качества и оптики. В то же время я не хотел дорогих и строгих профессиональных зеркалок, где видео режима нет. Поэтому выбор пал на "продвинутые незеркалки". Из этого класса на этот момент были

Sony Cyber-shot DSC-H9 Sony Cyber-shot DSC-H9/H7Olympus SP-550 Ultra Zoom Olympus SP-550 Ultra ZoomCanon PowerShot S5 IS Canon PowerShot S5 ISFuji FinePix S6500fd Fuji FinePix S6500fd
- 7990 EEK- 8.1 MP- ISO 3200- AVI- 2.2 к/с- 7690 EEK- 7.1 MP- ISO 5000- RAW- 7690 EEK- 8 MP- ISO 1600- 7250 EEK- 6 MP- ISO 3200- RAW,AVI

Как можно заметить - все умеют записывать видео. Заявленные ISO 5000 у Olympus мало что дают, а отсутсвие USB 2.0 и аскетизм в дизайне только усугубляют положение.

Проблема с Sony - даже если вместо H9 взять практически аналогичную H7 и сэкономить тысячу, то всё-равно можно остаться недовольным отсутсвием AA-батарей и малым циклом аккумулятора - у Canon в два раза больше энергии, и хотя экран пожалуй самый больший из перечисленных, это сказывается также на эргономике - никаких дополнительных кнопок нет.

Про Fuji можно отметить что хотя оптика и хороша, как и в Sony, но матрица меньше, да и процессор старше - нет стабилизатора.

Как вы уже догадались - я выбрал Canon, отчасти и из-за брэнда. Оптика - 36 - 432 mm с F2,7-3,5. Главное преимущество - стабилизатор, видео со стереозвуком, крутящийся дисплей. Пальчиковые батарейки, встроенная вспышка, USB2. В минусы - отсутсвует RAW, хлюпкая крышка объектива. Нет предела человеческой глупости, решившего что искомое найдено - купил в fotoluks и только потом увидел в hinnavaatlus цену на тысячу меньше. Всем советую :)

Магазины в Эстонии - photopointfotoluks.
Обзоры: zoom.

Соединяем блог и Livejournal через XML-RPC

· 2 мин. чтения

XML remote procedure call на самом деле очень простая процедура, при помощи которой я теперь могу писать в своём блоге и копировать статью в livejournal.

С виду, самым простым решением вероятно выглядело бы создание такого процесса, где передача данных на сервер LJ происходил бы браузером. Достаточно создать отдельный iframe, в него поместить форму, в которую копировать содержание из другой формы и в итоге публиковать в LJ. Но - во первых это уродливо, во вторых не факт что так можно исхитриться.

Презентация к диплому

· 2 мин. чтения

Защита диплома в ТТУ дело обыкновенное - достаточно сделать презентацию на 15 минут о том какая проблема решалась. Ввиду специфики области (академическая защита) и ограниченность по времени (всё идёт как по конвейеру), надо постараться выжать самый концентрат сока.

В общем надо ответить на три вопроса

  1. Какая проблема?
  2. На каких теоретических и практических исследованиях работа основывалась, есть ли соавторы
  3. Какие получены новые результаты и какие последствия открываются для будующего поколения учёных

Если презентация делается на 15 минут, то надо не более 15 слайдов где по минимуму будет содержание. Помните, что вы не энциклопедию передаёте поколению, а делаете для себя визуальную помощь. Заранее скажите как вы будете отвечать на вопросы (сразу или в конце).

Календарь на PHP, MySQL и ajax

· 2 мин. чтения

Для корпоративных сайтов зачастую нужен календарь. И ладно бы что-бы он просто показывал дни недели, так зачастую вносится понятие События (Event), а ввиду обширного потенциала этого понятия можно говорить об Event Management System. Поскольку деловым людям свойственно планирование, то такая система должна быть удобной, мобильной и расширяемой. За удобство отвачает ajax, за мобильность - само наличие интернета, а за расширяемость - программист и проектировщик.

А ведь событие ещё может иметь и..

  • повторяемость (с определённым периодом , до бесконечности/определённого числа повторений/конкретной даты )

  • местоположение (для точного - google maps, для неточного - просто текст)

  • привязку к временной зоне

  • неопределённое время или длительность (идёт в todo список?)

  • принадлежать группам или типам событий (деловые встречи, личные встречи, культурные мероприятия)

  • доступ к просмотру для других пользователей (sharing, оповещение)

  • систему оповещения по email/sms/desktop widget


Публичные сервисы

На рынке сейчас есть передовые услуги не только с возможностью хранения всей информации, но и с синхронизацией устройств, приглашением других участников и тп.

Opensource-продукты

Когда дело касается своего сайта, то выбор значительно уже:

  • PlansCalendar на php/mysql, без ajax и видов по дням/неделям

  • phpiCalendar внешне обманчив - работает на файловой системе с .ics файлами

  • monket хоть и на ajax, но скуден

  • thyme платен и по сути чуть лучше чем PlansCalendar

  • jquery fullcalendar - оболочка без серверной части

  • jquery wdcalendar

  • myCalendar

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

На будущее разработчикам - на забудьте что календарь должен быть интегрируем, экспортируем в outlook, ical микроформат , удобен и расширяем.