I was recently working on some MySQL 5.5 performance testing. I had to generate a lot of SQL queries I would then use for my testing. To make my tests repeatable I needed to hardcode the values for IDs. That is, I couldn’t simply use:

INSERT INTO TABLE_NAME SET column1 = 'value1';

because this query may generate a row with a different ID each time (depending on the value of auto_increment for the table_name). What I really needed is:

INSERT INTO TABLE_NAME SET column1 = 'value1', id=17;

To accomplish that I needed to know a value of the next auto increment ID for my table. Here is how can you retrieve that value in MySQL:

SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='table_name';

This kind of “predicting” next ID will not work reliably and you should never use it in real application. It is safe in my case, as I’m only using it for generating data (queries) and I’m 100% that there are no concurrent connections to my database.


Setup

Below I will demonstrate how to use an excellent Dependency Injection component from Symfony 2, without using the whole Symfony framework. I will also use ClassLoader from Symfony and just for the sake of the demo I will integrate it with Zend Framework. The code requires PHP 5.3 (mostly for namespaces support).
Create a directory for your project. Inside create “lib” directory. Inside lib, create directory structure: Symfony/Component. Put ClassLoader code inside Component – the easiest thing to do is to clone if from Symfony github:

cd lib/Symfony/Component
git clone https://github.com/symfony/ClassLoader.git

The same goes for DependencyInjection component:

cd lib/Symfony/Component
git clone https://github.com/symfony/DependencyInjection.git

Finally download Zend Framework and put the contents of Zend directory into lib/Zend (so for instance Log.php file will be available in lib/Zend/Log.php).
The actual source code will go into “src” directory, which is a sibling directory of “lib”.

Configuring the ClassLoader

DependencyInjection uses namespaces for managing classes, so it needs to be registered with registerNamespace method. Zend Framework follows PEAR naming convention for classes – registerPrefix will do the work for us. Finally, I will register our own code that will be stored in src directory. I will use namespaces as well. Create a new file (let’s call it main.php) in the top-level directory:

require_once('lib/Symfony/Component/ClassLoader/UniversalClassLoader.php');
 
$loader = new Symfony\Component\ClassLoader\UniversalClassLoader();
$loader->registerNamespace('Zabuchy',__DIR__.'/src');
$loader->registerNamespace('Symfony',__DIR__.'/lib');
$loader->registerPrefix('Zend',__DIR__.'/lib');
$loader->register();
 
set_include_path(get_include_path().PATH_SEPARATOR.__DIR__.'/lib');

ClassLoader should now work just fine but we still need set_include_path so require functions inside Zend code will work correctly.

Dependency Injection container

Create a sample class that we’ll use for testing. I will call it Test and put it into Zabuchy\Techblog, which means it should be located at src/Zabuchy/Techblog/Test.php:

namespace Zabuchy\Techblog;
 
class Test
{
    private $logger;
 
    public function __construct($logger) {
      $this->logger = $logger;
    }
 
    public function run() {
     $this->logger->info("Running...");
    }
}

$logger should be injected using container – here is where we will use Zend_Log class. This one in turn requires a Writer, so we will create it as well. The rest of main.php will look like this:

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
 
$sc = new ContainerBuilder();
 
$sc->register('log.writer','Zend_Log_Writer_Stream')
    ->addArgument('php://output');
$sc->register('logger', 'Zend_Log')
    ->addArgument(new Reference('log.writer'));
$sc->register('test','Zabuchy\Techblog\Test')
    ->addArgument(new Reference('logger'));
 
$sc->get('test')->run();

Running the code should give an output like below:

% php main.php 
2011-06-09T15:17:22+01:00 INFO (6): Running...

Complete code

For reader’s convenience I’m attaching a full source code – including a copy of Zend library and Symfony 2 components.


This is part 5 of the Java Technologies Integration tutorial. The purpose of this part is to provide updates to Hibernate configuration in existing project to make the maintenance of the project more straight forward.

Hibernate configuration files

The description of Hibernate configuration was described here: Java Technologies Integration tutorial – part 2 – Hibernate configuration. It is possible to remove hibernate mapping files and use automatic hibernate mapping.

In order to do so the following files should be changed as follows:

Hibernate.xml

sessionFactory bean

Change sessionFactory bean from org.springframework.orm.hibernate3.LocalSessionFactoryBean to org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean. Such change allows using Hibernate annotations automatically.

packagesToScan property

Remove mappingResources property including all the mapping files reference. Instead add packagesToScan property. As the value enter package name, where your classes with hibernate annotations are located, e.g, net.opensesam or to be more specific net.opensesam.entity. Hibernate will scan your package and find all the entities (classes annotated with @Entity) automatically, so you do not have to waste your time on configuration of entity classes.

It is possible to define one package to be scanned:

<property name="packagesToScan" value="net.opensesam" />

as well as multiple locations of Hibernate annotated files:

<property name="packagesToScan">
	<list>
		<value>net.opensesam.entity1</value>
		<value>net.opensesam.entity2</value>
	</list>
</property>

annotatedClasses property

Instead of scanning you can also use annotatedClasses property, but then you have to list all the classes annotated as @Entity explicitly. For example:

<property name="annotatedClasses">
	<list>
		<value>net.opensesam.entity.User</value>
		<value>net.opensesam.entity.Resource</value>
	</list>
</property>

Hibernate.xml file

Modified Hibernate.xml file of the project is presented below.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
	<!-- Hibernate session factory -->
	<bean
		class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
		id="sessionFactory">
		<property name="dataSource">
			<ref bean="dataSource" />
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">${hibernate.dialect}</prop>
				<!-- In prod set to "validate", in test set to "create-drop" -->
				<prop key="hibernate.hbm2ddl.auto">update</prop>
				<!-- In prod set to "false" -->
				<prop key="hibernate.show_sql">false</prop>
				<!-- In prod set to "false" -->
				<prop key="hibernate.format_sql">true</prop>
				<!-- In prod set to "false" -->
				<prop key="hibernate.use_sql_comments">true</prop>
				<!-- In prod set to "false", in test set to "true" -->
				<prop key="hibernate.cache.use_second_level_cache">false</prop>
			</props>
		</property>
		<property name="packagesToScan" value="net.opensesam" />
	</bean>
</beans>

Mapping files

Having the changes introduced you no longer need Hibernate mapping files (*.hbm.xml). Remove them from src/main/resources/resources/hibernate/ directory.


Below is the fastest way to install the latest trunk version (currently 1.9.6) of Battle of Wesnoth on your Ubuntu Natty Narwhal. Note: it will probably install a bit too many packages than you really need.

sudo apt-get install automake debhelper libboost1.42-all-dev libboost1.42-dev libboost-dev libboost-iostreams-dev libboost-regex-dev libboost-serialization-dev libboost-test-dev libdbus-1-dev libfreetype6-dev libfribidi-dev libghc6-pango-dev liblua5.1-0-dev libpango1.0-dev libsdl1.2-dev libsdl-dev libsdl-image1.2-dev libsdl-mixer1.2-dev libsdl-net1.2-dev libsdl-ttf2.0-dev python-support quilt scons subversion && svn co http://svn.gna.org/svn/wesnoth/trunk wesnoth && cd wesnoth && scons

That’s all – keep in mind that this may take a long time to execute… To play the game, you don’t need to install it, simply type:

./wesnoth

I’d like to share a quick guide on how to set up master/slave replication for the MySQL 5.5 server. The procedure below should be used for development/testing only. If you want to create a production-ready setup, you should follow instructions from MySQL official documentation or use MySQL server packaged by your favorite Linux distribution.

1. Download latest MySQL 5.5 from http://dev.mysql.com/downloads/mysql.

2. Follow the installation instructions on http://dev.mysql.com/doc/refman/5.5/en/binary-installation.html or instructions below if you don’t care about the secure setup (e.g. you are only using this MySQL installation for testing). You should also follow my instructions if you want to avoid conflicts with the MySQL you may have installed from your Linux distribution package. Do not follow them for the production setup.

  • switch to root
  • on ubuntu/debian run sudo apt-get install libaio1
  • cd /opt
  • download mysql tarball
  • unpack it tar -zxf mysql-5.5.3-m3-linux2.6-x86_64-icc.tar.gz
  • ln -s mysql-5.5.3-m3-linux2.6-x86_64-icc mysql
  • cd mysql
  • scripts/mysql_install_db --basedir=/opt/mysql --datadir=/opt/mysql/data
  • bin/mysqld_safe --defaults-file=support-files/my-medium.cnf --user=root --basedir=/opt/mysql --datadir=/opt/mysql/data

You should be able to connect as a root without the password

% mysql -u root -h 127.0.0.1
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.5.3-m3 MySQL Community Server (GPL)

To shut down your MySQL use

mysqladmin -h 127.0.0.1 -u root shutdown

Now, repeat the procedure on the second machine and we can move on.

3. Set up the replication.
Master will already be configured for the replication, as the whole necessary setup (log-bin,server-id) is already included in support-files/my-medium.cnf. You will still need to create a replication user on the slave:

CREATE USER 'repl'@'%' IDENTIFIED BY 'slavepass';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';

Go to your slave and set in the /opt/mysql/support-files/my-medium.cnf:
server-id=2 (replace the default id 1 with 2)

Make sure you can connect from the machine where slave is installed to the master MySQL server, using ‘repl’ user.

CHANGE MASTER TO MASTER_HOST='192.168.1.10', MASTER_USER='repl', MASTER_PASSWORD='slavepass';
START SLAVE;

That’s it! Let’s test it, on your master issue:

CREATE DATABASE symfony2;
USE symfony2;
CREATE TABLE test_table (a INT);
INSERT INTO test_table VALUES (1);

Corresponding table should be created on slave and should contain one record. Now, let’s test temporary disabling replication log on master:

SET sql_log_bin=0;
INSERT INTO test_table VALUES (2),(3);
SET sql_log_bin=1;
INSERT INTO test_table VALUES (4),(5);

You table on master should contain 5 rows but the one on the slave only 3 – the values 2 and 3 should be missing.


I wanted to change the way teasers are displayed – disable this information about the node submission: published by admin on Fri, 04/22/2011 – 17:25.

As it turns out, there is a variable that Drupal checks when generating submission information. The variable is set per each content type in a format node_submitted_<NODE TYPE>, e.g., node_submitted_page and should be simply set to TRUE or FALSE. Here is the code I’ve added to my micropt module, to micropt.install

function micropt_install() {
  variable_set("node_submitted_micropt", FALSE);
}

You can change the value of the variable using drush or directly in the database:<p></p>

UPDATE `variable` SET `value` = 'b:1;' WHERE `name` LIKE 'node_submitted_micropt'

“b:1;” is a serialized value for TRUE, for FALSE use “b:0;”. If you do so, don’t forget to clear the cache!


Say you would like to transfer set of files from location A to B. The source directory is really big but you are only interested in transferring some files (say *.png only). rsync is a good tool for the job. There are two methods I know that can be utilized.

find + rsync

Use find to select the files and then send them over with rsync:

find source -name "*.png" -print0 | rsync -av --files-from=- --from0 ./ ./destination/

This will create the minimum directories (and sub-directories) required for your files.

rsync only

Use rsync command only with –include and –exclude options.

rsync -av --include='*/' --include='*.png' --exclude='*' source/ destination/

The difference from the previous command is that rsync will create all the directories from source in destination, and then copy *.png files. It will potentially leave your destination filled with empty directories – which may or may not be what you want.


to make perl properly handle utf-8 strings inserted and retrieved from ms sql database, freetds config must be used (the configuration with only odbc.ini is possible to make perl connect to a database, but i could not find any way to make it work with utf)

for this purpose, the entry in odbc.ini should contain “Servername”, which points to an entry in the freetds.conf. the sample configuration may look as following:

#/etc/odbc.ini

[JA223ODBC]
Description = Just Another 223 ODBC entry
Driver = FreeTDS
Servername = MYSERV
Database&nbsp; = mydatabase

#/usr/local/etc/freetds.conf

[MYSERV]
host = 192.168.1.223
port = 1433
tds version = 8.0
client charset = UTF-8

#perl script connection string:

my $data_source = q/dbi:ODBC:JA223ODBC/; # DSN string from /etc/odbc.ini
my $user = q/username/;
my $password = q/password/;
my $dbh = DBI-&gt;connect($data_source, $user, $password, {RaiseError =&gt; 0, PrintError =&gt; 1}) or die "Can't connect to $data_source: $DBI::errstr"

tips:

- use tds dump for debugging. for this, set the TDSDUMP env variable and try to connect; read debug info from the dump file:

export TDSDUMP=/path/to/tdsdump.txt

- use tsql to debug connection. in another terminal, set the TDSDUMP variable, run

tsql -S MYSERV -U username -P password

then exit, and compare information from the tsql’s dump with the script’s dump

- be careful with config files; freetds can read from /usr/local/etc/freetds or /etc/freetds.conf depending on it’s installation configuration, but will definitely use only $HOME/.freetds.conf if it exists

- and do not forget to enclose your utf-8 strings in N” in queries, otherwise ms sql server will not understand it’s utf:

select stringID from stringtable where string = N'utf-8 ąęćźś string';

 


Update 2013.06.17: use Multiple Checkbox Checker.

Update 2012.12.10: also try CheckFox extension.

Update on 2011.12.01: the script doesn’t work for my FF8 anymore, looks like checkboxmate-lefedor-edition is a way to go now.

Upon installing WYSIWYG module in Drupal 7, site builder is presented with rather annoying task of selecting all the buttons to be enabled. The corresponding section of the WYSIWYG form – “buttons and plugins” is rather intimidating:

Site builder is required to go through all the checkboxes and check them manually. There is some ongoing work to fix the problem on Drupal side but meanwhile there is a better way – Firefox plugin! Install greasemonkey, restart your browser and add this user script.

The usage is not very straightforward at the beginning but it’s very handy once you get used to it. Position your mouse cursor above the first checkbox, click and drag with the mouse. All the checkboxes inside the rectangle you’ll draw will flip their state.


Normally when you quit less, your screen will be redrawn and you will be back with the content you could see on your screen before using less. Sometimes though it’s very handy to see the file with less, scroll down to the fragment of your interest and have that fragment still visible on the screen after you quit less.
Although the results may vary depending on what kind of terminal you use, try -X option when invoking less:

less -X /path/to/file

This and more cool tricks with less can be found on the excellent less FAQ.