psql: перенаправляем вывод в файл

=> copy (select 42) to '/tmp/answer';

Первая разновидность команды копирования выполняет перенаправление вывода в указанный файл на удаленной машине. Ждя ее исполнения пользователь должен обладать правами рута.

=> /copy (select 42) to '/tmp/answer'

Вторая разновидность — это метакоманда клиента psql которой не требуются права суперпользователя и запись выполняется в файл на локальной машине.

Стоит обратить внимание, что первый вариант — это команда sql (поэтому за ней и идет точка с запятой), а вторая — это именно метакоманда. окончание — всегда символ новой строки.

PostgreSQL: bytea в varchar

byteaЕсть такой тип: bytea. При попытке вдеслть селект на него в консоли он отображен не будет. А в Pgadmin будет заглушка «<двоичные данные>». Это совсем неудобно когда хочется посмотреть, что же там скрывается.

Но все решается просто :)

select convert_from(body, 'utf8') from megatable

Вторым аргументом convert_from выступает кодировка исходного текста.
 

Symfony2, Doctrine2, Postgresql и кодировки

Суть проблемы: в doctrine2 нет возможности выбрать кодировку подключения для драйвера pdo_pgsql. Совсем никак. Нет. Даже не пытайтесь. У вас ничего не получится.

Вот незадача: в mysql есть опция драйвера pdo PDO::MYSQL_ATTR_INIT_COMMAND. Благодаря этой опции можно устанавливать кодировку подключения при помощи

set names 'utf8'

И даже драйвер mysql поддерживает установку кодировки при помощи опции charset в настройках подключения.

Если мы покопаемся в файле драйвера, то увидим, что кодировка исправно обрабатывается

<b>Doctrine\DBAL\Driver\PDOMySql\Driver</b>

    /**
     * Constructs the MySql PDO DSN.
     *
     * @param array $params
     *
     * @return string The DSN.
     */
    private function _constructPdoDsn(array $params)
    {
        $dsn = 'mysql:';
        if (isset($params['host']) && $params['host'] != '') {
            $dsn .= 'host=' . $params['host'] . ';';
        }
        if (isset($params['port'])) {
            $dsn .= 'port=' . $params['port'] . ';';
        }
        if (isset($params['dbname'])) {
            $dsn .= 'dbname=' . $params['dbname'] . ';';
        }
        if (isset($params['unix_socket'])) {
            $dsn .= 'unix_socket=' . $params['unix_socket'] . ';';
        }
        if (isset($params['charset'])) {
            $dsn .= 'charset=' . $params['charset'] . ';';
        }

        return $dsn;
    }

Для драйвера pdo_pgsql (Doctrine\DBAL\Driver\PDOPgSql\Driver) нет ничего подобного.

При этом сам драйвер вполне успешно с кодировками работает.

Однако, безвыходных ситуаций не бывает. Чтобы как-то изменить кодировку при работе с базой pgsql можно применять события symfony2. А конкретно событие postConnect из doctrine2.

Все, что нам потребуется — это реализовать собственный листенер этого события.

namespace DatabaseBundle\Event\Listeners;

use Doctrine\DBAL\Event\ConnectionEventArgs;
use Doctrine\DBAL\Events;
use Doctrine\Common\EventSubscriber;

/**
 * Событие инициализации подключения pgsql.
 * Позволяет установить кодировку бд.
 */
class PgsqlConnectionInit implements EventSubscriber
{
    /**
     * Используемая кодировка
     *
     * @var string
     */
    private $_charset;

    /**
     * Конфигурирование кодировки при создании класса
     *
     * @param string         $charset   The charset.
     */
    public function __construct($charset = 'utf8')
    {
        $this->_charset = $charset;
    }

    /**
     * @param \Doctrine\DBAL\Event\ConnectionEventArgs $args
     *
     * @return void
     */
    public function postConnect(ConnectionEventArgs $args)
    {
        $args->getConnection()->executeQuery("SET NAMES ?", array($this->_charset));
    }

    /**
     * {@inheritdoc}
     */
    public function getSubscribedEvents()
    {
        return array(Events::postConnect);
    }
}

А затем подключить этот эвент в config.yml

services:
  pgsql.connection.init:
    class: DatabaseBundle\Event\Listeners\PgsqlConnectionInit
    tags:
      - { name: doctrine.event_listener, event: postConnect }

Теперь все ок :)

tmux + mc + ssh

Если запустить ssh в tmux, а в нем запустить mc, то последний пожалуется, что тип терминала неизвестен и закроется. А на локальной машине не работают сочетания Shift+Fx.

Решение простое — добавить в файлы на удаленных машинах следующие опции (в локальные тоже не помешает):

~/.profile

if [ $TERM = "screen" ]; then
    export TERM=xterm-color
fi
if [ -n "$TMUX" ]; then
    export COLORTERM=rxvt
fi

~/.tmux.conf

setw -g xterm-keys on

И задеплоить это с помощью ansible.

Symfony2: cannot redeclarate class

Fatal error: include() [<a href="http://contoso.com/app/function.include">function.include</a>]: Cannot redeclare class symfony\bundle\frameworkbundle\frameworkbundle in /srv/www/contoso.com/vendor/composer/ClassLoader.php on line <i>412</i>

Да-да. Есть такая противная ошибка.

Она лечится либо отключением apc, либо установкой для него следующего набора опций

apc.include_once_override = 0
apc.canonicalize = 0
apc.stat = 0

PostgreSQL: ограничиваем время выполнения запроса

db=> set statement_timeout to 100;
SET
db=> select pg_sleep(110);
ERROR:  canceling statement due to statement timeout
db=> set statement_timeout to 0;
SET
db=> 

Первым выражением установим максимальное время выполнения запроса в миллисекундах. Вторым пойдет запрос, а третьим мы снимем ограничение на время выполнения (0 — значение по умолчанию).

Дока.

OpenSUSE и шрифты

Сравнение шрифтов. Слева шрифт без нормально настроенного рендеринга, а справа - с нормально настроенным.

Сравнение шрифтов. Слева шрифт без нормально настроенного рендеринга, а справа — с нормально настроенным.

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

Как раз на картинке видно две ситуации:

  • слева дефолтный рендеринг шрифтов «искаропки»
  • справа — допиленный рендеринг infinality (который всячески нахваливают)

Осталось его лишь настроить.

zypper ar http://download.opensuse.org/repositories/home:/nick31:/INFINALITY-ULTIMATE/openSUSE_13.2/ subpixel
zypper mr -p 98 subpixel
zypper ref && sudo zypper dup
zypper in libfreetype6 libfreetype6-32bit

К слову, репозитарий выше — это единственный рабочий репозитарий с обновляемым (с нормальной скоростью) freetype и другими плюшками.

После этого можно поставить шрифт ubuntu (он даже нормально выглядит) или cantarell.