понедельник, 31 декабря 2012 г.

Fedora 17 install VirtualBox

Good manual this.

If you find errors in log file:
makefile:181 *** error: unable to find the sources

or:
Trying to register the VirtualBox kernel modules using DKMSError! Bad return status for module build on kernel

Check this packages in you system:
binutils
gcc
make
patch
libgomp
glibc-headers
glibc-devel
kernel-headers
kernel-devel
dkms

and read this page.

понедельник, 5 ноября 2012 г.

Install instant Oracle client on Centos 64

Downloads from http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html
oracle-instantclient11.2-basic-11.2.0.3.0-1.x86_64.rpm
oracle-instantclient11.2-sqlplus-11.2.0.3.0-1.x86_64.rpm
and setup this.
Create /etc/profile.d/oracle.sh with:
export ORACLE_HOME="/usr/lib/oracle/11.2/client64"
export LD_LIBRARY_PATH=$ORACLE_HOME/lib
export TNS_ADMIN=$ORACLE_HOME
export PATH=$PATH:$ORACLE_HOME/bin
create "tnsnames.ora" file in $TNS_ADMIN folder, with:
ORCL =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.5)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = orcl)
    )
  )
Setup rlwrap:
sudo yum install rlwrap
and add this line to ~/.bashrc
alias sqlplus="rlwrap sqlplus"
Test:
sqlplus user_name@orcl
If you get error:
sqlplus: error while loading shared libraries: libsqlplus.so: cannot
open shared object file: No such file or directory
then check $ORACLE_PATH and $LD_LIBRARY_PATH and grants:
chmod -R 755 $ORACLE_HOME
If you get this error:
sqlplus: error while loading shared libraries: libsqlplus.so: cannot
open shared object file: No such file or directory
then add local machine to /etc/hosts :
127.0.0.1   localhost [machine_name]

среда, 31 октября 2012 г.

Обязательное чтиво для PG девелопера

Нарвался здесь на список ресурсов по Postgres. Как раз то что искал. Надеюсь автор не будет против, опубликую у себя:

Wiki
Планета Postgresql
Новости Weekly news
Конференция пользователей и разработчиков PostgreSQL
Исходники

воскресенье, 2 сентября 2012 г.

воскресенье, 22 апреля 2012 г.

Vimium - keyboard browser

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

воскресенье, 15 апреля 2012 г.

Source code of DB objects

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

Как вы думаете, это нормальная ситуация? Думаю, что нет. Но почему-то такой подход довольно часто применяется при разработке приложений БД. Объекты создаются и изменяются "наживую" прямо в БД. Большинство специализированных IDE предоставляют массу "удобных" инструментов для этого - поиск нужного объекта с помощью навигационного дерева, его модификация несколькими щелчками мыши и т.д. При этом об исходном коде мало кто задумывается - а при сборке версии часто используются утилиты, которые на основании кода текущей базы и кода базы продакшена генерируют диф-скрипт (для меня до сих остается загадкой как, т.к. альтер (таблицы например) можно сформировать множеством спосбов, все зависит от конкретного случая, от логики изменения и т.д.). Получается, что исходного кода базы как бы и не существует, он считается неким машинным кодом, трудно воспринимаемым человеком, который полностью отдается на откуп визуальным средствам разаработки. Программист работает не с функционалом своей СУБД, а с функционалом конкретной IDE, неким красивым и (как кажется первое время) удобным промежуточным слоем. При этом приходится изучать именно IDE, а не саму СУБД.

Стоит помнить, что после того как вы с помощью собственно написанного кода (выверенного, отформатированного по корпаративным стандартам, оформленного комментариями) создаете объект БД, этот код нигде не сохранится, вы потеряете его, а в замен получите, то что соберет за вас машина (IDE, специальные утилиты или библиотеки), опираясь на словарь данных БД. При этом теряется история изменения объектов (становится невозможным узнать/вспомнить кто, когда и зачем создавал/удалял/изменял тот или иной объект), могут возникать конфликты при совместной разработке и еще очень много чего.

Об этом можно почитать в "PLSQL Standards Developed for the PLSQL Starter Framework" в главе "Source Code Control":

Remember to never modify the PL/SQL stored in the database. Work from the source code file instead. Yes, modifying the compiled code inside the database is technically feasible, but a really bad idea. It is comparable in some ways to modifying Java bytecode or C object files.

и в главе "Data Models and DDL":

Most DDL is still created by hand. Make it clean, commented and readable, just like source code.

Напоследок приведу код создания простой таблицы в Oracle и то, что из него получается после выгрузки из БД различными утилитами.
Исходный код создания таблицы:
-- This is test_table
CREATE TABLE test_table (
  id NUMBER(38),  -- PK
  value NUMBER(10,2),  -- main value
  width NUMBER(5,0) -- main width value
);
DBMS_METADATA:
  CREATE TABLE "OBJECTMAN"."TEST_TABLE" 
   ( "ID" NUMBER(38,0), 
 "VALUE" NUMBER(10,2), 
 "WIDTH" NUMBER(5,0)
   ) 
Tora:
CREATE TABLE objectman.test_table
(
    id                               NUMBER(38)                      
  , value                            NUMBER(10,2)                    
  , width                            NUMBER(5)                       
)
TOAD Eclpise plugin:
create table test_table
(
    id       number(38),
    value    number(10,2),
    width    number(5)
)


Как видно солянка полная, кто на что горазд.

Конечно это не значит, что нужно полностью отказаться от современных визуальных средств и работать в консольном редакторе. Самое главное работать именно с исходным кодом вашего приложения БД, контроллировать его самостоятельно, не отдавать на откуп машине. Исходный код приложений БД ничем не хуже кода Java или C++ приложений и требует к себе такого же обращения: форматирование, комментарии, контроль версий и т.д.

Несколько рекомендаций:
1. Весь код БД (DML, DDL, DCL, TCL и т.д.) необходимо хранить в репозитории (один объект = один файл);
2. Исходя из первого пункта, должна быть возможность собрать готовую к использованию "чистую" базу "с нуля", используя исходники из репозитория (нет необходимости делать дампы базы, вырезать ненужные(тестовые) данные и т.д.)
3. Править и компилировать код объекта БД нужно именно из файла (т.о. вместо навигатора по объктом БД вашей IDE станет актуален навигатор по файлам проекта в репозитории - найти файл, открыть на редактирование, накатить на базу).

пятница, 30 марта 2012 г.

IDE for Oracle = vim + vorax

Install ruby:
sudo yum install ruby ruby-devel rubygems
sudo gem install antlr3 -r

Install vim with ruby support:
sudo yum install zlib-devel openssl-devel ncurses-devel
cd Downloads
git clone git://repo.or.cz/vim_mainline.git
cd vim_mainline
./configure --enable-rubyinterp --with-features=huge
make
sudo make install


wget http://www.vim.org/scripts/download_script.php?src_id=14847

воскресенье, 25 марта 2012 г.

Автодокументирование PL SQL кода

Отличная утилита для автодокументирования кода PL SQL - pldoc

воскресенье, 11 марта 2012 г.

install Tora 2.1.3 on Fedora 16

Скачиваем исходники и достаем из архива:
cd Downloads
wget http://downloads.sourceforge.net/project/tora/tora/2.1.3/tora-2.1.3.tar.bz2?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Ftora%2Ffiles%2Flatest%2Fdownload&ts=1331490264&use_mirror=ignum
tar -jxvf tora-2.1.3.tar.bz2

Устанавливаем зависимые пакеты:
su -c 'yum install qt-devel qscintilla-devel'

Понадобится переменная окружения LD_LIBRARY_PATH:
export LD_LIBRARY_PATH=$ORACLE_HOME/lib

cd tora-2.1.3/

Теперь неменого подправим файл src/Makefile.am: в блоке BUILT_SOURCES нужно добавить moc_toawr.cpp:
...
# files listed in BUILT_SOURCES are built before anything else.
BUILT_SOURCES = \
 moc_toawr.cpp \
 moc_toabout.cpp \
 moc_toalert.cpp \
...

Конфигурируем и собираем (предполагается, что на машине есть Oracle):
./configure --prefix=/usr --with-oracle=$ORACLE_HOME --with-oracle-libraries=$ORACLE_HOME/lib
make
su -c 'make install'

пятница, 9 марта 2012 г.

Extract Oracle DDL to File

Простой скрипт для выгрузки DDL-кода Oracle-объекта в файл.

GenDDL.sql:
SET TERMOUT OFF
SET VERIFY OFF
SET ECHO OFF
SET LONG 9000000
SET LONGC 900
SET LINES 400
SET TRIMSPOOL ON
SET PAGES 0
SET FEEDBACK OFF
SET HEAD OFF
SET SQLBLANKLINES OFF
SET SERVEROUTPUT ON

BEGIN
   DBMS_METADATA.set_transform_param (DBMS_METADATA.session_transform,
                                      'PRETTY',
                                      TRUE);
   DBMS_METADATA.set_transform_param (DBMS_METADATA.session_transform,
                                      'SQLTERMINATOR',
                                      TRUE);
   DBMS_METADATA.set_transform_param (DBMS_METADATA.session_transform,
                                      'SEGMENT_ATTRIBUTES',
                                      FALSE);
   DBMS_METADATA.set_transform_param (DBMS_METADATA.session_transform,
                                      'STORAGE',
                                      FALSE);
   DBMS_METADATA.set_transform_param (DBMS_METADATA.session_transform,
                                      'TABLESPACE',
                                      FALSE);
   DBMS_METADATA.set_transform_param (DBMS_METADATA.session_transform,
                                      'REF_CONSTRAINTS',
                                      TRUE);
   DBMS_METADATA.set_transform_param (DBMS_METADATA.session_transform,
                                      'SPECIFICATION',
                                      TRUE);
   DBMS_METADATA.set_transform_param (DBMS_METADATA.session_transform,
                                      'BODY',
                                      TRUE);
   DBMS_METADATA.set_transform_param (DBMS_METADATA.session_transform,
                                      'CONSTRAINTS',
                                      TRUE);
   DBMS_METADATA.set_transform_param (DBMS_METADATA.session_transform,
                                      'STORAGE',
                                      TRUE);
   DBMS_METADATA.set_transform_param (DBMS_METADATA.session_transform,
                                      'CONSTRAINTS_AS_ALTER',
                                      TRUE);
END;
/

SPOOL '&&3'

BEGIN
   FOR i IN (SELECT owner,
                    object_type,
                    object_name,
                    created d
               FROM all_objects
              WHERE owner = '&&1' AND object_name = '&&2')
   LOOP
      DBMS_OUTPUT.Put_Line (
         DBMS_METADATA.get_ddl (REPLACE (i.object_type, ' ', '_'),
                                i.object_name,
                                i.owner));
   END LOOP;
END;
/

SPOOL OFF

EXIT
Используется 3 входных параметра:
1) Пользователь (схема);
2) Объект;
3) Файл для выгрузки.

Пример запуска:
rlwrap sqlplus -silent=true objectman@XE/objectman @/home/maksim/projects/AntOraDDL/GenDDL.sql OBJECTMAN MYBOOKS /home/maksim/projects/AntOraDDL/mybooks.sql

воскресенье, 4 марта 2012 г.

Автодополнение в sqlplus

Наконец нашел то, чего так не хватало в sqlplus'е - простой GPL'ный фрон енд - gqlplus:
- Навигация по истории команд;
- Редактор командной строки (правда все это есть в rlwrap);
- Автододополнении для имен таблиц и колонок (вот это действительно здорово).
Плюс ко всему этому имеются собранные deb и rpm пакеты.

понедельник, 6 февраля 2012 г.

воскресенье, 5 февраля 2012 г.

hEAVy database model

Отличная статья by Tim Gorman, посвещянная EAV моделям.
Позволю себе привести пример из этой статьи.
Запрос для реляционной модели:
Select name,
      mailing_street_addr1,
      mailing_street_addr2,
      mailing_city,
      mailing_state_province,
      mailing_postal_zip,
      ...
from company
where company_id = 
Этот же запрос, но для EAV модели:
Select cn.description,
      ma.string82,
      ma.string83,
      mc.string44,
      mc.string63,
      mz.numeric31,
      ...
from      data c,
      data cc,
      data cn,
      data ma,
      data mc,
      data mz,
      data ...
where      c.description = 'CUSTOMER'
and      cc.entity_id = c.sysno
and      cc.description = 'COLUMN'
and      ma.column_id = cc.sysno
and      ...

четверг, 26 января 2012 г.

Oracle. Администрирование и разработка.: Деление на ноль? Легко!

Oracle. Администрирование и разработка.: Деление на ноль? Легко!: Q: can oracle divide by zero? A: no Q: are you absolutely sure? A: yes Q: then why does this work? select 1 from dual where exists (sel...

среда, 25 января 2012 г.

setEncoding для java.util.zip

Как известно у методов замечательного стандартного пакета java.util.zip нет возможности указывать кодировку файлов. И вообще для работы с архивами лучше ипользовать сторонние специализированные библиотеки, как например Apache Commons Compress.
Но, если код (или его часть) уже написаны под java.util.zip, то можно воспользоваться пакетом для работы с архивами, входящим в состав бинарников Apache Ant. В пакете org.apache.tools.zip содержаться классы аналогичные java.util.zip, но исправленные (в частности содержится setEncoding), практически все имена и методы классов совпадают.

1) Скачиваем последнюю версию бинарника Appache Ant;
2) Достаем из папки lib файл ant.jar;
3) "Выковыриваем" все "ненужные" нам пакеты из папки org, оставляем на месте только файлы в папке /org/apache/tools/zip;
4) Подключаем jar-файл к своему проекту вместо java.util.zip;
5) В моем коде пришлось только изменить метод Entries на getEntries;
6) Теперь при создании экземпляра ZipFile вторым параметром можно указать кодировку.

Вот небольшой пример:
import java.io.*;
import java.util.Enumeration;
import org.apache.tools.zip.*;

public class ZipUtil {

private static String ZIPENCODE = "CP866";

public static final void unzip(String extractFrom, String extractTo)
   throws IOException {
  File extractFromFile = new File(extractFrom);
  File extractToFile = new File(extractTo);
  ZipFile archive = new ZipFile(  extractFromFile, ZIPENCODE);
  Enumeration e = archive.getEntries();
  while (e.hasMoreElements()) {
   ZipEntry entry = (ZipEntry) e.nextElement();
   File file = new File(extractToFile, entry.getName());
   if (!entry.isDirectory()) {
    if (!file.getParentFile().exists()) {
     file.getParentFile().mkdirs();
    }
    InputStream in = archive.getInputStream(entry);
    BufferedOutputStream out = new BufferedOutputStream(
      new FileOutputStream(file));
    byte[] buffer = new byte[8192];
    int read;
    while (-1 != (read = in.read(buffer))) {
     out.write(buffer, 0, read);
    }
    in.close();
    out.close();
   }
  }
 }
}

Лично я использовал этот пакет в хранимых java процедурах Oracle, предварительно загрузив jar-файл в базу с помощью loadjava.

И, само собой, при распространении своей программы с использованием этой библиотеки не забываем о соблюдении условий, выдвигаемых лицензией Apache.

Свободная бухгалтерская программа на PostgreSQL + Qt4.

http://qbalance.sourceforge.net/

вторник, 7 июня 2011 г.

Oracle: Выполнение команд ОС и обработка результатов

Этой теме посвещено много статей, но когда занялся сам, то встретился с трудностями получения и обработки кода ошибки (кода возврата) команды, поэтому опишу следующий вариант решения:

На просторах Интеренета (а именно здесь) нашел следующий код:
try {
 Process p = Runtime.getRuntime().exec("Команда ОС");
 BufferedReader stdInput = new BufferedReader(new
 InputStreamReader(p.getInputStream()));
 BufferedReader stdError = new BufferedReader(new
 InputStreamReader(p.getErrorStream()));
 System.out.println("Here is the standard output of the command:\n");
 while ((s = stdInput.readLine()) != null) {
  System.out.println(s);
 }
 System.out.println("Here is the standard error of the command (if any):\n");
 while ((s = stdError.readLine()) != null) {
  System.out.println(s);
 }
}
catch (IOException e) {
 System.out.println("exception happened - here's what I know:");
 e.printStackTrace();
}
Программа выполняет команду, а затем считывает стандартный выходной поток и поток ошибок.
Меня вполне все устроило, заиcключением того, что проблематично получить код ошибки, возвращаемый при завершении работы программы.
В Windows строка Runtime.getRuntime().exec("echo %errorlevel%")
всегда вернет "0" (насколько я понял, из рантайма вообще невозможно работать с переменными окружения, из за того, что в разных системах доступ к ним осуществляется по разному).

Поискав дальше нашел статью.
Т.е. код возвата программы можно получить:
System.out.println(p.exitValue());
Теперь оформим в виде хранимой процедуры Oracle:
CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED "os_execute" AS
import java.io.*;
public class os_execute {
 public static void main() throws IOException {
  String s = null;
  try {
   Process p = Runtime.getRuntime().exec("Команда ОС");
   BufferedReader stdInput = new BufferedReader(new
   InputStreamReader(p.getInputStream()));
   BufferedReader stdError = new BufferedReader(new
   InputStreamReader(p.getErrorStream()));
   System.out.println("Here is the standard output of the command:\n");
   while ((s = stdInput.readLine()) != null) {
    System.out.println(s);
   }
   System.out.println("Here is the standard error of the command (if any):\n");
   while ((s = stdError.readLine()) != null) {
    System.out.println(s);
   }
   System.out.println(p.exitValue());
  }
  catch (IOException e) {
   System.out.println("exception happened - here's what I know:");
   e.printStackTrace();
  }
 }
}
Таким образом на терминале отобразится текст, возвращаемый командной строкой, и код ошибки.
Код также будет работать и под Linux.
Данную процедуру можно переделать в функцию и возвращать результаты в выходном параметре.

воскресенье, 5 июня 2011 г.

Удаление связанных таблиц ORACLE

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

set serveroutput on;
begin
  for i in (select * from all_constraints where table_name in ('t1', 't2') and constraint_type in ('U','C','R')) loop
    dbms_output.put_line('alter table ' || i.table_name || ' drop constraint ' || i.constraint_name || ';');
  end loop;

  for i in (select * from all_constraints where table_name in ('t1', 't2') and constraint_type = 'P') loop
    dbms_output.put_line('alter table ' || i.table_name || ' drop constraint ' || i.constraint_name || ';');
  end loop;
  
  for i in (select * from all_tables where table_name in ('t1', 't2') loop
    dbms_output.put_line('drop table ' || i.table_name || ';');
  end loop;
end;

воскресенье, 13 февраля 2011 г.

Install Postgresql-9.0 on Ubuntu

Добавим новый источник postgresql:
sudo add-apt-repository ppa:pitti/postgresql

Обновим список пакетов:
sudo apt-get update

Установка postgresql:
sudo apt-get install postgresql-9.0 postgresql-client postgresql-contrib

и Pgadmin'а:
sudo apt-get install pgadmin3

Чтобы открыть доступ для сетевых подключений в файле:
sudo gedit /etc/postgresql/9.0/main/postgresql.conf
изменяем:
#listen_addresses = 'localhost'
на:
listen_addresses = '*'

и в фале:
sudo gedit /etc/postgresql/9.0/main/pg_hba.conf
указываем параметры подключений pg_hba.conf
Я настроил так:
# TYPE  DATABASE        USER            CIDR-ADDRESS            METHOD
host    all             all             192.168.1.49/32         trust

Т.е. доступ по сети только для указанного IP, для любого пользователя, к любой бд и без пароля.

запуск сервера:
sudo /etc/init.d/postgresql start
перезапуск:
sudo /etc/init.d/postgresql restart
остановка:
sudo /etc/init.d/postgresql stop

Каталог с конфигурационными файлами: /etc/postgresql/9.0/main
Каталог по умолчанию с пользовательскими данными: /var/lib/postgresql/9.0/main

На основании статей
Installing PostgreSQL 9.0 on Ubuntu 10.04
Install PostgreSQL on Ubuntu 9.04/9.10
И личного опыта:)

четверг, 27 января 2011 г.

Zend: отображение ошибок приложения

При возникновении ошибок, Zend по умолчанию выводит скупую фразу:
An error occurred
Application error
Чтобы на экране была видна детальная информаця об ошибках, необходимо в application.ini в нужном блоке (у нас это testing) указать:
[testing : production]
resources.frontController.params.displayExceptions = 1
И незабыть в htacces показать, что мы хотим использовать именно этот блок:
SetEnv APPLICATION_ENV testing