Archive for the ‘oracle’ Category

Oracle, JDeveloper и PL/SQL

Август 10, 2008

Так уж получилось, что я решил чуть-чуть сместить фокус своей девелоперской деятельности в сторону Oracle PL/SQL. Нет, мне совершенно не надоел веб, просто у меня есть свой проект Smart Masses, который представляет собой магазин для гиков и сочувствующих имени доктора Жаба, и мне его более чем достаточно для экспериментов.
А учитывая, что в конторе, где я работаю всегда есть возможность выбора проекта, я решил «прокачать» знания по sql и pl/sql, с которым до этого не работал. Для начала оформил себе оракловые курсы по банальному sql и уложил все знания в систему =) Учиться понравилось. Вчера съездил в Олимпийский и закупил литературы по Oracle PL/SQL и немного Тома Кайта для души =)

Сегодня уже установил себе Oracle 10g XE на Ubuntu 8.04 и начал вдумчиво читать литературу и выполнять примеры.

У оракла есть некая IDE с незамысловатым названием JDeveloper. Не то, чтобы я горю желанием изучить ещё одну IDE, но посмотреть на неё захотелось. Ставиться она не без бубна, но официального руководства вполне достаточно. Единственная проблема возникает, когда пытаешься законнектиться к базе из неё. Проблема выражается двумя ошибками:


ORA-00604: error occurred at recursive SQL level 1
ORA-12705: Cannot access NLS data files or invalid environment specified

И ничего не признает. Выставление параметра NLS_LANG в профиле баша ничего не дает. После многочисленных расследований и поисков в гугле решение было найдено. В файл jdev.conf необходимо добавить пару строк:

AddVMOption -Duser.language=en
AddVMOption -Duser.region=us

Оказывается Ынтырпрайз Жава не очень признает всякие NLS_LANG и берет параметры прямо из среды обитания. И эти параметры оказываются неверными. Этот «хак» подходит для любых IDE, написанных на этом чудесном кросс-платформенном языке и использующихся для разработки под Oracle.

И вот ещё одна ссылка по которой можно почитать чуть более объемное описание проблемы и способы её решения. Отличный статья, рекомендую.

…тем же вечером…

Продолжая копать в нужном направлении, нарвался на SqlDeveloper, выпускаемый Oracle. Который не несет в себе столько уг, как jDeveloper. При установке был капризен и требовал путей к jvm, не смотря на то, что она была прописана в PATH. Ещё пытался (неудачно) создавать файл jdk в дирректории ~/.sqldeveloper/ и писать туда этот самый путь, чтобы не спрашивать каждый раз при старте. Но что-то у него не задавалось. Пришлось создать ему этот файлик, раздать на него 777 (на всякий случай =) и вот тогда, он туда уже всё написал.

Ну и баг NLS data files лечился тем же способом. В sqldeveloper.conf добавились те же магические строки =) Вот такой вот он…ЫнтЫрпрайз.

ExtJs. Многостраничный грид с фильтром и поиском. Часть 1.

Январь 23, 2008

Просматривая статистику поискового трафика, любезно предоставленную мне feedburner’ом, я замечаю, что основная масса трафика идет на тему ExtJS. Мне не совсем понятен этот момент 😉 Обычно, когда мне что-то надо узнать по ExtJs, я двигаю на их форум. Потому что именно там собрана вся информация, которая вообще может пригодиться (после документации, конечно). В гугле я ищу только конкретные ошибки, которые выдает мне FireBug. Потому что поисковая система форума далека от идеала.

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

Работая с ещё с ExtJS 1.1, я нашел замечательный топик, в котором рассказывалось о подобном гриде. И приводился замечательный пример. В этом примере всё отлично. Но он написан на первой версии и использует в качестве бэк-энда python. В этой серии туториалов я опишу создание такого же грида, с использованием ExtJS 2.0, php5 и Oracle (для MySQL будут приведены примеры запросов, не сильно отличающиеся от ораклинских).

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

Итак. Наш грид будет состоять из:

  • grid.html — html-файл, содержащий разметку страницы
  • grid_data.php — файл, обслуживающий запросы к БД со стороны грида
  • grid.js — js-файл, содержащий основной код приложения

Архитектура будет банальной. Наш грид посредством AJAX-запросов, будет обращаться к php-файлику и тот будет передавать ему данные в формате JSON. Запросы к БД будут всего двух типов:

  • Запрос очередной страницы с данными
  • Поисковый запрос

Для простоты демонстрации, не будем сильно усложнять поиск и обойдемся LIKE. Но никто не мешает реализовать сложную поисковую логику. Просто это выходит за рамки этой серии статей. Ну а постраничная разбивка — это совсем просто (хотя на Oracle — чуть сложнее)

На сегодня всё. Stay on line.

Постраничная разбивка с Oracle.

Ноябрь 19, 2007

Ни для кого не секрет, что Oracle — это труЪ =) Но когда я «проапгрэйдился» на проекте до него с MySQL, то я не нашел там привычного сердцу LIMIT 0, 20 и расстроился. Как же так. Самая лучшая БД, а такой полезной функции нет.

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

В приведенном решении меня не устраивало 3 вещи:

  1. Для подсчета строк надо делать отдельный запрос
  2. Глючит при хитрых ORDER BY
  3. DBA сказал «мутная весчь этот rownum» =)

Решение было найдено довольно быстро. И оно было избавлено от всех 3х недостатков. Вместо «мутного» rownum была применена функция row_number(), которая дала нужный результат. Плюс доработав запрос, я получил в нем и колличество строк. Правда оно пишется в каждой строке ответа, но нам же оно нужно для постраничной разбивки, поэтому заботиться о количестве данных, передаваемых по сети не стоит. Вот готовый рецепт:

select * from (
select ROW_NUMBER() over(order by req.requests_date desc) as r,
count(tab.id) over() as total,
from table tab,
where tab.column = 'value'
) x
where x.r between '" . ($start + 1) . "' and '" . ($start + $limit) . "'

Ссылка на документацию по Oracle может внести дополнительную ясность, от себя добавлю лишь, что в over() пишем все ORDER BY, $start и $limit это с чего начинать(начинаем с 0) и на чем остановиться (передается количество записей на страницу). count() должен применяться на unique поле (что характерно ;). Вот, в принципе, всё. Если остаются вопросы или предложения по оптимизации — прошу в комменты.

Сага про Solaris 5.9, Oracle 10 и PHP 5.2.3.

Август 14, 2007

Эта история является продолжением работы над славным и большим проектом. В честь которого я уже копал LDAP.

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

Решив, что скоро у меня будет свой серер под Solaris’ом, я продолжил ковырять LDAP и успел реализовать неплохую авторизацию. Правда с использованием mod_auth_sspi.so, который умеет крутиться только на виндовых серверах. А у меня будет Solaris. Но простота реализации мне очень понравилась.

Ждать пришлось не очень долго, и скоро мне прислали логин, пароль, имя сервера и имя папки. Подобное письмо вызвало у меня ряд вопросов. И меня отправили к специалисту. Специалист объяснил мне, чем коннектиться к серверу по SFTP (WinSCP) и показал как пользоваться PuTTY. Он же сказал мне, что root мне никогда не дадут, свой сервер тоже, и что он поднимал Apache с PHP под простой (не рутовой) учетной записью, и всё было номрально.

Так мне пришлось заняться чрезвычайно интересной задачей по поднятию сервера в маленькой локальной папочке на сервере под Solaris 5.9, где нет вообще ничего.
Если искать в инете книги по Solaris, то вы нигде не найдете в них способ установки софта без прав админа. Я знаю про сырцы, но у меня не было binutils, g++ и кучи библиотек.

Зато мне рассказали про команду pkgtrans. После прочтения по ней manа, лично мне понятнее не стало. Рассказы о ленте и других потоковых накопитилях совершенно меня расстроили. Но команда оказалась единственной полезной, и если бы не она, мне не удалось бы осуществить задуманное.

Установка софта без прав root

Идем на www.sunfreeware.com (пакеты вообще без расширений) или на www.blastwave.org (пакеты с расширением pkg). Там лежат большие архивы собранного софта. Для кучи версий Solaris’а. Качаем то, что нам нужно, копируем себе в дирректорию (обозначим её для краткости $HOME), распаковываем командой gunzip pack_name распаковываем его. А дальше вступает pkgtrans. В той же дирректории пишем
pkgtrans pack_name pack/
Эта комманда распакует наш пакет в поддиректорию $HOME/pack/SMCpack_name или pack/CSWpack_name, в зависимости от того, откуда качали файл.
Теперь у нас есть автомат. Т.е. скомпилированный софт. Т.е. хотя бы gcc =).

Сборка софта для сборки сервера.

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

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

Итак, у меня есть работающий GCC, т.е. оба компилятора и для C и для C++. Это уже хорошо. Теперь можно собрать binutils, в которых присутствуют необходимые для сборки инструменты. Единственный параметр, с которым я собирал был —prefix=/u01/users/php/tools. Т.е. я просил установить всё в папку tools, где у меня со временем образовалось почти полное дерево системы. Таким образом, собирая все инструменты в эту папку, я избавил себя от необходимости прописывать десятки путей в свой .profile. Важно прописать пути к этой папке до основных путей системы. Т.е. при задании переменных окружения надо писать export PATH=/u01/users/php/tools:$PATH.

После binutils, установим пакеты bison, flex, gawk, m4, make (все есть на gnu.org, кроме flex, он живет на flex.sourceforge.net). Эти пакеты необходимо собирать с тем же префиксом, что и binutils. Они собираются без проблем, насколько я помню. Чтобы понять что использует ваша система, когды вы говорите ей, допустим make, стоит набрать which make, и получите путь, откуда этот make запускается. Так стоит проверять, чтобы использовались нужные инструменты.

Сборка Apache 2.0.59

Собрать, как я уже говорил, мне необходимо работающий сервер Apache+PHP и связать его с Oracle. Я начал с Apache. Как с наиболее простого. По каким-то причинам Apache ветки 2.2 у меня собираться отказался. Поэтому я собирал проверенный Apache 2.0.59. Создаем простой файлик, куда пишем полный конфиг, делаем файлику chmod +x, или каждый раз пишем sh apache2_config. Вот содержимое файлика:


cd /u01/users/php/src/httpd-2.0.59
./configure \
—prefix=/u01/users/php/apache2 \
—enable-so \
—enable-mods-shared=’rewrite mime-magic ssl vhost-alias’ \
—disable-cgi \
—disable-autoindex \
—with-mpm=prefork \
—with-ssl=/u01/users/php/openssl \

Модулей не очень много. Для сборки Apache мне пришлось установить только собранный из сырцов OpenSSL. Хотя для сборки PHP, мне пришлось использовать скомпилированный openssl 0.9.7, потому что при сборке с текущим 0.9.8 выпадал ld, который под Solaris не очень стабилен. А заставить ПСС использовать GNU ld мне не удалось. Для этого пришлось бы пересобирать компилятор. Это мне не удалось. Вообщем, с Apache проблем особо не возникло.

Сборка PHP 5.2.3

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


cd /u01/users/php/src/php-5.2.3/
./configure \
—prefix=/u01/users/php/php5 \
—with-apxs2=/u01/users/php/apache2/bin/apxs \
—enable-bcmath \
—enable-calendar \
—enable-exif \
—enable-mbstring \
—enable-soap \
—enable-sockets \
—with-gd=/u01/users/php/tools \
—with-jpeg-dir=/u01/users/php/tools \
—with-png-dir=/u01/users/php/libpng \
—with-iconv \
—with-libxml-dir=/u01/users/php/tools \
—with-xsl=/u01/users/php/tools \
—enable-zip \
—with-zlib \
—with-ldap=/u01/users/php/tools \
—with-openssl=/u01/users/php/pack/SMCosslg/reloc \
—enable-soap \
—with-mcrypt=/u01/users/php/libmcrypt \
—disable-ipv6 \
—with-oci8=instantclient,/u01/users/php/instantclient_10_2 \
—enable-pdo \
—with-pdo-oci=instantclient,/u01/users/php/instantclient_10_2,10.2.0.3 \
—without-pdo-sqlite \
—without-sqlite

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

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

Дальше начинается GD. Для сборки GD, надо сначала собрать libpng (без проблем) и libjpeg. Собрав libjpeg командой ./configure —prefix=/u01/users/php/tools, самое главное на забыть после команды make install, скомандовать make install-lib. Без этого, GD будет конфигурироваться, но не будет собираться (отняло примерно день, решение нашлось на каком-то форуме).Если нужна поддержка ttf или xpm, их тоже надо собирать. Мне они нужны не были. После этого сборка GD проходит гладко, и в конфиге мы указываем его, и пути к библиотекам jpeg и png.

Дальше идет iconv, xml и xslt, для них необходимо собрать библиотеки, соответственно iconv, libxml2 и libxslt. Здесь проблем нет. Не забываем про prefix, иначе make install не пройдет.

Теперь ldap, openssl и mcrypt. LDAP собирается (правда, он у меня попросил Berkeley DB, но это проблемой не считается =)), а вот openssl, как я уже говорил, мне пришлось использовать готовый. Т.к. PHP отказывался делать make, вызывая панику у ld. Это проблема новой версии 0.9.8 и архитектуры SPARC. С mcrypt проблем не было.

И вот начинается самое интересное. Oracle. Достаем мануал The Underground PHP and Oracle® Manual с оракловского сайта. Читаем. Идем на тот же оракловский сайт и качаем instant client под Solaris Sparc. Почему он в zip, я не знаю. Разкатываем архив в нашу папочку. Теперь у нас есть оракловый клиент. С ним-то мы и будем собирать PHP. Это стоило мне где-то трех дней. PHP спокойно конфигурировался с OCI8, но отказывлся конфигурировать PDO_OCI. А он мне был очень нужен. Проблема скрывалась в Sun’овском SH (шелле), который немного отлично ведет себя от обычных. Я решил проблему, прописав в конфигурационном файле #!bin/bash вместо #!bin/sh. У меня всё собралось. Эту проблему обещали исправить в PHP 5.2.4 (Тред по этой проблеме на phpClub).

Соединяемся с Oracle

В принципе на этом проблемы со сборкой закончились. Всё собралось, запустилось и заработало. Не хватало только соединиться с Oracle. Здесь меня тоже ожидали сюрпризы (дня два). Не смотря на всё, что написано в Подземелье ПХП и Оракла, они никак не соединялись. У меня в наличие было два файлика sqlnet.ora и ldap.ora, которые объясняли Ораклу где искать сервер, но не смотря на всякие TNS_ADMIN, Oracke Instant Client не видел сервер. И файлики, видимо тоже. Всё решилось довольно хитро. Обычно, если устанавливать на компьютер обычный оракловый клиент, эти файлики лежат в папочке $ORACLE_HOME/network/admin/. Это и есть ключ. Пришлось в папке instantclietn_10_2, которая жила у меня, сделать эту структуру подпапок. И уже в подпапку admin положить два файлика. И он их нашёл. Я не знаю, зачем так всё сложно. Но мне кажется, что без программерской лени тут не обошлось.

Первый этап саги окончен. Сервер работает. Связь с БД есть. Но что-то мне подсказывает, что пересобирать я буду и Apache и PHP. Тогда, если будет о чем написать — буду дописывать сюда.

Zend Framework 1.0 и Oracle.

Август 3, 2007

На работе надо было связаться с оракловым сервером. Так как я решил поплотнее пообщаться с Zend Framework, было решено соединяться им. К тому же он предоставляет достаточно хороший каркас для создания приложений. И со временем, я думаю, я буду использовать его всё больше.

Ну так вот. Соединился я с базой. И всё, вроде, нормально, если писать запросы руками. Т.е. «SELECT * FROM USER». Но это не очень интересно. Так как ZF предоставляет достаточно классов для работы с базой в более прозрачном режиме. НО! При попытке создать запрос его средствами, я получал ошибку. 942 ORA-00942: table or view does not exist. И дальше шёл странный такой SQL-запрос. Слабо похожий на то, что любит Oracle.

Мне сразу не очень понравились все эти кавычки вокруг имени таблицы и полей. И Ораклу они тоже не нравятся.

В документации я решения проблемы не нашёл. Долго бродил по исходному коду. Безысходно. Спросил у умных. Те объяснили мне, что эти кавычки появляются автоматически и отвечает за это переменная $_autoQuoteIdentifiers в классе Zend_Db_Adapter_Abstract.

Поначалу я на радостях просто выставил ей false, но потом понял, что модификация фреймворка не есть гуд. Потому что проблемы с обновлениями не заставят себя ждать. И тогда мне очередные умные люди объяснили, что надо просто при инициализации подключения надо указать в параметрах опцию ‘options’ => array(Zend_Db::AUTO_QUOTE_IDENTIFIERS => false). И всё будет ок.