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

Git: Обновление подмодулей

git submodule init
git submodule update

вторник, 26 ноября 2013 г.

SQL Developer: ORA-12705: Cannot access NLS data files or invalid environment specified


При попытке подключиться с помощью SQL Developer 4.0.0.13 к БД Oracle, получаю ошибку:
Status : Failure -Test failed: ORA-00604: error occurred at recursive SQL level 1
ORA-12705: Cannot access NLS data files or invalid environment specified
NLS - расшифровывается как National Language Support. Проблема связана с кодировкой. Причем при подключении через SQL*Plus никаких проблем с кодировкой не возникает. Это значит что проблема в самом SQL Developer. Поисказ в инете нашел вот эту заметку. Выполнив приведенные в ней дейвтвия решил пролбему:
  • открыть файл sqldeveloper\ide\bin\ide.conf;
  • в конец добавил строки:
    AddVMOption -Duser.region=us
    AddVMOption -Duser.language=en
    
  • перезапустил SQL Developer.

понедельник, 25 ноября 2013 г.

ORA-12638: Credential retrieval failed

При попытке подключиться к Oracle из под учетной записи пользователя Windows не состоящего в группе ORA_DBA, получаю ошибку:
ORA-12638: Credential retrieval failed

Решение

Вот тут написано, что нужно в файле sqlnet.ora (у меня он находится по пути c:\oraclexe\app\oracle\product\11.2.0\server\network\ADMIN\sqlnet.ora) заменить строку:
SQLNET.AUTHENTICATION_SERVICES = (NTS)
на 
SQLNET.AUTHENTICATION_SERVICES = (NONE)

четверг, 21 ноября 2013 г.

Изучаю Oracle: Пользователи и их права

В предыдущем посте в п. 2 я писал как исправить проблемы с некорректно установленным Oracle'ом. Как оказалось, то что я написал не полностью решает проблему, по-этому я его снес и установил заново уже под локальной учетной записью. Теперь все работает как надо и можно продолжить изучение.

При установке Oracle по умолчанию создаются два пользователя/схемы - SYS и SYSTEM. Я написал "пользователя/схемы" потому, что при создании нового пользователя для него создается одноименная схема. Не сразу понятно чем понятие "пользователь" отличается от понятия "схема". Чтобы понять представьте пользователя Windows (Unix). Пользователь имеет имя ИмяПользователя  и принадлежащую ему папку - C:\Users\ИмяПользователя (/home/ИмяПользователя). Так вот пользователь Oracle аналогичен пользователю Windows, а схема - аналогична папке пользователя. Точно так же как у пользователя Windows, у пользователя Oracle есть набор прав. Так же как папка пользователя Windows содержит различные файлы, также и схема Oracle содержит различные объекты - таблицы, последовательности, триггеры и др. Если продолжать аналогию, то пользователей SYS и SYSTEM можно считать Администратором Windows или root-пользователем Unix. Они имеют неограниченные права. И работать под ними не рекомендуется. По-этому сначала нужно создать еще одного пользователя.

1. Создание пользователя и предоставление ему прав


Создадим пользователя, например fiftin:
CREATE USER fiftin IDENTIFIED BY 123456;
Мы создали пользователя fiftin с паролем 123456. Он не имеет абсолютно никаких прав. Вы даже не сможете под ним зайти:
SQL> connect fiftin
Enter password:
ERROR:
ORA-01045: user FIFTIN lacks CREATE SESSION privilege; logon denied
Для наделения пользователя правами существует команда GRANT. Например дадим права пользователю fiftin на вход:
GRANT CREATE SESSION TO fiftin;
Если теперь вы попробуете подключиться как пользователь fiftin у вас это получится. Но это все что разрешено пользователю fiftin. Наделим пользователя правами администратора:
GRANT dba TO fiftin WITH ADMIN OPTION;
Теперь вы можете подцепиться к БД под fiftin'ом как админ:
connect fiftin/fiftin
Создадим таблицу:
CREATE TABLE table1(id INT, column1 INT);
Вставим данные:
INSERT INTO table1(id, column1) VALUES (0, 1)

2. Права на создание таблиц


Создадим еще одного пользователя - test:
CREATE USER test IDENTIFIED BY 123;
Дадим ему права:
GRANT create session, create table TO test;
Теперь пользователь test может подключаться и создавать таблицы. Попробуем создать таблицу (не забудьте зайти под test'ом):
CREATE TABLE tbl_test(id int, column1 INT);
Получаем ошибку:
ORA-01950: no privileges on tablespace 'SYSTEM'
Почему так? Оказывается для того чтобы обычный пользователь (не админ) мог что-либо создать в БД, ему нужно выделить для этого место. Зайдем снова под fiftin'ом и выполним команду:
ALTER USER test QUOTA 50m ON system;
Этой командой мы выделяем пользователю test 50Мб под его нужды. Попробуйте теперь зайти под пользователем test и создать таблицу и у вас получится.

3. Права на доступ к таблицам из другой схемы


Теперь предположим что пользователь test должен брать данные из таблицы table1t. По-идее для этого нужно вызвать команду:
SELECT * FROM table1;
Но это не работает. Все потому, что таблица table1 находится в схеме fiftin и пользователь test её не видит (test видит таблицы только в своей схеме). Чтобы test увидел таблицу table1 нужно явно указать что она находится в схеме test - fiftin.table1. Но если вы сейчас попробуете обратиться к таблице fiftin.table1 вы её все равно не увидите. Потому что у пользователя test нет прав на доступ к данным из другой схемы (так же как пользователь Windows не может увидеть файлы другого пользователя, если у него нет на это прав).
Чтобы дать пользователю test права на чтение данных из таблицы fiftin.table1 нужно вызвать команду:
GRANT SELECT ON fiftin.table1 TO test
Теперь повторим попытку чтения из fiftin.table1 под пользователем test. Ура, получилось!

4. Синонимы


Чтобы не писать каждый раз "fiftin.table1" Oracle предоставляет возможность создавать синонимы. Мы можем создать синоним таблицы table1 в схеме test и обращаться к ней по короткому имени.
Для начала дадим права пользователю test на создание синонимов:
GRANT CREATE SYNONYM TO test
А теперь создадим сам синоним:
CREATE SYNONYM table1 FOR fiftin.table1;
Все.

среда, 20 ноября 2013 г.

Изучаю Oracle: Начало

Oracle предоставляет бесплатную (express) версию своей СУБД, которую можно скачать на официальном сайте (потребуется зарегистрироваться).

Если ваш компьютер/сервер находится в домене, то чтобы корректно установить oracle потребуется зайти под локальной учетной записью с правами администратора. СУБД установится и под доменной учетной записью, но при этом сам экземпляр БД (instance) будет создана некорректно и его придется пересоздавать и перенастраивать. Как это сделать будет написано дальше.

Что такое "экземпляр БД"? Это отдельная БД со своим именем, пользователями, таблицами, настройками, правами. В Oracle могут быть созданы и работать несколько экземпляров БД. Экземпляр можно остановить, создать, удалить и это никак не будет влиять на другие экземпляры. По умолчанию создается только один экземпляр.

1. Проверка работы БД


Для управления БД в комплекте идет консольное приложение SQL*Plus, с помощью которой можно как настраивать БД, так и получать доступ к данных хранящимся в ней. Запустив её вы увидите:
SQL*Plus: Release 11.2.0.2.0 Production on ******************
Copyright (c) 1982, 2010, Oracle.  All rights reserved.
SQL>
На данный момент вы просто запустили её. Но к БД доступа, на данный момент, вы не имеете. Чтобы получить доступ к БД нужно к ней подключиться. Для этого существует команда CONNECT. Чтобы с помощью неё подключиться к БД с правами администратора без логина и пароля, необходимо чтобы учетная запись пользователя под которой запущен SQL*Plus была в группах Администраторы и ORA_DBA. В этом случае команда для подключения выгладит так:
CONNECT / AS SYSDBA
Теперь проверим запущен ли экземпляр БД командой:
STARTUP
Эта команда запускает экземпляр БД. Если экземпляр уже запущен, то вы увидите:
ORA-01081: cannot start already-running ORACLE - shut it down first
Если не был запущен, но успешно запустился:
ORACLE instance started.
Total System Global Area  ********* bytes
Fixed Size                  ******* bytes
Variable Size             ********* bytes
Database Buffers          ********* bytes
Redo Buffers                ******* bytes
Database mounted.
Database opened.
Если же не был запущен и при попытке запустить возникла ошибка, вы увидите сообщение об ошибке:
ORA-01078: failure in processing system parameters
ORA-01565: error in identifying file 'C:\oraclexe\app\oracle\product\11.2.0\serv
er\dbs\spfileXE.ora'
ORA-27041: unable to open file
OSD-04002: unable to open file
O/S-Error: (OS 2) ?? ??????? ????? ????????? ????.
Если у вас на данном этапе не возникло проблем, то теперь вы можете делать с БД все что захотите: останавливать, запускать, создавать таблицы, добавлять данные и пункт 2 вы можете пока не читать.

2. Что делать если вы устанавливали СУБД Oracle из под доменной учетной записи и теперь не можете запустить БД


* Ниже будет использоваться абсолютный путь расположения директории Oracle, у меня это C:\ORACLEXE. Название экземпляра БД - XE.

Начнем с того, что восстановил главный настоечный файл БД - spfile. Он должен располагаться здесь - C:\ORACLEXE\APP\ORACLE\product\11.2.0\server\dbs\ и иметь имя - spfile<имя_экземпляра_БД>.ora, в нашем случае spfileXE.ora. Но его там нет. Но зато есть файл init.ora. С помощью него мы получим spfile.
Откроем init.ora:
# Change '<ORACLE_BASE>' to point to the oracle base (the one you specify at
# install time)
db_name='ORCL'
memory_target=1G
processes = 150
audit_file_dest='<ORACLE_BASE>/admin/orcl/adump'
audit_trail ='db'
db_block_size=8192
db_domain=''
db_recovery_file_dest='<ORACLE_BASE>/flash_recovery_area'
db_recovery_file_dest_size=2G
diagnostic_dest='<ORACLE_BASE>'
dispatchers='(PROTOCOL=TCP) (SERVICE=ORCLXDB)'
open_cursors=300 
remote_login_passwordfile='EXCLUSIVE'
#undo_tablespace='UNDOTBS1'
# You may want to ensure that control files are created on separate physical
# devices
control_files = (ora_control1, ora_control2)
compatible ='11.2.0'

В нем везде заменим (перед этим можно сделать резервную копию) <ORACLE_BASE> на c:\oraclexe\app\oracle и сохраняем.
Далее в SQL*Plus вызываем команду:
CREATE SPFILE='C:\ORACLEXE\APP\ORACLE\product\11.2.0\server\dbs\spfileXE.ora' FROM PFILE='C:\ORACLEXE\APP\ORACLE\product\11.2.0\server\dbs\init.ora'
Теперь мы имеем рабочий spfile и можем повторить попытку запустить экземпляр БД командой STARTUP в SQL*Plus. Теперь она должна пройти но при этом выдать ошибку:
ORACLE instance started.
Total System Global Area  644468736 bytes
Fixed Size                  1385488 bytes
Variable Size             192941040 bytes
Database Buffers          444596224 bytes
Redo Buffers                5545984 bytes
ORA-00205: error in identifying control file, check alert log for more info
Связано это с тем, что на самом деле запуск экземпляра состоит из нескольких этапов:
1) Запуск экземпляра.
2) Монтирование (mount).
3) Открытие доступа (open).
Мы смогли запустить экземпляр, но смонтировать данные не смогли. Это потому, что нам нечего монтировать - файлов содержащих данные нету. Если вы загляните в директорию C:\oraclexe\app\oracle\oradata\XE, то увидите что она пуста. Так быть не должно. Чтобы это исправить нужно вызвать команду CREATE DATABASE <имя_экземпляра_БД>, которая создаст необходимые для работы БД файлы. Синтаксис вызова такой:
CREATE DATABASE xe
   USER SYS IDENTIFIED BY 123456
   USER SYSTEM IDENTIFIED BY 123456
   LOGFILE GROUP 1 ('c:\oraclexe\app\oracle\oradata\xe\redo01.log') SIZE 100M,
           GROUP 2 ('c:\oraclexe\app\oracle\oradata\xe\redo02.log') SIZE 100M,
           GROUP 3 ('c:\oraclexe\app\oracle\oradata\xe\redo03.log') SIZE 100M
   MAXLOGFILES 5
   MAXLOGMEMBERS 5
   MAXLOGHISTORY 1
   MAXDATAFILES 100
   MAXINSTANCES 1
   CHARACTER SET US7ASCII
   NATIONAL CHARACTER SET AL16UTF16
   DATAFILE 'c:\oraclexe\app\oracle\oradata\xe\system01.dbf' SIZE 325M REUSE
   EXTENT MANAGEMENT LOCAL
   SYSAUX DATAFILE 'c:\oraclexe\app\oracle\oradata\xe\sysaux01.dbf' SIZE 325M REUSE
   DEFAULT TEMPORARY TABLESPACE tempts1
      TEMPFILE 'c:\oraclexe\app\oracle\oradata\xe\temp01.dbf' 
      SIZE 20M REUSE
   UNDO TABLESPACE UNDOTBS1
      DATAFILE 'c:\oraclexe\app\oracle\oradata\xe\undotbs01.dbf'
      SIZE 200M REUSE AUTOEXTEND ON MAXSIZE UNLIMITED;
В конце выполнения команда должна выдать "Database created."
Если теперь вы заглянете в папку C:\oraclexe\app\oracle\oradata\XE, то должны увидеть следующие файлы:
REDO01.LOG
REDO02.LOG
REDO03.LOG
SYSAUX01.DBF
SYSTEM01.DBF
TEMP01.DBF
UNDOTBS01.DBF

Все. Теперь вы можете попробовать создать таблицу:
CREATE TABLE tbl_test1(id int, col1 int);
Вставить в нее данные:
INSERT INTO tbl_test1 VALUES(1, 1);
INSERT INTO tbl_test1 VALUES(2, 2);
INSERT INTO tbl_test1 VALUES(3, 3);
и считать их:
SELECT * FROM tbl_test1;

понедельник, 28 октября 2013 г.

Не удалось добавить пакет драйвера: Хэш этого файла отсутствует в заданном файле каталога. Возможно, файл поврежден или подделан

Проблема

При попытке установить драйвер для Android-устройства под Windows 8 получил сообщение об ошибке:
Не удалось добавить пакет драйвера: Хэш этого файла отсутствует в заданном файле каталога. Возможно, файл поврежден или подделан.

Решение проблемы

Решение было найдено здесь. В командной строке с правами администратора выполняем команды:
bcdedit.exe /set loadoptions DDISABLE_INTEGRITY_CHECKS
bcdedit.exe /set TESTSIGNING ON
Перезагружаем компьютер.

После этого при установки ненадежного драйвера будет выводиться запрос на подтвержение установки такого драйвера.

Вот тут написано почему так, но почему способ устранения предложенный там мне не подошел.

среда, 25 сентября 2013 г.

Монтирование расшаринной папки Windows в файловую иерархию Linux

mount -t cifs //192.168.XXX.XXX/share /path/to/mount -o user=username,password=password

среда, 18 сентября 2013 г.

Настройка разрешения второго монитора подключенного к ноутбуку под Ubuntu (13.04)

Есть ноутбук с Ubuntu 13.04 у которого разрешение экрана 1366x768. Есть монитор с допустимым разрешением 1280x1024. При подключении его к ноутбуку для него устанавливалось разрешение 1024x768. И в списке допустимых разрешений не было нужного (1024x768 было максимальным).
Решение проблемы нашел здесь.

Вначале вызывает: xrandr
Он выводит список мониторов и допустимые для них разрешения:

Screen 0: minimum 320 x 200, current 2390 x 768, maximum 8192 x 8192
LVDS connected 1366x768+1024+0 (normal left inverted right x axis y axis) 344mm x 193mm
   1366x768       60.1*+
   1280x720       59.9
   1152x768       59.8
   1024x768       59.9
   800x600        59.9
   848x480        59.7
   720x480        59.7
   640x480        59.4
VGA-0 connected 1024x768+0+0 (normal left inverted right x axis y axis) 0mm x 0mm
   1024x768       60.0*
   800x600        60.3     56.2
   848x480        60.0
   640x480        59.9
HDMI-0 disconnected (normal left inverted right x axis y axis)


VGA-0 -- имя второго монитора.
Как видно в этом списке нету нашего разрешения. Его нужно туда добавить. Для этого:
  1. Вызываем прогамму:         cvt 1280 1024 60

    Она выведет что-то похожее на это:

    # 1280x1024 59.89 Hz (CVT 1.31M4) hsync: 63.67 kHz; pclk: 109.00 MHz
    Modeline "1280x1024_60.00"  109.00  1280 1368 1496 1712  1024 1027 1034 1063 -hsync +vsync


    Из вывода программ cvt все что после  Modeline будет нам нужно для добавления нового разрешения. Для этого копируем все что после Modeline и вставляем в вызов программы xrandr с ключем --newmode следующим образом:

    xrandr --newmode "1280x1024_60.00"  109.00  1280 1368 1496 1712  1024 1027 1034 1063 -hsync +vsync

    Таким образом мы создали новый режим с именем 1280x1024_60.00.
  2. Теперь добавляем созданный нами режим в список доступных для нашего монитора:

    xrandr --addmode VGA-0 1280x1024_60.00
  3. Если теперь вызвать xrandr, то можно увидеть, что в списке допустимых разрешений появилось 1280x1024_60.00 которое мы можем выбрать:
    Screen 0: minimum 320 x 200, current 2646 x 1024, maximum 8192 x 8192
    LVDS connected 1366x768+1280+29 (normal left inverted right x axis y axis) 344mm x 193mm
       1366x768       60.1*+
       1280x720       59.9 
       1152x768       59.8 
       1024x768       59.9 
       800x600        59.9 
       848x480        59.7 
       720x480        59.7 
       640x480        59.4 
    VGA-0 connected 1280x1024+0+0 (normal left inverted right x axis y axis) 0mm x 0mm
       1024x768       60.0     59.9 
       800x600        60.3     56.2 
       848x480        60.0 
       640x480        59.9 
       1280x1024_60.00   59.9*

    HDMI-0 disconnected (normal left inverted right x axis y axis)

суббота, 14 сентября 2013 г.

Профайлер памяти и производительности для Java

Лучший из бесплатных профайлеров для Java - VisualVM.

четверг, 12 сентября 2013 г.

пятница, 30 августа 2013 г.

Замета Total Commander'а в Linux

Из всех увиденных, больше всего понравилась Krusader. В Ubuntu можно установить из репозитория.

Программы для создания шрифтов для LibGDX

  • BMFont -- программа только под Windows, но может запускаться под Линуском через Wine. Возникла проблема в связи с тем, что цвет фона выставляет черный.
  • Hiero -- java программа, более удобна чем первая и генерирует изображение с прозрачным фотом.

четверг, 29 августа 2013 г.

Сборка Vacuum-IM 1.2.2

Сборку выполнял в Qt Creator 1.3.1 в Ubuntu 10.4 под Qt 4.6, а так же в Qt Creator'е более новой версии в Ubuntu 12.04 под Qt 4.8. Процесс и ошибки одни и те же.
Для сборки потребовалось установить библиотеку libxss-dev как написано здесь. После этого сборка проходит успешно.
После сборки необходимо создать правильную иерархию каталогов в соответствии с константами PLUGINS_DIR, RESOURCES_DIR, TRANSLATIONS_DIR определенными в файле loader/config/config.inc.
Если теперь запустить программу ./vacuum, то получим ошибку:
vacuum: error while loading shared libraries: libvacuumutils.so.1: cannot open shared object file: No such file or directory.
Чтобы от нее избавиться нужно создать в директории /etc/ld.so.conf.d файл vacuum.conf содержащий путь к директории с библиотекой libvacuumutils.so.1
cd /etc/ld.so.conf.d
sudo -s
echo путь_к_дирректории_с_библиотекам > vacuum.conf
Чтобы применился новый конфигурационный файл vacuum.conf нужно вызвать команду:
ldconfig
Теперь все должно работать.

X11/extensions/scrnsaver.h: Нет такого файла или каталога

sudo apt-get install libxss-dev

вторник, 27 августа 2013 г.

среда, 14 августа 2013 г.

Востроизведение видео/фото/музыки на телевизоре с ноутбука

Соверменные телевизоры поддерживают воспроизведение мультемедийного контента (видео, музыки, фото) с компьютера с помощую запущенного на компьютера медиасервера.

Рассмотрим как это делается на примере телевизора Philips 42PFL6008S/60.

Этот телевизор поддерживает как Wi-Fi так и проводное соединение с сетью. С проводным соединением все просто, поэтому рассмотрим беспроводное подключение к сети.

Если у вас нету Wi-Fi роутера, то необходимо настроить ноутбук как Wi-Fi точку доступа. Для этого существует прогрмма mHotspot. Устанавливаете её, запускаете и указваете как точка доступа будет назваться и код для подключения к ней. Также она позволяет указать максимальное разрешенное количество подключений к ней. Нажимает Start Hotspot и ноутбует становится виден для тебевизора.

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

После этого можно запустить медиасервер и перейти к настройки телевизора.

Работа со временем и датами в PHP

Для работы со временим и датами в PHP 5.2 и выше существует класс DateTime. Он заменяет функционал старых функций для работы со времением/датами.
Чтобы получить текущую дату/время нужно создать объект DateTime без передачи ему параметров.

$now = new DateTime(); 

Для получения объекта DateTime из строки содержащей время существует статический метод createFromFormat(string $format, string $time). Первый параметр - формат передаваемой даты/времени. Второй параметр - строка содаржащая дату/время в формате, переданном в первом параметре %)

Формат даты/времени может выглядеть например так:

Y-m-d H:i:s

что означает запись например такого вида:

2009-02-15 15:16:17.

В приведенной выше строке формата латинские буквы означают следующее:

  • Y -- запись года четырьмя цыфрами (например 2013);
  • m -- запись месяца двумя цыфрами с 01 по 12 (например 07);
  • d -- день месяца двумя цыфрами с 01 по 31;
  • H -- запись часа в 24-ох часовом формате двумя цыфрами с 00 до 23;
  • i -- минуты с нулем в начале;
  • s-- секунды с нулем в начале.

Существуют так же следующие символы формата даты/времени:

  • D и l -- текстовое представление дня месяца (От Mon до Sun либо от Sunday до Saturday);
  • z -- номер дня с начала года;
  • F и M -- текстовое представление месяца, например January или Sept;
  • y -- 2 цифровое представление года (например 03 -- это 2003 год);
  • a и A -- до полудня и После полудня (am или pm);
  • g и h -- 12-ти часовой формат времени с первым нулем или без него.

Для обратного преобразования объекта DateTime в строку существует метод format(string $format). В качестве параметра принимает строку с форматом даты/времени (таким же как в методе createFromFormat).

Для того чтобы вычесть или добавить в дате/времени какой-либо интервал времени (например 2 часа или 3 месяца), нужно воспользоваться методом add(DateInterval $interval) или sub(DateInterval $interval). ВАЖНО: Преобразование применяется к объекту для которого вызавается метод. В качестве параметров эти методы принимают объект класса DateInterval.

В качестве параметра конструктор этого класса принимает строку с интревалом времени в формате из спецификации ISO 8601. В соответсвии с ней: строка с интервалом времени начинается с латинсткой буквы P. Длина каждого периода описывается целым значением и следующим за ним указателем периода. Если длина периода содержит время, то его описанию должна предшествовать буква T. Например 2 дня записываются так -- P2D. Две секунды -- PT2S. Допустимы следующие обозначения интервалов:

  • Y -- года;
  • M -- месяцы;
  • D -- дни;
  • W -- недели;
  • H -- часы;
  • M -- минуты;
  • S -- секунды.

Помимо конструктора создать объект интервала времени можно с помощью статического метода DateInterval::createFromDateString(string $time). Он принимает в качестве параметра строку с интервалом времени в более читаемом виде. Например:
1 day
2 weeks
3 months
и даже
1 year + 1 day
1 day + 12 hours.


Таким образом благодаря классу DateTime работа с датами и временем в PHP не вызывает сложностей.

вторник, 4 июня 2013 г.

Встроенный web-сервер в PHP

В PHP начиная с версии 5.4 встроен Web сервер. Запустить его очень легко:
  1. Открываем терминал.
  2. Переходим в директорию в которой находятся скрипты, доступ к которым должен предоставить web сервер.
  3. Выполняем команду:
    php -S хост:порт
Если в качестве хоста прописать localhost, то доступ к серверу будут иметь только локальные клиенты.

суббота, 1 июня 2013 г.

Настрока прокси для Git

Чтобы Git начал работать через прокси, нужно:
Создать, если не существует, файл .gitconfig в корневой папке пользователя.
В файл добавить следующие строки:
[http]
proxy = http://логин:пароль@хост:порт
sslverify = false
где
   логин, пароль - параметры учетной записи на прокси сервере;
   хост, порт - адрес для подключения к прокси серверу.

Ошибка 0x80004005 при попытке получения Developer License в Visual Studio 2012 for Windows 8

На работе установил Visual Studio 2012 for Windows 8. А она при открытии требует получения Лицензии Разработчика (Developer License). Нажимаю "Получить"  и вместо лицензии получаю ошибку 0x80004005. Решения предлагаемые в инете не подошли, но зато я понял что ошибка из-за подключения к интернету. Интернет на работе задается через прокси сервер. Как оказалось, в этом и была проблема. Несмотря на то что в IE я настроил работу через прокси, VS небо все равно.

Решение проблемы

Решил проблему настройкой глобального прокси через утилиту netsh.
Под учетной записью администратора нужно выполнить следующую команду:
netsh winhttp set proxy прокси-хост:прокси-порт 

суббота, 25 мая 2013 г.

MonoDevelop 4 под Ubuntu 12.10

На официальном сайте MonoDevelop для Ubuntu доступны бинарники только версии 2.6. Для получения версии 4 нужно собрать её самому. Делается это следующим образом:
sudo apt-get install build-essential automake checkinstall intltool git
sudo apt-get install mono-complete mono-addins-utils gtk-sharp2 gnome-sharp2
git clone git://github.com/mono/monodevelop
cd monodevelop
git checkout monodevelop-4.0
git submodule update --init --recursive
./configure
make
sudo checkinstall
После сборки exe-шник доступен по пути: monodevelop/main/build/bin/MonoDevelop.exe. Запускается командой:
mono MonoDevelop.exe
Если вы используете оболочку Unity (по умолчанию в Ubuntu 12.10), то заметите что главное меню отсутствует. Эта проблема возникает только в Unity. Для того чтобы вернуть меню, перед запуском MonoDevelop нужно присвоить переменной окружения UBUNTU_MENUPROXY значение 0. Для того чтобы каждый раз не мучиться, можно создать скрипт, который всё это делает:
UBUNTU_MENUPROXY=0
mono ~/monodevelop/main/build/bin/MonoDevelop.exe
Спасибо за внимание.

среда, 3 апреля 2013 г.

Дамп базы PostgreSQL

Для создания дампа базы PostgreSQL существует утилита pg_dump.
Самый простой вызов этой утилиты выглядит так:
pg_dump база > файл_дампа

Если нужно задампить только одну таблицу:
pg_dump -t таблица база > файл_дампа

Если нужно указать имя пользователя, хост и порт, то нужно применить соответсвующие опции:

pg_dump -U пользователь -h хост -p порт базы > файл_дампа
или
pg_dump -U пользователь --host=хост --port=порт базы > файл_дампа

Во всех приведенных вариантах вызовов, pg_dump запросит пароль пользователя. Если вы пишите скрипт для автоматического бекапирования, то такое поведение не подходит -- пароль должен передаваться из скрипта. Для этого существует переменная окружения PGPASSWORD.  Следующий вызов не запросит пароль пользователя:
set PGPASSWORD = пароль_пользователя
pg_dump -U пользователь база > файл_дампа

Помимо переменной с паролем поддерживаются следующие переменные окружения:
  • PGDATABASE - база данных;
  • PGHOST - хост;
  • PGPORT - порт;
  • PGUSER - имя пользователя.


Очень полезно при бекапе ставить ключ --inserts, который для вставки данных в таблицы использует INSERT выражения (а не COPY как по умолчанию, которые понимает только pg_dump).

Ключ -c или --clean вставляет DROP выражения перед выражениями CREATE. Удобно если вы разворачиваете дамп в базу в которой уже есть таблицы и вам их нужно заменить.

четверг, 28 марта 2013 г.

Yahoo Web Mail Service

На работе интернет только через прокси + закрыты все порты, кроме 80 и 433. А нужно было протестировать механизм регистрации на разрабатываемом сайте (с отправкой сообщения пользователю на мыло). Единственное что пришло в голову, это найти сервис электронной почты с открытым API и использовать его для отправки сообщений. Погуглив, нашел только на yahoo.com такой API. Вот тут его описание.
Для работы с Yahoo Web Mail Service, нужно:
  • Завести аккаунт на Yahoo.com.
  • Зайти на страницу управления вашими проектами и создаем новый. Проект - это сущность, которая является "учетной записью" вашего проекта на сервере Yahoo. Каждый проект имеет Consumer Key и Consumer Secret, по которым и осуществляется доступ к API.
  • Скачать здесь PHP-библиотеку для работы с Yahoo Web Mail Service и поместить её в директорию сайта.
  • Ниже приведен исходный код скрипта для работы с API:
    require_once 'ymclient.php';
    
    define('OA_CONSUMER_KEY', '****************************************************************************************************');
    define('OA_CONSUMER_SECRET', '****************************************');
    define('OA_CALLBACK_URL', 'http://localhost/');
    define('REQUEST_TOKEN_COOKIE_NAME', 'rt');
    define('ACCESS_TOKEN_COOKIE_NAME', 'at');
    
    $ymc = new YMClientRequest(OA_CONSUMER_KEY, OA_CONSUMER_SECRET,
     OA_CALLBACK_URL, '192.168.60.3:3128');
    
    header("Content-type: text/plain\r\n\r\n");
    message = new stdclass();
    $msg->message->subject = 'Test from Yahoo!';
    $msg->message->from = new stdclass();
    $msg->message->from->email = '*******@yahoo.com';
    $msg->message->to = new stdclass();
    $msg->message->to->email = '******@gmail.com';
    $msg->message->simplebody = new stdclass();
    $msg->message->simplebody->text = 'Hello, World!';
    if ($ymc->SendMessage($msg)===false)
     echo 'error';
    else
     echo 'ok';
    
    class YMClientRequest {
        function __construct($oaConsumerKey, $oaConsumerSecret, $callbackURL,
          $proxy=null) {
            $this->oaConsumerKey = $oaConsumerKey;
            $this->oaConsumerSecret = $oaConsumerSecret;
            $this->callbackURL = $callbackURL;
            $this->ymc = new YMClient($oaConsumerKey, $oaConsumerSecret, $proxy);
        }
        function __call($method, $arguments) {
            $tok = $this->__get_access_token();            
            $result = $this->ymc->$method($arguments, $tok);
            $newtok = $this->ymc->oauth_get_refreshed_token();
            if($newtok) {
                setcookie(ACCESS_TOKEN_COOKIE_NAME, 
                    YMClient::oauth_token_to_query_string($newtok));
            }
            return $result;
        }
        private function __get_access_token() {
            // Access token exists in a cookie
            if(isset($_COOKIE[ACCESS_TOKEN_COOKIE_NAME])
                && $_COOKIE[ACCESS_TOKEN_COOKIE_NAME]) {
                parse_str($_COOKIE[ACCESS_TOKEN_COOKIE_NAME], $tok);                
                return $tok;
            }
            // Handling a redirect back from login
            else if(isset($_COOKIE[REQUEST_TOKEN_COOKIE_NAME])
                && $_COOKIE[REQUEST_TOKEN_COOKIE_NAME]
                && isset($_REQUEST['oauth_verifier'])
                && $_REQUEST['oauth_verifier'] 
                && isset($_REQUEST['oauth_token'])
                && $_REQUEST['oauth_token']) {
    
                $tok = YMClient::oauth_token_from_query_string(
                    $_COOKIE[REQUEST_TOKEN_COOKIE_NAME]);
    
                if($tok['oauth_token'] != $_REQUEST['oauth_token'])
                    throw new Exception("Cookie and URL disagree "
                        ."about request token value");
    
                $tok['oauth_verifier'] = $_REQUEST['oauth_verifier'];                            
                $newtok = $this->ymc->oauth_get_access_token($tok);
    
                setcookie(REQUEST_TOKEN_COOKIE_NAME, "", time()-3600);
                setcookie(ACCESS_TOKEN_COOKIE_NAME,
                    YMClient::oauth_token_to_query_string($newtok));
                return $newtok;
            }
            else {
                list ($tok, $url) = $this->ymc->oauth_get_request_token(
                    $this->callbackURL);
                setcookie(REQUEST_TOKEN_COOKIE_NAME,
                    YMClient::oauth_token_to_query_string($tok));
                header("Location: $url");
            }
        }
    }
    
    В приведенном выше фрагменте используется прокси для подключению с API. Изначально библиотека этого не предусматривала, поэтому её пришлось несколько модифицировать. Исходный код модифицированной версии можно скачать здесь. Этот фрагмент отправляет электронное сообщение, что и требовалось.
Интересные факты(:
  • Аутентификация осуществляется через OAuth.

среда, 27 марта 2013 г.

Настройка NTP-сервера на Windows

Для того чтобы настроить NTP-сервер, необходимо в редакторе реестра зайти в каталог:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time.

В нем:
  • В подкаталоге Config, установить:
    • AnnounceFlags = 0x05
    • MaxNegPhaseCorrection = 0x2a300
    • MaxPosPhaseCorrection = 0x2a300
  • В подкаталоге Parameters, установить:
    • NtpServer = <адрес_сервера_для_синхронизации>,0x1
    • Type = NTP
  • В подкаталоге TimeProviders/NtpClient, установить:
    • Enabled = 1
  • В подкаталоге TimeProviders/NtpServer, установить:
    • Enabled = 1
    • AllowNonstandardModeCombinations = 1
    • InputProvider = 0
  • Перезапустить службу времени Windows или вызвать команду
    w32tm /update /config.
  • Всё.

суббота, 16 марта 2013 г.

Yii + PHPUnit + PhpStorm

В иерархии папок web-приложения Yii есть папка webroot/protected/tests/unit для создания unit-тестов.
Для того чтобы тесты работали по мимо PHPUnit должен быть установлен PHPUnit_Selenium и быть запущен Selenium Server.
Как установить PHPUnit и PHPUnit_Selenium написано в предыдущем посте.
Для настройки проекта для тестирования в PhpStorm, нужно создать PHPUnit конфигурацию, в которой:
  • DirectoryC:\www\casade\casade2\protected\tests\unit.
  • Поставить галочку Use alternative configuration file и выбрать в качестве конфигурационного файла  webroot/protected/tests/phpunit.xml.

пятница, 15 марта 2013 г.

Установка и настройка PHPUnit. Настройка PhpStorm

Установка PHPUnit

Установить PHPUnit можно через PEAR командой:
pear channel-discover pear.phpunit.de
pear install --alldeps phpunit/PHPUnit
Так же может потребоваться установка PHPUnit_Selenium. Но перед этим нужно добавить канал pear.symfony.com, т. к. PHPUnit_Selenium использует Symfony2 Yaml Component. Добавляется канал командой:
pear channel-discover pear.symfony.com
После этого можно устанавливать PHPUnit_Selenium:
pear install --alldeps phpunit/PHPUnit_Selenium

Настройка PhpStorm

PHPUnit в PhpStorm не требует каких-либо дополнительных настроек, главное чтобы в настройках Settings->PHP->Include path был путь к директории PEAR.

Установка и настройка PEAR

  1. Скачать PEAR http://pear.php.net/go-pear.phar.
  2. Скопировать его в отдельную папку, например c:\utils\pear.
  3. Выполнить команду php go-pear.phar.
  4. Во время установки PEAR спросит где Вы хотите сохранить конфигурационные файлы: system - в C:\Windows, local - в папке PEAR'а.
  5. Так же он спросит место расположения PHP, т. к. дописывает свой путь в include_path. Пусть к PEAR можно дописать в php.ini и после установки:
    ;***** Added by go-pear
    include_path=".;C:\utils\pear\pear"
    ;*****
  6. Послу установки можно добавить нужные каналы:
    pear channel-discover pear.phpunit.de
    pear channel-discover pear.symfony.com
    
  7. После этого можно устанавливать пакеты командой:
    pear install --alldeps phpunit/PHPUnit
    

О том как настраивать PEAR с помощью переменных окружения написано тут.

четверг, 14 марта 2013 г.

Настройка PEAR

Возникли сложности с настройкой параметров PEAR, посмотреть их можно вызвав команду:

pear config-show

Настройки можно задать через переменные окружения:

PHP_PEAR_MASTER_SERVER - master_server
PHP_PEAR_HTTP_PROXY    - http_proxy
PHP_PEAR_INSTALL_DIR   - php_dir
PHP_PEAR_EXTENSION_DIR - ext_dir
PHP_PEAR_DOC_DIR       - doc_dir
PHP_PEAR_BIN_DIR       - bin_dir
PHP_PEAR_DATA_DIR      - data_dir
PHP_PEAR_CFG_DIR       - cfg_dir
PHP_PEAR_WWW_DIR       - www_dir
PHP_PEAR_TEST_DIR      - test_dir
PHP_PEAR_TEMP_DIR      - temp_dir
PHP_PEAR_CACHE_DIR     - cache_dir
PHP_PEAR_DOWNLOAD_DIR  - download_dir
PHP_PEAR_PHP_BIN       - php_bin
PHP_PEAR_SYSCONF_DIR   - папка где находятся pear.ini и pearsys.ini.

Задавая эти параметры можно вообще не пользоваться командой pear config-set.

среда, 13 марта 2013 г.

Настройка PhpStorm для работы с XDebug

Вот фрагмент конфигурации XDebug из php.ini:
zend_extension = "C:/utils/wamp/bin/php/php5.4.7/ext/php_xdebug-2.2.1-5.4-vc9.dll"

[xdebug]
xdebug.remote_enable = on
xdebug.profiler_enable = on
xdebug.profiler_enable_trigger = off
xdebug.profiler_output_name = cachegrind.out.%t.%p
xdebug.profiler_output_dir = "c:/utils/wamp/tmp"

Для того чтобы XDebug заработал с PhpStorm нужно:
  • создать Run/Debug конфигурацию PHP Remote Debug;
  • в разделе Configuration для свойства Servers выбрать нужный сервер или создать новый;
  • для свойства Ide key ввести PHPSTORM;
  • нажать OK.
Далее выбрать созданную конфигурацию в кобмобоксе Select Run/Debug Configuration и нажать на кнопку Start Listen PHP Debug Connections и на Debug.

В браузере  (Google Chrome) установить расширение XDebug helper, после чего в углу адресной строки появится значок расширения, если он зеленый, нажав на него, можно включить отладку.

Если Вам необходимо установить XDebug, то для начала нужно скачать его для нужной версии PHP отсюда. После этого скопировать бинарник в папку с другими модулями. В php.ini прописать настройки в точности как написано в начале статьи. ВАЖНО: путь к бинарнику указать ПОЛНОСТЬЮ.

вторник, 12 марта 2013 г.

Yii: Использование CClientScript

Класс-компонент CClientScript предназначен для подключения js-скриптов и css-стилей.
По умолчанию доступ к нему осуществляется через Yii::app()->clientScript.
Компонент содержит свойство packages, с помощью которого можно формировать пакеты скриптов, через конфигурационный файл делается это так:
'components' => array( 
    'clientScript' => array(
        'packages' => array(
            'item' => array(
                'basePath'=>'application.assets'
                'js' => array('js/item.js'),
                'depends' => array('jquery'),
            ),
            'filter' => array(
                'basePath'=>'application.assets'
                'js' => array('js/filter.js'),
                'depends' => array('jquery'),
            ),
        ),
    ),
),
Тут создается 2 пакета - item и filter. В приведенном примере используется свойство 'basePath' равное 'application.assets'. Это значит что скрипт item.js хранится в папке protected/assets/js/. При обращении происходит публикация этих ресурсов и на странице мы увидим обращение к опубликованному скрипту /assets/d03789dg/js/item.js.
Вместо свойства 'basePath' можно использовать 'baseUrl', при этом конечный URL скрипта будет <baseUrl>/js/item.js.

Подключаются они во вьюшке так:
Yii::app()->clientScript->registerPackage('item');

Статья по теме, из нее и взяты фрагменты кода.

Yii: как работать с AssetManager

AssetManager предназначен для публикации файлов js, css, png и др. ресурсы в папке webroot/asserts/.

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

Публикация выполняется методом AssetManager::publish($path), где $path - путь к папке с ресурсами которые нужно опубликовать.

Часто для публикации ресурсов и последующего доступа к ним, в базовый класс контроллера добавляют свойство getAssetsUrl():

class Controller extends CController
{
   private $_assetsUrl;
   public function getAssetsUrl() {
       if ($this->_assetsUrl === null) {
           $this->_assetsUrl = Yii::app()->assetManager->
               publish(Yii::getPathOfAlias('application.assets'));
       }
       return $this->_assetsUrl;
   }
}
UPDATE Не знаю для чего создавать временную переменную, т.к. внутри метода publish тоже есть проверка о публикации.

И во вьющке используют это свойство так:
<link rel="stylesheet" type="text/css" href="<?=$this->assetsUrl?>/css/main.css" />

Вот статья по теме на хабре.

четверг, 14 февраля 2013 г.

Mono в Visual Studio 2010

Оказывается, в Visual Studio 2010 при написании программ можно использовать Mono, вместо Framework .NET. Как это сделать написано тут.

Отмена запроса PostgreSQL

Если программа вызовит долговыполняющийся запрос к PostgreSQL, то даже её закрытие не прекратит выполнение этого запроса. Особенно это актуально для REINDEX или FULL VACUUM, которые кроме того что долго выполняются, еще и блокируют таблицу.
Для отметы такого запроса, нужно вызвать другой запрос:
SELECT pg_cancel_backend(procpid) as x 
FROM pg_stat_activity 
WHERE current_query like 'REINDEX%';

среда, 13 февраля 2013 г.

WMI на C#

WMI (Windows Management Instrumentation) - это одна из базовых технологий для централизованного управления и слежения за работой различных частей компьютерной инфраструктуры под управлением платформы Windows. (Википедия)

Для работы с WMI Framework .NET предоставляет сборку System.Management.dll и одноименным неймспейсом.

Работа с WMI начинается с класса ManagementScope, который предназначен для подключению к серверу WMI, как локального компьютера, так и удаленного. Основной конструктор этого класса принимает 2 параметра:
  1. path - путь для подключения;
  2. options - параметры подключения.
Параметр path обычно: string.Format(@"\\{0}\root\cimv2", host). Пусть содержит хост компьютера к которому нужно подключиться, и путь неймспейса WMI (имеет иерархическую структуру). Имеется много нейсмпейсов, но наиболее используемый cimv2.
Параметр options содержит следующие поля:
  • Username - имя пользователя Windows.
  • Password/SecurePassword - пароль пользователя Windows.
  • Другия параметы - не использовал.
После создания объекта, для того чтобы подключения к WMI нужно вызвать метод Connect.
Исходный код подключения к WMI:
ConnectionOptions options = new ConnectionOptions();
options.Username = username;
options.Password = password;
scope = new ManagementScope(string.Format("\\\\{0}\\root\\cimv2", host),
    options);
scope.Connect();
Свойство IsConnected возвращает состояние подключения.
Важно: класс ManagementScope не имеет метода для разрыва связи, для того чтобы переподключиться, ножно повторно вызвать метод Connect.

После создания подключения, мы можем начать запрашивать различную информацию от WMI.
Для этого существует класс SelectQuery. В конструкторе ему передается строка с SQL-подобным запросом. После этого мы можем использовать объект класса SelectQuery для передачи его в конструктор класса ManagementObjectSearcher.

SelectQuery query = new SelectQuery(@"Select
    DeviceID, FreeSpace, Size, DriveType from Win32_LogicalDisk");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope,
    query);
ManagementObjectCollection queryCollection = searcher.Get();
foreach (ManagementObject mo in queryCollection) {
    Console.WriteLine("DeviceID: {0}", mo["DeviceID"]);
    Console.WriteLine("FreeSpace: {0}", mo["FreeSpace"]);
    Console.WriteLine("Size: {0}", mo["Size"]);
    Console.WriteLine("DriveType : {0}", mo["DriveType "]);
}

Таким вот нехитрым способом можно получить с компа очень много системной информации.

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

JavaScript: объект select

Как известно объект select представляет собой выпадающий список. Он содержит список параметров (который и выпадает при нажании на него), доступ к которому можно получить через свойство options. Количество элеменов можно получить из свойства length самого объекта select. Свойство же size возыращает и задает количество отображаемых на странице элементов (не в выпадающем списке, а именно на странице). Я тестил это свойство в Chrome и при заничении size > 1 отображались все элементы списка.

Если необходимо чтобы список поддерживал множествнное выделение нужно присвоить свойсту multiple значение true.

Индекс текущего выбранного элемента содержится в свойстве selectedIndex. Если выбран режим со множественным выдылением, то это свойство содержит индекс первого выделенного элемента.

Так же имеется свойство form, которое ссылается на форму, в которой находится объект select.

Вставить новый элемент в список можно как с помощъю метода add самого select'a, так и с помощью метода add свойсва options.
selectObject.add(option,before)

Удаляются элементы списка методом remove:
selectObject.remove(index)

Также стоит напомнить как оформляеся select в HTML:


PS: подробная информация с примерами об объекте select находится сдесь.

пятница, 8 февраля 2013 г.

OpenSource: JSIL - компилятор C# в JS

Нашел в инете 3 основный проека по компилированию C# в JS:
Script# я тестил давно, мне не понравился :-) Не доделанный какой-то.
Про SharpKit пишут хорошие отзывы, но он платный.
А вот с JSIL можно поэксперементоровать. Он OpenSource и генерит вполне читаемый и логичный JS. На сайте есть возможность в онлайне скомпилировать любой код и увадеть что получится.
Написано что JSIL позволяет компилировать XNA игры и приведено нескольно демок. Но это надо еще проверить... У меня есть одна простая игра на XNA, будет время попробую скомпилировать.

Доступ к PostgreSQL через сеть

По умолчанию БД PostgreSQL настроина на доступ к ней только локально. Для того чтобы сделать доступной БД по сети нужно изменить настройку host в файле pg_hba.conf в каталоге БД. По умолчанию там стоит:
host    all             all             127.0.0.1/32            md5
Для того чтобы к БД можно подключиться в любого IP, намените эту настройку на следующую:
host    all             all             0.0.0.0/0            md5
или укажите нужную вам масту подсети.